Get started with the Processing API

The Processing API supports the automation of your processing workflows. You can programmatically use this API to create and update custodians, data sources, processing sets, and profiles required for processing. It provides an alternative to manually creating them through the Relativity UI. You also can use the Processing API to run inventory, discovery, and publishing jobs.

Use the information on this page to learn about Processing API fundamentals. It includes prerequisites for developing with this API, and code samples for common operations. Additional resources to help you get started with the Processing API include:

  • Field Mapping (.NET) and Field Mapping (REST) - provides information about the Field Mapping service available through the Relativity Services API and REST API respectively.
  • Processing on the RelativityOne Documentation site - provides general information about how Relativity supports processing.
  • Relativity SDK samples - provides information about how to run the code samples provided on this page against your local Relativity instance.

This page contains the following information:

See these related pages:

Processing API fundamentals

The Processing application provides system admins with the ability to ingest raw data directly into a workspace for review. When you set up a processing workflow, you create a processing profile. This profile specifies settings that control how the processing engine ingests the data. You create or reference the following items:

  • A custodian who is a user associated with the data included in a processing job.
  • A data source that contains the path used to specify the location of the files that you want to discover.

You also create a processing set that links a processing profile to one or more data sources. When you run a discovery job, the processing engine discovers files in the data source based on the values specified in the processing set. For more information, see Processing on the RelativityOne Documentation site

The Processing API provides interfaces and objects that you can use to automate many of the tasks in a processing workflow. It includes the following interfaces that you can use to access services, which interact with custodian, data source, and processing set objects:

  • IProcessingCustodianManager - used to access the Processing Custodian Manager service.
  • IProcessingDataSourceManager - used to access the Processing Data Source Manager service.
  • IProcessingProfileManager - used to access the Processing Profile Manager service.
  • IProcessingSetManager - used to access the Processing Set Manager service.

Each of these interfaces provide a ReadAsync() and SaveAsync() method, which you can use to create, update, or retrieve processing objects. The Processing API includes the ProcessingCustodian, ProcessingDatasource, ProcessingProfile, and ProcessingSet classes. You can set or retrieve properties on these classes by calling the ReadAsync() or SaveAsync() method on their respective interfaces. You must call the SaveAsync() method to add any new or modified objects to the database.

Common processing workflows

The Processing API also includes the IProcessingJobManager interface. You can use this interface to access the Processing Job Manager service for running inventory, discovery, and publishing jobs. It includes the following methods:

  • SubmitInventoryJobsAsync() method – used for excluding irrelevant files from a data set prior to running a discovery job, such as eliminating NIST file types. The InventoryJob class includes properties for the workspace artifact and processing set IDs required to submit a job.
  • SubmitDiscoveryJobsAsync() method – used for submitting data sources to the processing engine for discovery. The DiscoveryJob class includes properties for the workspace artifact and processing set IDs required to submit a job.
  • SubmitPublishJobsAsync() method – used to publish the processed data to a workspace after discovery, so that reviewers can access it. The PublishJob class includes properties for the workspace artifact and processing set IDs required to submit a job.

Common workflows for processing include inventorying, discovering, and then publishing data, or just discovering and then publishing data. You can only inventory files that haven’t been discovered. Additionally, you can only publish files after Relativity has completed discovery. For more information, see Processing Job Manager and Processing API services for REST.

In Relativity, you want to enable the auto-publish option on the processing profile, so that the discovered files are automatically added to the workspace. See Relativity environment setup.

Processing API prerequisites

Complete the following prerequisites to begin development with the Processing API:

Development guidelines for the Processing API

Use these guidelines when automating workflows with the Processing API:

  • Add the following DLL references to your Visual Studio project. For additional information, see Prerequisites for Processing API development.
    • Relativity.Processing.Services.Interfaces.dll (in the Processing API SDK)
    • kCura.Relativity.Client.dll (in the Relativity SDK)
    • Relativity.Kepler.dll (in the Relativity SDK)
  • Use the Relativity API helpers to establish a connection with the Processing API and set the context used for your code execution. All code samples on this page illustrate how to use the helper classes to connect with the Processing API. For more information, see Using Relativity API Helpers.
  • Call the SaveAsync() method on any processing object that you create or modify. Your changes won't be added to the database until you make this call.
  • Use a try-catch block around your code for creating, updating, and reading objects. Also, use it when submitting jobs. Catch any ServiceExceptions raised by your code as exemplified in the following code samples.
  • Use logging to help troubleshoot your code as exemplified in the following code samples.

