示例#1
0
        public static bool FindFieldOnLayout(IDBContext context, int fieldArtifactID, int layoutArtifactID, IAPILog logger)
        {
            string sql =
                @"SELECT COUNT(1)
            FROM LayoutField
            WHERE FieldArtifactID = @fieldArtifactID
                AND LayoutArtifactID = @layoutArtifactID";

            SqlParameter fieldArtifact  = new SqlParameter("@fieldArtifactID", SqlDbType.Int);
            SqlParameter layoutArtifact = new SqlParameter("@layoutArtifactID", SqlDbType.Int);

            fieldArtifact.Value  = fieldArtifactID;
            layoutArtifact.Value = layoutArtifactID;

            logger.LogDebug("Querying for field {fieldArtifactID} on layout {layoutArtifactID}", fieldArtifactID, layoutArtifactID);
            var count = context.ExecuteSqlStatementAsScalar <int>(sql, new SqlParameter[] { fieldArtifact, layoutArtifact });

            logger.LogDebug("Count returned from LayoutField: {count}", count);

            if (count > 0)
            {
                return(true);
            }

            return(false);
        }
示例#2
0
        public async Task OnButtonClickAsync(ConsoleButton consoleButton, IAPILog logger)
        {
            var selectedObjectType = string.Empty;

            var colObjectType = (ChoiceCollection)ActiveArtifact.Fields[GetArtifactIdByGuid(Constant.Guids.Field.ExportUtilityJob.ObjectType)].Value.Value;

            foreach (Choice objectType in colObjectType)
            {
                if (!objectType.IsSelected)
                {
                    continue;
                }
                selectedObjectType = objectType.Name;
                break;
            }

            var exportManagerResultsTableName = $"{Constant.Names.TablePrefix}Export_Manager_Results_{Guid.NewGuid()}";

            switch (consoleButton.Name)
            {
            case Constant.Buttons.SUBMIT:
                logger.LogDebug($"{Constant.Names.ApplicationName} - {Constant.Buttons.SUBMIT} button clicked.");
                var recordExists = await DoesRecordExistAsync();

                if (recordExists == false)
                {
                    var resourceGroupId = await ArtifactQueries.GetResourcePoolArtifactId(Helper.GetServicesManager(), ExecutionIdentity.System, Helper.GetActiveCaseID());

                    await SqlQueryHelper.InsertRowIntoExportManagerQueueAsync(Helper.GetDBContext(-1), Helper.GetActiveCaseID(), 1, Helper.GetAuthenticationManager().UserInfo.ArtifactID, ActiveArtifact.ArtifactID, resourceGroupId, selectedObjectType, exportManagerResultsTableName);
                }
                break;

            case Constant.Buttons.DOWNLOAD_FILE:
                logger.LogDebug($"{Constant.Names.ApplicationName} - {Constant.Buttons.DOWNLOAD_FILE} button clicked.");
                var id = await RetrieveIdByArtifactIdAsync();

                if (id > 0)
                {
                    await SqlQueryHelper.RemoveRecordFromTableByIdAsync(Helper.GetDBContext(-1), Constant.Tables.ExportManagerQueue, id);
                }
                break;
            }
        }
        public async Task OnButtonClickAsync(ConsoleButton consoleButton, IAPILog logger)
        {
            bool recordExists;
            var  selectedObjectType = ActiveArtifact.Fields[GetArtifactIdByGuid(Constant.Guids.Field.ExportUtilityJob.ObjectType)].Value.Value.ToString();

            switch (consoleButton.Name)
            {
            case Constant.Buttons.VALIDATE:
                logger.LogDebug($"{Constant.Names.ApplicationName} - {Constant.Buttons.VALIDATE} button clicked.");
                recordExists = await DoesRecordExistAsync();

                if (recordExists == false)
                {
                    Int32 resourceGroupId = await ArtifactQueries.GetResourcePoolArtifactId(Helper.GetServicesManager(), ExecutionIdentity.System, Helper.GetActiveCaseID());

                    await SqlQueryHelper.InsertRowIntoImportManagerQueueAsync(Helper.GetDBContext(-1), Helper.GetActiveCaseID(), 1, Helper.GetAuthenticationManager().UserInfo.ArtifactID, ActiveArtifact.ArtifactID, resourceGroupId, selectedObjectType, Constant.ExportUtilityJob.JobType.VALIDATE);
                }
                break;

            case Constant.Buttons.SUBMIT:
                logger.LogDebug($"{Constant.Names.ApplicationName} - {Constant.Buttons.SUBMIT} button clicked.");
                recordExists = await DoesRecordExistAsync();

                if (recordExists == false)
                {
                    Int32 resourceGroupId = await ArtifactQueries.GetResourcePoolArtifactId(Helper.GetServicesManager(), ExecutionIdentity.System, Helper.GetActiveCaseID());

                    await SqlQueryHelper.InsertRowIntoImportManagerQueueAsync(Helper.GetDBContext(-1), Helper.GetActiveCaseID(), 1, Helper.GetAuthenticationManager().UserInfo.ArtifactID, ActiveArtifact.ArtifactID, resourceGroupId, selectedObjectType, Constant.ExportUtilityJob.JobType.VALIDATE_SUBMIT);
                }
                break;

            case Constant.Buttons.CANCEL:
                logger.LogDebug($"{Constant.Names.ApplicationName} - {Constant.Buttons.CANCEL} button clicked.");
                var id = await RetrieveIdByArtifactIdAsync();

                if (id > 0)
                {
                    await SqlQueryHelper.RemoveRecordFromTableByIdAsync(Helper.GetDBContext(-1), Constant.Tables.ImportManagerQueue, id);
                }
                break;
            }
        }
        public void Run()
        {
            int agentTypeId;
            int agentToDeleteId;
            int counter;
            List <SpotsPerServer> agentsPerServer = new List <SpotsPerServer>();

            while (_agentsToDelete.Count > 0)
            {
                _logger.LogDebug(string.Format("{0} AgentsDesiredObjects to be deleted", _agentsToDelete.Count));

                counter = _agentsToDelete.Count - 1;
                while (counter >= 0)
                {
                    _agentsToDelete[counter].Count = Math.Abs(_agentsToDelete[counter].Count);
                    agentTypeId     = _environment.GetArtifactIdFromGuid(_agentsToDelete[counter].Guid);
                    agentsPerServer = _environment.GetAgentsPerServerByPool(agentTypeId, _poolId);
                    if (agentsPerServer.Count > 0)
                    {
                        agentsPerServer = agentsPerServer.OrderByDescending(x => x.Spots).ToList();
                        if (agentsPerServer[0].Spots > 0)
                        {
                            agentToDeleteId = _deleteAgent.GetAgentIdToDelete(agentTypeId, agentsPerServer[0].AgentServerArtifactId);
                            _deleteAgent.Delete(agentToDeleteId);
                            _agentsToDelete[counter].Count -= 1;

                            if (_agentsToDelete[counter].Count < 1)
                            {
                                _agentsToDelete.Remove(_agentsToDelete[counter]);
                            }
                        }
                        else
                        {
                            _agentsToDelete.Remove(_agentsToDelete[counter]);
                        }
                    }
                    else
                    {
                        _agentsToDelete.Remove(_agentsToDelete[counter]);
                    }

                    counter -= 1;
                }
            }
        }
        public List <AgentsDesired> Compare()
        {
            List <AgentsDesired> outputList = new List <AgentsDesired>();
            string logString = "";

            int counter = _agentsDesiredList.Count - 1;

            while (counter >= 0)
            {
                //Declaring all of these to variables to make logging easier
                int    currentCount;
                string agentGuid    = _agentsDesiredList[counter].Guid;
                int    agentTypeId  = _environment.GetArtifactIdFromGuid(agentGuid);
                int    desiredCount = _agentsDesiredList[counter].Count;

                //Account for agents Resource Pool policy
                if (_agentsDesiredList[counter].RespectsResourcePool)
                {
                    currentCount = _environment.GetAgentCountByPool(agentTypeId, _poolId);
                }
                else
                {
                    currentCount = _environment.GetAgentCount(agentTypeId);
                }

                int difference = desiredCount - currentCount;

                logString += string.Format("AgentGuid: {0}, AgentTypeID {1}, Current Count: {2}, Desired Count: {3} Difference: {4}\r\n", agentGuid, agentTypeId, currentCount, desiredCount, difference);

                outputList.Add(new AgentsDesired
                {
                    Guid = _agentsDesiredList[counter].Guid,
                    RespectsResourcePool = _agentsDesiredList[counter].RespectsResourcePool,
                    Count = difference
                });

                counter -= 1;
            }
            _logger.LogDebug("Compare output--\r\n" + logString);
            return(outputList);
        }
