Skip to content

Accessing Files

It is often the case that a masking algorithm will require a large library of input values - for example, a set of replacement names or account numbers. In other cases, it may be desirable to store the configuration of a particularly complex algorithm in a format other than JSON, perhaps in order to leverage pre-existing code. To support these use cases, the extensible algorithm framework allows algorithms to access input files from a variety of sources.

Opening Input Files

Algorithms may access files in several locations, both on the engine and over the network. In all cases, access is achieved by invoking the openInputFile method of the ComponentService object passed to the algorithm's setup method to acquire an InputStream. The file's location must be specified by an FileReference object visible in the object's public fields. This object is passed to the openInputFile method. The value of the FileReference may be made configurable using the @JsonProperty annotation. The openInputFile method accepts a URI style syntax that combines standard URL notation for web resources with custom URI types for engine and JAR located files. The following formats are supported for FileReference values:

URI Format Description
http[s]://<host>[:<port>]/<path> To open files located on a remote web server
jar://file/<filepath> To open a file located in the algorithm plugin JAR
delphix-file://upload/<file reference details> To open a file uploaded using Delphix Masking Engine's fileUpload endpoint. The result of POST>ing to the fileUpload API endpoint is a URI in this format that should be used exactly as-is for the uri value of the FileReference.
delphix-file://mount/<mountType>/<mountId>/<file path> To open a file located on a NFS/CIFS mount server that has been mounted inside the Delphix Masking Engine using mountFilesystem endpoint

Example Algorithm

public class RedactionFile implements MaskingAlgorithm<String> {
   private String redactionCharacter = null;

   @JsonProperty(value = "file", required = true)
   public FileReference file;
   @Override
   public String getName() {
       return "RedactionFile";
   }

   @Override
   public String mask(@Nullable String input) throws MaskingException {
       if (input == null) {
           return null;
       }
       StringBuilder returnVal = new StringBuilder();
       for (int i = 0; i < input.length(); i++) {
           returnVal.append(redactionCharacter);
       }
       return returnVal.toString();
   }

   @Override
   public void setup(@Nonnull ComponentService serviceProvider) {
       InputStream inputStream = serviceProvider.openInputFile(file);
       try (Scanner scanner = new Scanner(inputStream, Charset.defaultCharset().name())) {
           redactionCharacter = scanner.nextLine().trim();
       } catch (Exception e) {
           e.printStackTrace();
           throw new RuntimeException("Unable to parse input file", e);
       }
   }

   @Override
   public void validate() throws ComponentConfigurationException {
       GenericReference.checkRequiredReference(file, "file");
   }
}

Some methods have been omitted for brevity.

This example algorithm is very similar to the StringRedaction class discussed earlier, in that it redacts strings by replacing with a same-length string of the redaction character. This variant reads the character to use for redaction from an input file, the location of which is specified in the algorithm's configuration. This is all done in the initialize method:

  • The value of the variable file is public and marked configurable with @JsonProperty.
  • The file reference is passed to serviceProvider.openInputFile during setup - this allows the algorithm to ingest input files in any supported location.
  • The redaction character is read from the input stream and stored in instance variable redactionCharacter for use in the mask method.
  • This class's validate method uses the static method GenericReference.checkRequiredReference provided by the Masking Plugin API to check the file reference for validity.