Processing Custodian Manager

The Processing Custodian Manager service supports read and save operations on custodian objects. The ProcessingCustodian class represents a custodian associated with the files that you want to process. For more information, see Entity object on the RelativityOne Documentation site.

Create a ProcessingCustodian

To create a ProcessingCustodian instance, invoke the constructor and then initialize the following properties:

  • ArtifactID – set this property to 0, indicating that you are creating a new instance.
  • DocumentNumberingPrefix – set this property to a prefix that you want applied to files when the processing engine publishes them to a workspace. The default value is REL.
  • FirstName – set this property to the custodian's first name.
  • LastName – set this property to the custodian's last name.

Next, call the SaveAsync() method on the proxy created with the IProcessingCustodianManager interface to access the service. You must then pass this method the initialized ProcessingCustodian instance and the workspace Artifact ID.

public async Task<bool> ProcessingCustodianManager_Create_SaveAsync(IHelper helper)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingCustodianManager proxy = helper.GetServicesManager().CreateProxy<IProcessingCustodianManager>(ExecutionIdentity.User))
   {
      try
      {
         //Build the ProcessingCustodian object.
         ProcessingCustodian processingCustodian = new ProcessingCustodian
         {
            ArtifactID = 0, // Indicates a new ProcessingCustodian object.
            DocumentNumberingPrefix = "REL",
            FirstName = "John",
            LastName = "Smith"
         };

         //Create the ProcessingCustodian object. The service returns the Artifact ID of the object.
         int artifactId = await proxy.SaveAsync(processingCustodian, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingCustodianManager_Create_SaveAsync), "Create failed", this.GetType().Name);
         }
      }
      catch (Exception exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingCustodianManager_Create_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Read a ProcessingCustodian

Read the values for the properties on a ProcessingCustodian object by calling the ReadAsync() method on the proxy created with IProcessingCustodianManager interface. The ReadAsync() method requires that you pass the Artifact IDs of the ProcessingCustodian object and the workspace as arguments.

public async Task<bool> ProcessingCustodianManager_ReadAsync(IHelper helper, int processingCustodianArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingCustodianManager proxy = helper.GetServicesManager().CreateProxy<IProcessingCustodianManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingCustodian object.
         ProcessingCustodian processingCustodian = await proxy.ReadAsync(processingCustodianArtifactId, WorkspaceId);

         //Display the last and first name of the custodian.
         string fullName = $"{processingCustodian.LastName}, {processingCustodian.FirstName}";
         Logger.LogMessage(LogLevel.Debug, nameof(ProcessingCustodianManager_ReadAsync), fullName, this.GetType().Name);

         success = true;
      }
      catch (Exception exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingCustodianManager_ReadAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Update a ProcessingCustodian

When updating a ProcessingCustodian instance, you call the AsyncRead() method on the proxy created with the IProcessingCustodianManager interface. Next, set the properties on the instance to their new values, and then call the SaveAsync() method. You must call the SaveAsync() method in order for your changes to be added to the database.

public async Task<bool> ProcessingCustodianManager_Update_SaveAsync(IHelper helper, int processingCustodianArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user. 
   using (IProcessingCustodianManager proxy = helper.GetServicesManager().CreateProxy<IProcessingCustodianManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingCustodian object.
         ProcessingCustodian processingCustodian = await proxy.ReadAsync(processingCustodianArtifactId, WorkspaceId);

         //Modify the document numbering prefix and first name.
         processingCustodian.DocumentNumberingPrefix = "ECA";
         processingCustodian.FirstName = "Sam";
         processingCustodian.Name = $"{processingCustodian.LastName}, {processingCustodian.FirstName}";

         //Update the ProcessingCustodian object. The service returns the Artifact ID of the object.
         int artifactId = await proxy.SaveAsync(processingCustodian, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingCustodianManager_Update_SaveAsync), "Update failed", this.GetType().Name);
         }
      }
      catch (Exception exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingCustodianManager_Update_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Processing Profile Manager

The Processing Profile Manager service includes the SaveAsync() method for creating and updating a profile, the ReadAsync() method for retrieving a profile, and the DeleteAsync() method for removing a profile from Relativity. The ProcessingProfile class represents a collection of settings used to process documents. Processing profiles are associated with processing sets, so you must provide the Artifact ID of a processing profile when creating or updating a processing set. See Processing Set Manager.

Sample ProcessingProfile object

The ProcessingProfile class has multiple properties for specifying numbering, deNISTing, extraction, and deduplication settings. Many of these properties reference other classes and enumerations. For example, the ProcessingProfile class contains a property that references the DeduplicationSettings class, which has a property that is set with values from the DeduplicationMethod enumeration.

You can find more information about processing profile fields on the following pages:

The BuildBasicProfile class provides an example of how to set the properties on a ProcessingProfile object. It is referenced in the other code samples in this section.

private ProcessingProfile BuildBasicProfile(int timeZoneId)
{
    ProcessingProfile profile = new ProcessingProfile();
    profile.Name = "testProf";

    profile.NumberingSettings = new NumberingSettings();
    profile.NumberingSettings.DefaultDocumentNumberingPrefix = "abc";
    profile.NumberingSettings.NumberOfDigits = NumberOfDigits.NumberOfDigits4;
    profile.NumberingSettings.NumberingType = NumberingType.AutoNumber;
    profile.NumberingSettings.ParentChildNumbering = ParentChildNumbering.ContinuousAlways;

    profile.DeduplicationSettings = new DeduplicationSettings();
    profile.DeduplicationSettings.DeduplicationMethod = DeduplicationMethod.None;

    profile.ExtractionSettings = new ExtractionSettings();
    profile.ExtractionSettings.Extractchildren = false;
    profile.ExtractionSettings.EmailOutput = EmailOutput.MSG;
    profile.ExtractionSettings.ExcelTextExtractionMethod = ExcelTextExtractionMethod.Native;
    profile.ExtractionSettings.ExcelHeaderFooterExtraction = ExcelHeaderFooterExtraction.DoNotExtract;
    profile.ExtractionSettings.PowerPointTextExtractionMethod = PowerPointTextExtractionMethod.Native;
    profile.ExtractionSettings.WordTextExtractionMethod = WordTextExtractionMethod.Native;
    profile.ExtractionSettings.OCR = false;

    profile.InventoryDiscoverSettings = new InventoryDiscoverSettings();
    profile.InventoryDiscoverSettings.DeNIST = false;
    profile.InventoryDiscoverSettings.DefaultTimeZoneID = timeZoneId;
    profile.InventoryDiscoverSettings.DefaultOCRlanguages = new HashSet<OcrLanguage>
    {
        OcrLanguage.English
    };

    profile.PublishSettings = new PublishSettings();
    profile.PublishSettings.AutopublishSet = false;
    profile.PublishSettings.DefaultDestinationFolder = new Services.Folder.FolderRef { ArtifactID = NewFolderId };
    profile.PublishSettings.UseSourceFolderStructure = true;

    return profile;
}

Create a ProcessingProfile

To create a processing profile in a workspace, instantiate a ProcessingProfile object, and set the required fields as illustrated in Sample ProcessingProfile object. Call the SaveAsync() method by passing it the new ProcessingProfile instance and the Artificat ID of a Workspace object. See the following code:

public async Task<int> ProcessingProfileManager_Create_SaveAsync(IHelper helper, int timeZoneId)
{
    int profileId = 0;

    //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
    //agents, and custom Pages. They are mocked in these samples.
    //This sample code executes under the context of the current user.
    using (IProcessingProfileManager proxy = helper.GetServicesManager().CreateProxy<IProcessingProfileManager>(ExecutionIdentity.User))
    {
        try
        {
            //Build the ProcessingProfile object.
            ProcessingProfile profile = BuildBasicProfile(timeZoneId);
            //Build the ProcessingProfileSaveRequest.
            ProcessingProfileSaveRequest saveRequest = new ProcessingProfileSaveRequest
            {
                ProcessingProfile = profile,
                WorkspaceId = WorkspaceId
            };

            //Create the ProcessingProfile object. The service returns a ProcessingProfileSaveResponse object.
            ProcessingProfileSaveResponse saveResponse = await proxy.SaveAsync(saveRequest);
            profileId = saveResponse.ProcessingProfileId;
            if (profileId == 0)
            {
                Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_Create_SaveAsync), "Create failed", this.GetType().Name);
            }
        }
        catch (ServiceException exception)
        {
            //The service returns exceptions of type ServiceException.
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_Create_SaveAsync), exception.Message, this.GetType().Name);
        }
    }
    return profileId;
}