示例#6
0
        public override Response Execute()
        {
            Helper.GetLoggerFactory().GetLogger();
            //Construct a response object with default values.
            Response retVal = new Response();

            retVal.Success = true;
            retVal.Message = String.Empty;

            //Get the logger from the helper
            IAPILog logger = Helper.GetLoggerFactory().GetLogger();

            logger.LogVerbose("Log information throughout execution.");


            try
            {
                IRSAPIClient proxy = Helper.GetServicesManager().CreateProxy <IRSAPIClient>(ExecutionIdentity.System);

                //Set the proxy to use the current workspace
                proxy.APIOptions.WorkspaceID = -1;

                //Get a dbContext for the EDDS database
                IDBContext dbContext      = Helper.GetDBContext(-1);
                Boolean    isValidSandbox = false;

                //Check to see if its an R1 instance
                logger.LogDebug($"DAPI - {nameof(DynamicApiPreInstallEventHandler)} - {nameof(Execute)} - Checking to see if the relativity instance is a cloud instance.");

                int doesCloudInstanceSettingExist = DoesInstanceSettingExists(dbContext, RELATIVITY_URL_SECTION_NAME, RELATIVITY_CLOUD_INSTANCE_SETTING);

                string cloudInstanceSetting = GetInstanceSetting(dbContext, RELATIVITY_URL_SECTION_NAME, RELATIVITY_CLOUD_INSTANCE_SETTING);
                if (!string.IsNullOrWhiteSpace(cloudInstanceSetting))
                {
                    if (cloudInstanceSetting.ToLower().Equals("true"))
                    {
                        logger.LogDebug($"DAPI - {nameof(DynamicApiPreInstallEventHandler)} - {nameof(Execute)} - Relativity instance is a cloud instance.");

                        //Get the URL for the Relativity Instance URL
                        string relativityInstance = GetInstanceSetting(dbContext, RELATIVITY_URL_SECTION_NAME, RELATIVITY_URL_NAME);

                        if (string.IsNullOrWhiteSpace(relativityInstance))
                        {
                            isValidSandbox = false;
                        }
                        else
                        {
                            //If Relativity instance ends with sandbox.relativity.one then install the application
                            if (relativityInstance.ToLower().EndsWith(SandboxString1.ToLower()) || relativityInstance.ToLower().EndsWith(SandboxString2.ToLower()))
                            {
                                isValidSandbox = true;
                            }
                        }
                    }
                    else
                    {
                        isValidSandbox = true;
                    }
                }

                // If on-prem or sandbox RelOne
                if (doesCloudInstanceSettingExist == 0 || isValidSandbox)
                {
                    logger.LogDebug($"DAPI - {nameof(DynamicApiPreInstallEventHandler)} - {nameof(Execute)} - Application installation was successful.");
                    retVal.Success = true;
                    retVal.Message = String.Empty;
                }
                else
                {
                    logger.LogDebug($"DAPI - {nameof(DynamicApiPreInstallEventHandler)} - {nameof(Execute)} - Relativity instance is not an RelOne Developer Sandbox or On-Prem, installation has been stopped.");
                    retVal.Success = false;
                    retVal.Message = "Application is only allowed to be installed in an RelOne Developer Sandbox or On-Prem Instance.";
                }
            }
            //If its an On-prem instance do nothing
            catch (Exception ex)
            {
                //Change the response Success property to false to let the user know an error occurred
                retVal.Success = false;
                retVal.Message = ex.ToString();
            }

            return(retVal);
        }
