Pre Uninstall event handlers

You can use Pre Uninstall event handlers to perform cleanup tasks associated with removing an application from workspaces or from your Relativity environment, such as deleting choices, fields, objects, and other items. It executes immediately after an agent starts running an uninstall job. For example, you can add functionality to clear entries from database tables or to drop unneeded tables.

Guidelines for Pre Uninstall event handlers

  • Create a new class in Visual Studio.

    Note: You can also use a template to create this event handler type. For more information, see Visual Studio templates.

  • Add NuGet packages - ensure your Visual Studio project has installed the relevant NuGet packages, including at a minimum the Relativity.EventHandler and Relativity.Api packages.
  • Add a GUID for the event handler - set the System.Runtime.InteropServices.Guid to the GUID identifying your event handler. Use the GUID generator in Visual Studio.
  • Set the CustomAttributes.Description attribute - provide a description that you want to appear in the Relativity UI for the event handler.
  • Inherit from the PreUninstallEventHandler class – ensure that you extend the PreUninstallEventHandler base class.
  • Override the Execute() method – add your business logic for the event handler to this method. This method runs when your event handler is triggered.

Code sample for a Pre Uninstall event handler

Review the following sample code for the SamplePreUninstallEventHandler class. This code sample illustrates how to verify that an application is installed in a workspace. It also illustrates how to use the workspace ArtifactID to delete rows from a queue table, and how to drop a local workspace table.

Copy
using System;
using System.Data.SqlClient;
using System.Runtime.InteropServices;

using kCura.EventHandler;
using kCura.EventHandler.CustomAttributes;
using Relativity.API;

namespace Examples.EventHandlers.Install
{

    /// <summary>
    /// This event handler runs when the application is uninstalled and deletes a queue table from the EDDS database.
    /// </summary>
    [Description("Example uninstall event handler")]
    [Guid("B25E0A6D-57B5-416B-9110-69DD86A07B5A")]
    public class ExamplePreUninstallEventHandler : PreUninstallEventHandler
    {
        private static Guid EXAMPLE_APPLICATION_GUID = new Guid("B4F52C6C-F55C-488F-BA71-E8EE8B5C74F4");

        public override Response Execute()
        {
            //Construct a response object with default values.
            Response retVal = new Response();

            try
            {
                //Get the EDDS database context.
                IDBContext eddsDBContext = this.Helper.GetDBContext(-1);
                //Get the current workspace artifactID.
                int currentWorkspaceID = this.Helper.GetActiveCaseID();
                //Get the current workspace database context.
                IDBContext workspaceDBContext = this.Helper.GetDBContext(currentWorkspaceID);
                //Determine how many workspaces have this application installed.
                if (!IsLastApplicationInEnvironment(eddsDBContext, currentWorkspaceID))
                {
                    //If this application is installed on other workspaces, leave the table and delete entries for this workspace only.
                    RemoveWorkspaceEntriesFromQueueTable(eddsDBContext, currentWorkspaceID);
                }
                else
                {
                    //If this application isn't installed on any other workspaces, drop the queue table.
                    DropEDDSWorkspaceTablesIfExists(eddsDBContext);
                }

                retVal.Message = string.Empty;
                retVal.Success = true;
            }
            catch (Exception ex)
            {
                //Catch an exception if it occurs and fail the uninstall.
                retVal.Success = false;
                retVal.Message = ex.ToString();
            }

            return retVal;
        }

        /// <summary>
        /// Check to see if the application is installed in any other cases, or if this the last one.
        /// </summary>
        /// <param name="eddsDBContext">A properly constructed EDDS database context</param>
        /// <param name="currentWorkspaceID">Current workspace ArtifactID</param>
        /// <returns>True if no other workspaces have this application installed. False if other workspaces have this application installed.</returns>
        private static bool IsLastApplicationInEnvironment(IDBContext eddsDBContext, int currentWorkspaceID)
        {
            string applicationCountSQL = @"
DECLARE @applicationID INT = (SELECT [ArtifactID] FROM [LibraryApplication] WHERE [GUID] = @applicationGUID)
SELECT
    COUNT([CaseApplicationID])
FROM
    [CaseApplication]
WHERE
    [ApplicationID] IN (SELECT [ArtifactID] FROM [LibraryApplication] WHERE [GUID] = @applicationGUID)
    AND
    [CaseID] <> @workspaceArtifactID
";
            SqlParameter applicationGUIDParam = new SqlParameter("@applicationGUID", System.Data.SqlDbType.UniqueIdentifier)
            {
                Value = EXAMPLE_APPLICATION_GUID
            };
            SqlParameter workspaceArtifactIDParam1 = new SqlParameter("@workspaceArtifactID", System.Data.SqlDbType.Int)
            {
                Value = currentWorkspaceID
            };

            int installCount = eddsDBContext.ExecuteSqlStatementAsScalar<int>(applicationCountSQL, applicationGUIDParam, workspaceArtifactIDParam1);

            return installCount == 0;
        }

        /// <summary>
        /// Remove all workspace entries from queue table in the EDDS database.
        /// </summary>
        /// <param name="eddsDBContext">A properly constructed EDDS database context</param>
        /// <param name="currentWorkspaceID">Current workspace ArtifactID</param>
        private static void RemoveWorkspaceEntriesFromQueueTable(IDBContext eddsDBContext, int currentWorkspaceID)
        {
            string deleteWaitingJobsSQL = "DELETE FROM [ExampleMessageQueue] WHERE [WorkspaceArtifactID] = @workspaceArtifactID";
            SqlParameter workspaceArtifactIDParam = new SqlParameter("@workspaceArtifactID", System.Data.SqlDbType.Int)
            {
                Value = currentWorkspaceID
            };
            eddsDBContext.ExecuteNonQuerySQLStatement(deleteWaitingJobsSQL, new[] { workspaceArtifactIDParam });
        }

        /// <summary>
        /// Drop the EDDS tables from the environment when they are no longer needed.
        /// </summary>
        /// <param name="eddsDBContext">A properly constructed EDDS database context</param>
        private static void DropEDDSWorkspaceTablesIfExists(IDBContext eddsDBContext)
        {
            string sql = FormatDropTableSQL("ExampleMessageQueue");
            eddsDBContext.ExecuteNonQuerySQLStatement(sql);
        }

        /// <summary>
        /// Create a SQL statement to check if a table exists and drop the table if it does.
        /// </summary>
        /// <param name="tableName">Name of the table to look for</param>
        /// <returns></returns>
        private static string FormatDropTableSQL(string tableName)
        {
            return $"DROP TABLE IF EXISTS [{tableName}]";
        }
    }
}