Read a ProcessingProfile

Use the ReadAsync() method to retrieve a processing profile from Relativity. Pass this method a ProcessingProfileReadRequest object, which contains the Artifact ID of the ProcessingProfile object, and Artifact ID of an associated Workspace object. See the following sample code:

public async Task<ProcessingProfile> ProcessingProfileManager_ReadAsync(IHelper helper, int processingProfileArtifactId)
{
    ProcessingProfile readProfile = new ProcessingProfile();
    readProfile.ArtifactID = 0;

    //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
    //agents, and custom Pages. They are mocked in these samples.
    //This sample code executes under the context of the current user.
    using (IProcessingProfileManager proxy = helper.GetServicesManager().CreateProxy<IProcessingProfileManager>(ExecutionIdentity.User))
    {
        try
        {
            // Build the ProcessingProfileReadRequest object.
            ProcessingProfileReadRequest readRequest = new ProcessingProfileReadRequest
            {
                ProcessingProfileId = processingProfileArtifactId,
                WorkspaceId = WorkspaceId
            };

            //Read the ProcessingProfile object.
            ProcessingProfileReadResponse readResponse = await proxy.ReadAsync(readRequest).ConfigureAwait(false);

            //Display the Artifact ID of the processing profile.
            string profileId = $"{readResponse.ProcessingProfile.ArtifactID}";
            Logger.LogMessage(LogLevel.Debug, nameof(ProcessingProfileManager_ReadAsync), profileId, this.GetType().Name);

            readProfile = readResponse.ProcessingProfile;
        }
        catch (ServiceException exception)
        {
            //The service returns exceptions of type ServiceException.
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_ReadAsync), exception.Message, this.GetType().Name);
        }
    }
    return readProfile;
}