示例#7
0
 public void LogDebug(string message)
 {
     _logger.LogDebug(message);
 }
        public void Run()
        {
            int  counter;
            bool outOfServers = false;

            //while there are rows in the agent desired list and we have not run out of servers
            while (_agentsDesired.Count > 0 && outOfServers == false)
            {
                _logger.LogDebug(string.Format("{0} AgentsDesiredObjects desired", _agentsDesired.Count));
                //Create index counter for _agentsDesired
                counter = _agentsDesired.Count() - 1;

                //before counter gets to negative index range
                while (counter >= 0)
                {
                    //Are there any agents to be created for this object?
                    if (_agentsDesired[counter].Count > 0)
                    {
                        //Are there any servers available?
                        if (_spotsPerServer.Count > 0)
                        {
                            //Order the agent servers by spots descending, and then select first object
                            _spotsPerServer = _spotsPerServer.OrderByDescending(x => x.Spots).ToList();
                            if (_spotsPerServer[0].Spots > 0)
                            {
                                _createAgent.Create(_agentsDesired[counter].Guid, _spotsPerServer[0].AgentServerArtifactId);

                                _spotsPerServer[0].Spots      -= 1;
                                _agentsDesired[counter].Count -= 1;

                                if (_agentsDesired[counter].Count < 1)
                                {
                                    _agentsDesired.Remove(_agentsDesired[counter]);
                                }

                                if (_spotsPerServer[0].Spots < 1)
                                {
                                    _spotsPerServer.Remove(_spotsPerServer[0]);
                                }
                            }
                            else
                            {
                                _spotsPerServer.Remove(_spotsPerServer[0]);
                            }
                        }
                        else
                        {
                            //Out of servers!
                            _logger.LogWarning("We've run out of spots! {count} remaining AgentsDesiredObjects", _agentsDesired.Count);
                            outOfServers = true;
                            break;
                        }
                    }
                    else
                    {
                        _agentsDesired.Remove(_agentsDesired[0]);
                    }
                    counter -= 1;
                }
            }
        }
        public async Task <kCura.EventHandler.Response> ExecuteAsync()
        {
            return(await Task.Run(() =>
            {
                _logger = Helper.GetLoggerFactory().GetLogger();

                var response = new kCura.EventHandler.Response
                {
                    Success = true,
                    Message = String.Empty
                };
                var sqlQueryHelper = new SqlQueryHelper();

                //Create the Export Utility Job Manager queue table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Export Utility Job Manager queue table if it doesn't already exist");
                var exportManagerTableTask = sqlQueryHelper.CreateExportManagerQueueTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Export Utility Job Manager queue table if it doesn't already exist");

                //Create the Export Utility Job Worker queue table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Export Utility Job Worker queue table if it doesn't already exist");
                var exportWorkerTableTask = sqlQueryHelper.CreateExportWorkerQueueTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Export Utility Job Worker queue table if it doesn't already exist");

                //Create the Export Utility Job Error log table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Export Utility Job Error Log table if it doesn't already exist");
                var exportErrorLogTableTask = sqlQueryHelper.CreateExportErrorLogTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Export Utility Job Error Log table if it doesn't already exist");

                //Create the Import Utility Job Manager queue table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Import Utility Job Manager queue table if it doesn't already exist");
                var importManagerTableTask = sqlQueryHelper.CreateImportManagerQueueTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Import Utility Job Manager queue table if it doesn't already exist");

                //Create the Import Utility Job Worker queue table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Import Utility Job Worker queue table if it doesn't already exist");
                var importWorkerTableTask = sqlQueryHelper.CreateImportWorkerQueueTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Import Utility Job Worker queue table if it doesn't already exist");

                //Create the Import Utility Job Error log table if it doesn't already exist
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Creating Import Utility Job Error Log table if it doesn't already exist");
                var importErrorLogTableTask = sqlQueryHelper.CreateImportErrorLogTableAsync(Helper.GetDBContext(-1));
                _logger.LogDebug($"{Constant.Names.ApplicationName} - Created Import Utility Job Error Log table if it doesn't already exist");


                try
                {
                    // Waits for all tasks, otherwise exceptions would be lost
                    Task.WaitAll(exportManagerTableTask, exportWorkerTableTask, exportErrorLogTableTask, importManagerTableTask, importWorkerTableTask, importErrorLogTableTask);
                }
                catch (AggregateException aex)
                {
                    _logger.LogError(aex, $"{Constant.Names.ApplicationName} - Post-Install failed. {aex}");
                    var ex = aex.Flatten();
                    var message = ex.Message + " : " + (ex.InnerException?.Message ?? "None");
                    response.Success = false;
                    response.Message = "Post-Install field rename failed with message: " + message;
                }
                return response;
            }));
        }