Update a ProcessingProfile

To update a processing profile, modify the profile fields as necessary, instantiate a ProcessingProfileSaveRequest object, and then pass this object to the SaveAsync() method. The ProcessingProfileSaveRequest object contains the Artifact ID of the ProcessingProfile object, and Artifact ID of an associated Workspace object. See the following sample code:

public async Task<int> ProcessingProfileManager_Update_SaveAsync(IHelper helper, int processingProfileId)
{
    int profileId = 0;
    //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
    //agents, and custom Pages. They are mocked in these samples.
    //This sample code executes under the context of the current user.
    using (IProcessingProfileManager proxy = helper.GetServicesManager().CreateProxy<IProcessingProfileManager>(ExecutionIdentity.User))
    {
        try
        {
            // Build the ProcessingProfileReadRequest object.
            ProcessingProfileReadRequest readRequest = new ProcessingProfileReadRequest
            {
                ProcessingProfileId = processingProfileId,
                WorkspaceId = WorkspaceId
            };

            //Read the ProcessingProfileReadResponse object and grab the profile.
            ProcessingProfileReadResponse readResponse = await proxy.ReadAsync(readRequest).ConfigureAwait(false);

            ProcessingProfile profile = readResponse.ProcessingProfile;
            
            //Modify the list of OCR languages and the name of the processing profile.
            profile.Name = "The profile has been updated";
            profile.InventoryDiscoverSettings.DefaultOCRlanguages = new HashSet<OcrLanguage>
            {
                OcrLanguage.English,
                OcrLanguage.Spanish
            };

            //Build the ProcessingProfileSaveRequest.
            ProcessingProfileSaveRequest saveRequest = new ProcessingProfileSaveRequest
            {
                ProcessingProfile = profile,
                WorkspaceId = WorkspaceId
            };

            //Update the ProcessingProfile object.The service returns a ProcessingProfileSaveResponse.
            ProcessingProfileSaveResponse saveResponse = await proxy.SaveAsync(saveRequest).ConfigureAwait(false);
            profileId = saveResponse.ProcessingProfileId;
            if (profileId == 0)
            {
                Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_Update_SaveAsync), "Update failed", this.GetType().Name);
            }

        }
        catch (ServiceException exception)
        {
            //The service returns exceptions of type ServiceException.
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_Update_SaveAsync), exception.Message, this.GetType().Name);
        }
    }
    return profileId;
}

Delete a ProcessingProfile

Use the DeleteAsync() method to remove a processing profile from Relativity. Pass this method a ProcessingProfileDeleteRequest object, which contains the Artifact ID of the ProcessingProfile object, and Artifact ID of an associated Workspace object. See the following sample code:

public async Task<bool> ProcessingProfileManager_DeleteAsync(IHelper helper, int processingProfileId)
{
    bool success = false;

    //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
    //agents, and custom Pages. They are mocked in these samples.
    //This sample code executes under the context of the current user.
    using (IProcessingProfileManager proxy = helper.GetServicesManager().CreateProxy<IProcessingProfileManager>(ExecutionIdentity.User))
    {
        try
        {
            // Create the ProcessingProfileDeleteRequest object.
            ProcessingProfileDeleteRequest deleteRequest = new ProcessingProfileDeleteRequest
            {
                ProcessingProfileId = processingProfileId,
                WorkspaceId = WorkspaceId
            };
            ProcessingProfileDeleteResponse deleteResponse = await proxy.DeleteAsync(deleteRequest).ConfigureAwait(false);

            if (deleteResponse.Deleted)
            {
                success = true;
            }
            else
            {
                Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_DeleteAsync), "Deletion failed", this.GetType().Name);
            }
        }
        catch (ServiceException exception)
        {
            //The service returns exceptions of type ServiceException.
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingProfileManager_DeleteAsync), exception.Message, this.GetType().Name);
        }
    }
    return success;
}

Processing Data Source Manager

The Processing Data Source Manager service supports read and save operations on data source objects. The ProcessingDataSource class represents a data source that contains the location of the files for discovery during processing. For more information, see Processing sets on the RelativityOne Documentation site.

Create a ProcessingDataSource

To create a ProcessingDataSource instance, invoke the constructor and initialize the following properties:

  • ArtifactID – set this property to 0, indicating that you are creating a new instance.
  • Custodian – set this property to the Artifact ID associated with this data source.
  • TimeZone – set this property to the Artifact ID that you obtained from the workspace database. See Required Artifact IDs.
  • DestinationFolder – set this property to the Artifact ID that you obtained from the workspace database. See Required Artifact IDs.
  • StartNumber – set this property to the value used to begin numbering a sequence of documents published from a specific data source. This field should not be selected if the Processing Profile has Level Numbering selected for Numbering Type.

    Note: You can set this property to null. When it is null, Relativity uses auto-numbering. For more information about numbering type options, see Processing sets on the RelativityOne Documentation site.

  • IsStartNumberVisible – determines whether Relativity UI displays the Start Number field in the Data Source layout. This field should not be selected if the Processing Profile has Level Numbering selected for Numbering Type.
  • Other properties – set them to their required values. The following code sample uses the default values.

Call the SaveAsync() method on the proxy created with the IProcessingDataSourceManager interface. You must then pass this method the initialized ProcessingDataSource instance and the workspace Artifact ID as illustrated in the following code.

public async Task<bool> ProcessingDataSourceManager_Create_SaveAsync(IHelper helper, int custodianArtifactId, int destinationFolderArtifactId, int timeZoneArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingDataSourceManager proxy = helper.GetServicesManager().CreateProxy<IProcessingDataSourceManager>(ExecutionIdentity.User))
   {
      try
      {
         //Build the processing ProcessingDataSource object.
         ProcessingDataSource processingDataSource = new ProcessingDataSource
         {
            ArtifactID = 0, // Indicates a new ProcessingDataSource object.
            ProcessingSet = new ProcessingSetRef { ArtifactID = ProcessingSetId },
            Custodian = custodianArtifactId,
            DestinationFolder = destinationFolderArtifactId,
            DocumentNumberingPrefix = "REL",
            InputPath = "@Some/Path",
            Name = "Data Source 1",
            OcrLanguages = new[] { OcrLanguage.English },
            Order = 200,
            TimeZone = timeZoneArtifactId,
            StartNumber = 8,
            IsStartNumberVisible = true,
         };

         //Create the ProcessingDataSource object. The service returns the Artifact ID for the object.
         int artifactId = await proxy.SaveAsync(processingDataSource, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingDataSourceManager_Create_SaveAsync), "Create failed", this.GetType().Name);
         }
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingDataSourceManager_Create_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Read a ProcessingDataSource