示例#10
0
        public override Response PopulateScriptBlocks()
        {
            Response retVal = new Response()
            {
                Success = true,
                Message = string.Empty
            };

            int currentWorkspaceArtifactID = Helper.GetActiveCaseID();
            int currentLayoutArtifactID    = this.ActiveLayout.ArtifactID;
            int currentDocumentArtifactID  = this.ActiveArtifact.ArtifactID;

            IAPILog logger = Helper.GetLoggerFactory().GetLogger();

            int fieldArtifactID = RelativityAlertPIEH.Helper.GetFieldArtifactID(_fieldName, Helper, logger).GetAwaiter().GetResult();

            if (fieldArtifactID < 1)
            {
                logger.LogDebug("Alert field {fieldName} not found in workspace {caseArtifactID}",
                                _fieldName, currentWorkspaceArtifactID);
                return(retVal);
            }

            IDBContext workspaceDbContext = this.Helper.GetDBContext(currentWorkspaceArtifactID);
            bool       fieldExists        = RelativityAlertPIEH.Helper.FindFieldOnLayout(workspaceDbContext, fieldArtifactID, currentLayoutArtifactID, logger);

            if (!fieldExists)
            {
                logger.LogVerbose("Alert NOT fired because {fieldName} field not present on workspace {caseArtifactID}, layout {layoutArtifactID}",
                                  _fieldName, currentWorkspaceArtifactID, currentLayoutArtifactID);
                return(retVal);
            }

            string alertFieldText = "";

            if (!this.ActiveArtifact.Fields[_fieldName].Value.IsNull)
            {
                alertFieldText = RelativityAlertPIEH.Helper.SanitizeAlertText(this.ActiveArtifact.Fields[_fieldName].Value.Value.ToString());
            }

            if (!String.IsNullOrEmpty(alertFieldText))
            {
                string alert = $"<script type=\"text/javascript\"> alert(\"{ alertFieldText }\"); </script>";
                this.RegisterClientScriptBlock(new ScriptBlock()
                {
                    Key = "alertKey", Script = alert
                });
                logger.LogDebug("Alert fired on workspace {caseArtifactID}, layout {layoutArtifactID}, and document {documentArtifactID}",
                                currentWorkspaceArtifactID, currentLayoutArtifactID, currentDocumentArtifactID);
            }
            else
            {
                logger.LogVerbose("Alert NOT fired on workspace {caseArtifactID}, layout {layoutArtifactID}, and document {documentArtifactID}",
                                  currentWorkspaceArtifactID, currentLayoutArtifactID, currentDocumentArtifactID);
            }

            logger.LogVerbose("Alert text detected: {alertFieldText}",
                              alertFieldText);

            return(retVal);
        }