Read the values for the properties on a ProcessingDataSource object by calling the ReadAsync() method on the proxy created with the IProcessingDataSourceManager interface. The ReadAsync() method requires that you pass the Artifact IDs of the ProcessingDataSource object and the workspace as arguments.

public async Task<bool> ProcessingDataSourceManager_ReadAsync(IHelper helper, int processingDataSourceArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingDataSourceManager proxy = helper.GetServicesManager().CreateProxy<IProcessingDataSourceManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingSet object.
         ProcessingDataSource processingDataSource = await proxy.ReadAsync(processingDataSourceArtifactId, WorkspaceId);

         //Display the input path.
         Logger.LogMessage(LogLevel.Debug, nameof(ProcessingDataSourceManager_ReadAsync), processingDataSource.InputPath, this.GetType().Name);

         success = true;
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingDataSourceManager_ReadAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Update a ProcessingDataSource

When updating a ProcessingDataSource instance, you call the AsyncRead() method on the proxy created with the IProcessingDataSourceManager interface. Next, set the properties on the instance to their new values, and then call the SaveAsync() method. You must call the SaveAsync() method in order for your changes to be added to the database.

public async Task<bool> ProcessingDataSourceManager_Update_SaveAsync(IHelper helper, int processingDataSourceArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingDataSourceManager proxy = helper.GetServicesManager().CreateProxy<IProcessingDataSourceManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingDataSource object.
         ProcessingDataSource processingDataSource = await proxy.ReadAsync(processingDataSourceArtifactId, WorkspaceId);

         //Modify the input path and destination folder.
         processingDataSource.InputPath = "@Some/Other/Path";
         processingDataSource.DestinationFolder = 99; // Artifact Id of the destination folder

         //Update the processing data source object. The service returns the Artifact ID of the object.
         int artifactId = await proxy.SaveAsync(processingDataSource, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingDataSourceManager_Update_SaveAsync), "Update failed", this.GetType().Name);
         }
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingDataSourceManager_Update_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Processing Set Manager

The Processing Set Manager service supports read and save operations on processing set objects. The ProcessingSet class represents a processing set object that links a processing profile to one or more data sources. For more information, see Processing sets on the RelativityOne Documentation site.

Create a ProcessingSet

To create a ProcessingSet instance, invoke the constructor and then initialize the following properties:

  • ArtifactID – set this property to 0, indicating that you are creating a new instance.
  • EmailNotificationRecipients – set this optional property to an array of email addresses.
  • Name – set this property to the name of the processing set.
  • Profile – set this property to the Artifact ID of the processing profile that you obtained from your workspace database table. See Required Artifact IDs.

Call the SaveAsync() method on the proxy created with the IProcessingSetManager interface. You must then pass the initialized ProcessingSet object and workspace Artifact ID to this method.

public async Task<bool> ProcessingSetManager_Create_SaveAsync(IHelper helper, int processingProfileArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingSetManager proxy = helper.GetServicesManager().CreateProxy<IProcessingSetManager>(ExecutionIdentity.User))
   {
      try
      {
         //Build the ProcessingSet object.
         ProcessingSet processingSet = new ProcessingSet
         {
            ArtifactID = 0, // Indicates a new ProcessingSet object.
            EmailNotificationRecipients = new[] { "johnSmith@domain.com", "adamJohnson@domain.com" },
            Name = "Test Set",
            Profile = new ProcessingProfileRef(processingProfileArtifactId)  // The Artifact ID of the processing profile.
         };

         //Create the ProcessingSet object. The service returns the Artifact ID of the object.
         int artifactId = await proxy.SaveAsync(processingSet, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_Create_SaveAsync), "Create failed", this.GetType().Name);
         }
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_Create_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Read a ProcessingSet

Read the values for the properties on a ProcessingSet object by calling the ReadAsync() method on the IProcessingSetManager. The ReadAsync() method requires that you pass the Artifact IDs of the ProcessingSet object and the workspace as arguments.

public async Task<bool> ProcessingSetManager_ReadAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingSetManager proxy = helper.GetServicesManager().CreateProxy<IProcessingSetManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingSet object.
         ProcessingSet processingSet = await proxy.ReadAsync(processingSetArtifactId, WorkspaceId);

         //Display the Artifact ID of the processing profile.
         string profileId = $"{processingSet.Profile.ArtifactID}";
         Logger.LogMessage(LogLevel.Debug, nameof(ProcessingSetManager_ReadAsync), profileId, this.GetType().Name);

         success = true;
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_ReadAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Update a ProcessingSet

When updating a ProcessingSet instance, you call the AsyncRead() method on the proxy created with the IProcessingSetManager interface. Next, set the properties on the instance to their new values, and then call the SaveAsync() method. You must call the SaveAsync() method in order for your changes to be added to the database.

public async Task<bool> ProcessingSetManager_Update_SaveAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingSetManager proxy = helper.GetServicesManager().CreateProxy<IProcessingSetManager>(ExecutionIdentity.User))
   {
      try
      {
         //Read the ProcessingSet object.
         ProcessingSet processingSet = await proxy.ReadAsync(processingSetArtifactId, WorkspaceId);

         //Modify the list of email recipients list and the name of the processing set.
         processingSet.EmailNotificationRecipients = new[] { "johnSmith@domain.com" };
         processingSet.Name = "Test Set";

         //Update the ProcessingSet object. The service returns the Artifact ID of the object.
         int artifactId = await proxy.SaveAsync(processingSet, WorkspaceId);
         if (artifactId != 0)
         {
            success = true;
         }
         else
         {
            Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_Update_SaveAsync), "Update failed", this.GetType().Name);
         }
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_Update_SaveAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Retrieve a list of processing sets and related aggregate information

You can use the GetDocumentAggregates() method to retrieve document totals and other information about processing sets in a specific workspace. To retrieve this information, the process sets must have the statuses of Completed or Completed with errors. If you wanted to create a custom dashboard for reporting purposes, use this method to populate it with information about completed processing sets. For example, Relativity uses the GetDocumentAggregates() method to populate the Early Case Assessment dashboard with processing set data.

Use the following classes in conjunction with the GetDocumentAggregates() method. For additional reference information, see Processing API.

public async Task<ProcessingSetDocumentInfoSummary> ProcessingSetManager_GetDocumentAggregatesAsync(IHelper helper, int workspaceArtifactId)
{
   // Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   // agents, and custom Pages. They are mocked in these samples.
   // This sample code executes under the context of the current user.
   using (IProcessingSetManager proxy = helper.GetServicesManager().CreateProxy<IProcessingSetManager>(ExecutionIdentity.User))
   {
      try
      {
         // Build the GetDocumentAggregatesRequest object.
         GetDocumentAggregatesRequest request = new GetDocumentAggregatesRequest
         {
            Page = 0,
            PageSize = 15,
            SortColumnName = "ProcessingSetName",
            SortDescending = true,
            WorkspaceArtifactId = workspaceArtifactId
         };

         // Submit the request. The service returns information for all 'Completed' and 'Completed with Errors'
         // Processing Sets in the given workspace.
         ProcessingSetDocumentInfoSummary processingSetDocumentInfoSummary = await proxy.GetDocumentAggregates(request);
         return processingSetDocumentInfoSummary;
      }
      catch (ServiceException serviceException)
      {
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingSetManager_GetDocumentAggregatesAsync), serviceException.Message, this.GetType().Name);
         throw;
      }
   }
}

Processing Job Manager

The Processing Job Manager service includes methods for executing inventory, discovery, and publishing jobs. It also includes a method for canceling any of these jobs for a processing set. This service is available through the IProcessingJobManager interface. For more information, see Common processing workflows.

Inventory jobs

The following code illustrates how to run an inventory job by calling the SubmitInventoryJobsAsync() method on the proxy created with the IProcessingJobManager interface. You must pass an initialized InventoryJob instance to this method. This instance has the Artifact ID of the processing set that you want to use for the job, and the Artifact ID of the workspace where it resides.

If you want to use filtering on your inventory job, apply filters through Relativity after you programmatically run your inventory job. For more information, see Inventory on the RelativityOne Documentation site.