示例#11
0
        public override void Execute()
        {
            IAPILog logger = Helper.GetLoggerFactory().GetLogger();

            try
            {
                /* Adding message so time of last check-in updates */
                RaiseMessage("Managing the agents.", 10);

                /* Resource Pool ArtifactID is hard coded for now (Default pool)
                 * Will eventually make this accessible in the UI */
                int poolId = 1015040;

                /* Agent Server Adjustment factor.
                 * Will eventually make this accessible in the UI */
                int adjFactor = 10;

                /* This switch tells Agent Agent to not create any agents on a server containing the dtSearch search agent.
                 * Will eventually make this accessible in the UI*/
                bool ignoreSearchServer = true;

                /*Use API to create/delete agents instead of manually creating in SQL*/
                bool useApiCreate = true;
                bool useApiDelete = true;

                /* Making stuff */
                logger.LogVerbose("Creating new {objectName}", "Agent Helper");
                IAgentHelper agentHelper = Helper;

                logger.LogVerbose("Creating new {objectName}", "EDDS DB Context");
                IDBContext eddsDbContext = agentHelper.GetDBContext(-1);

                logger.LogVerbose("Creating new {objectName}", "Environment Helper");
                EnvironmentHelper environment = new EnvironmentHelper(eddsDbContext);

                logger.LogVerbose("Creating new {objectName}", "Desired Agents List");
                List <AgentsDesired> desiredAgentsList = new GetAgentsDesiredList(agentHelper, environment, poolId, IsOffHours()).AgentsPerServerObjectList;

                logger.LogVerbose("Creating new {objectName}", "Compared List");
                List <AgentsDesired> comparedList = new CompareDesiredAgentsToExisting(desiredAgentsList, poolId, environment, logger).Compare();

                logger.LogVerbose("Creating new {objectName}", "List Helper");
                AgentsDesiredListHelper listHelper = new AgentsDesiredListHelper(comparedList);

                logger.LogVerbose("Creating new {objectName}", "Create List");
                List <AgentsDesired> createList = listHelper.GetAgentCreateList();

                logger.LogVerbose("Creating new {objectName}", "Delete List");
                List <AgentsDesired> deleteList = listHelper.GetAgentDeleteList();

                logger.LogVerbose("Creating new {objectName}", "Spots Per Server List");
                List <SpotsPerServer> spotsPerServerList = new GetSpotsPerServerList(eddsDbContext, environment, adjFactor, poolId, ignoreSearchServer).SpotsPerServerList;

                logger.LogVerbose("Creating {objectName}", "Agent Create");
                ICreateAgent createAgent = new CreateAgentSql(eddsDbContext, environment);
                if (useApiCreate)
                {
                    createAgent = new CreateAgentApi(eddsDbContext, environment, agentHelper);
                }

                logger.LogVerbose("Creating {objectName}", "Agent Delete");
                IDeleteAgent deleteAgent = new DeleteAgent(eddsDbContext);
                if (useApiDelete)
                {
                    deleteAgent = new DeleteAgentApi(eddsDbContext, agentHelper);
                }


                /* Log createList, deleteList, and spotsPerServerList contents */
                string createListString         = "";
                string deleteListString         = "";
                string spotsPerServerListString = "";

                foreach (AgentsDesired cL in createList)
                {
                    createListString += string.Format("{0} - {1} - {2}\r\n", cL.Guid, cL.Count, cL.RespectsResourcePool);
                }

                foreach (AgentsDesired dL in deleteList)
                {
                    deleteListString += string.Format("{0} - {1} - {2}\r\n", dL.Guid, dL.Count, dL.RespectsResourcePool);
                }

                foreach (SpotsPerServer sP in spotsPerServerList)
                {
                    spotsPerServerListString += string.Format("{0} - {1}\r\n", sP.AgentServerArtifactId, sP.Spots);
                }

                logger.LogDebug("Delete List : {deleteList}", deleteListString);
                logger.LogDebug("Create List: {createList}", createListString);
                logger.LogDebug("Spots Per Server List = {spotsPerServerList}", spotsPerServerListString);


                /* Create */
                RunAgentCreate agentCreate = new RunAgentCreate(eddsDbContext, environment, createAgent, createList, spotsPerServerList, logger);
                logger.LogVerbose("Running {objectName}", "Agent Create");
                agentCreate.Run();
                logger.LogVerbose("Completed {objectName}", "Agent Create");


                /* Delete */
                RunAgentDelete agentDelete = new RunAgentDelete(eddsDbContext, environment, deleteAgent, poolId, deleteList, logger);
                logger.LogVerbose("Running {objectName}", "Agent Delete");
                agentDelete.Run();
                logger.LogVerbose("Completed {objectName}", "Agent Delete");
            }
            catch (Exception ex)
            {
                RaiseError(ex.Message, ex.StackTrace);
                logger.LogError("Exception during agent Execute(): {ex}", ex);
                RaiseMessage("There has been an error. See log for more details", 1);
            }
        }