public async Task<bool> ProcessingJobManager_InventoryAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingJobManager proxy = helper.GetServicesManager().CreateProxy<IProcessingJobManager>(ExecutionIdentity.User))
   {
      try
      {
         //Create an inventory job object.
         InventoryJob inventoryJob = new InventoryJob
         {
            ProcessingSetId = processingSetArtifactId,
            WorkspaceArtifactId = WorkspaceId
         };

         //Submit the job for inventory.
         await proxy.SubmitInventoryJobsAsync(inventoryJob);

         success = true;
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingJobManager_InventoryAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Discovery jobs

The following code illustrates how to run a discovery job by calling the SubmitDiscoveryJobsAsync() method on the proxy created with the IProcessingJobManager interface. You must pass an initialized DiscoveryJob instance to this method. The DiscoveryJob instance represents a processing job that you want to run. This instance has the Artifact ID of the processing set that you want to use for the job, and the Artifact ID of the workspace where it resides. For more information, see Processing on the RelativityOne Documentation site

public async Task<bool> ProcessingJobManager_DiscoveryAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user. For more information, see the documentation for Relativity API Helpers.
   using (IProcessingJobManager proxy = helper.GetServicesManager().CreateProxy<IProcessingJobManager>(ExecutionIdentity.User))
   {
      try
      {
         //Create a discovery job object.
         DiscoveryJob discoveryJob = new DiscoveryJob
         {
            ProcessingSetId = processingSetArtifactId,
            WorkspaceArtifactId = WorkspaceId
         };

         //Submit the job for discovery.
         await proxy.SubmitDiscoveryJobsAsync(discoveryJob);

         success = true;
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingJobManager_DiscoveryAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Publishing jobs

The following code illustrates how to execute a publishing job by calling the SubmitPublishJobsAsync() method on the proxy created with the IProcessingJobManager interface. You must pass an initialized PublishJob instance to this method. This instance has the Artifact ID of the processing set that you want to use for the job, and the Artifact ID of the workspace where it resides.

Similar to the Relativity UI, you can resubmit a publishing job with processing errors by calling the SubmitPublishJobsAsync() method again. For more information, see Publishing files on the RelativityOne Documentation site.

public async Task<bool> ProcessingJobManager_PublishAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingJobManager proxy = helper.GetServicesManager().CreateProxy<IProcessingJobManager>(ExecutionIdentity.User))
   {
      try
      {
         //Create a publish job object.
         PublishJob publishJob = new PublishJob
         {
            ProcessingSetId = processingSetArtifactId,
            WorkspaceArtifactId = WorkspaceId
         };

         //Submit the job for discovery.
         await proxy.SubmitPublishJobsAsync(publishJob);

         success = true;
      }
      catch (ServiceException exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingJobManager_PublishAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Cancel jobs

You can use the SubmitCancelJobAsync() method to cancel inventory, discovery, and publishing jobs for a specific processing set. The following code illustrates how to execute a cancel job by calling this method on the proxy created with the IProcessingJobManager interface. You must pass an initialized CancelJob instance to this method. This instance has the Artifact ID of the processing set associated with the job that you want to cancel, and the Artifact ID of the workspace where it resides.

This sample code returns a Boolean value called success after the cancel job has been successfully submitted. However, this return value doesn't indicate that the job has been canceled. Multiple factors influence when a worker picks up a cancel job and how long the job takes to execute. For example, the amount of data and system state can affect this outcome.

Note: The submission of cancel job returns successfully when the job associated with a processing set has already been canceled.

public async Task<bool> ProcessingJobManager_CancelAsync(IHelper helper, int processingSetArtifactId)
{
   bool success = false;

   //Get a connection to the API using the Relativity API Helper classes, available on event handlers,
   //agents, and custom Pages. They are mocked in these samples.
   //This sample code executes under the context of the current user.
   using (IProcessingJobManager proxy = helper.GetServicesManager().CreateProxy<IProcessingJobManager>(ExecutionIdentity.User))
   {
      try
      {
         //Create a cancel job object.
         CancelJob cancelJob = new CancelJob
         {
            ProcessingSetId = processingSetArtifactId,
            WorkspaceArtifactId = WorkspaceId
         };

         //Submit a job to cancel a processing set.
         await proxy.SubmitCancelJobAsync(cancelJob);

         success = true;
      }
      catch (Exception exception)
      {
         //The service returns exceptions of type ServiceException.
         Logger.LogMessage(LogLevel.Error, nameof(ProcessingJobManager_CancelAsync), exception.Message, this.GetType().Name);
      }
   }
   return success;
}

Community Updates

Aero Developer FAQ Evolving the Platform Most recent release notes
Learn more Learn more Learn more

Additional Resources

   
Access Third-Party Tools with GitHub     Create .NET Apps Faster with NuGet
Visit github     visit nuget