private void updatePreOpTest(ICDSPluginExecutionContext executionContext, TestProxy.Account target) { Assert.AreEqual(Ids.Account, target.Id); //alter the target to see if it get saved to the input parameters collection. target.AccountNumber = "1"; }
/// <summary> /// Demonstration update event handler /// </summary> /// <param name="executionContext">The <see cref="ICDSPluginExecutionContext"/> execution context for /// the handler execution</param> /// <param name="target">The target entity for the update. Contains any fields that are being sent in for update.</param> private void workingWithEntityUpdate(ICDSPluginExecutionContext executionContext, Account target) { var setting = executionContext.Settings.GetValue <string>("ps_environmentvariablename"); // carry out actions only if the update is affecting the name or accountnumber fields if (target.ContainsAny("name", "accountnumber")) { executionContext.Trace("Target contains at least one matching attribute"); // short cut to tracing service Trace method. } // TargetReference - Provides and entity reference for the entity in the InputParameters Target parameter. Return null if the entity does not exist. EntityReference targetRef = executionContext.TargetReference; // PreImage - Provides access to the first entity image in the PreEntityImages collection. Returns null if a image does not exist. Entity preImage = executionContext.PreImage; // PreMergedTarget - Provides an entity with attributes from the TargetEntity merged into the PreImage entity. If an attribute exists in // both the TargetEntity and the PreImage, the merged target will show the attribute from the Target. var mergedTarget = executionContext.PreMergedTarget.ToEntity <Account>(); // GetRecord is a simple retrieve shortcut that accepts an EntityReference, an optional list of columns, // and/or a cache timeout value for caching the result, and returns an early-bound entity. var myRecord1 = executionContext.GetRecord <Account>(targetRef); //Get record with all columns. var myRecord2 = executionContext.GetRecord <Account>(targetRef, new string[] { "name", "accountnumber" }); //retrieve 2 columns var myRecord3 = executionContext.GetRecord <Account>(targetRef, TimeSpan.FromSeconds(10)); //retrieve and cache for 10 seconds }
/// <summary> /// Demonstrates various features associated with the Organization Service /// </summary> /// <param name="executionContext"></param> private void workingWithOrgService(ICDSPluginExecutionContext executionContext) { // OrganizationService - Provides easy access to the organization service. // This instance of the organization service runs as user or system based on // the plugin RunAs execution property. var orgService = executionContext.OrganizationService; // ElevatedOrganizationService - Provides easy access to an organization service // instance that runs under the security context of the System User regardless // of plugin RunAs execution property. var elevatedOrgService = executionContext.ElevatedOrganizationService; // FluentQuery OrganizationService extension generates more readable queries than // standard query syntax. var records = orgService.Query <Account>() .Select(cols => new { cols.Name, cols.AccountNumber }) .WhereAll(e => e .IsActive() .Attribute("name").Is <string>(ConditionOperator.BeginsWith, "C")) .OrderByAsc("name", "accountnumber") .Retrieve(); var accountId = executionContext.TargetReference; // Load a record based on its record id var lateBoundRecord = orgService.GetRecord(accountId, "accountid", "name", "accountnumber"); var earlyBoundRecord = orgService.GetRecord <Account>(accountId, cols => new { cols.Id, cols.Name, cols.AccountNumber }); }
private void doNothing(ICDSPluginExecutionContext executionContext) { // Event Tracking. executionContext.TrackEvent("Initiated Handler"); // Exception tracking handled by code. try { throw new Exception("Handled Exception"); } catch (Exception ex) { executionContext.TrackException(ex); } // Message Telemetry executionContext.Trace("A simple message - {0}", executionContext.PrimaryEntityName); executionContext.Trace(Core.eSeverityLevel.Warning, "A warning message {0}", executionContext.UserId); executionContext.Trace(Core.eSeverityLevel.Critical, "A critical message"); // Web request dependency tracking. using (var webReq = executionContext.CreateWebRequest(new Uri("http://google.com"), "myWebRequestTest")) { var data = webReq.Get(); } // randomly throw an exception var random = new Random(); if (random.Next(100) <= 10) { // Unhandled exception tracking logged by base plugin. throw new Exception("Throw Unhandled Exception"); } }
/// <summary> /// Demonstrates some of the shortcuts and features around working with entities. /// </summary> /// <param name="executionContext"></param> private void workingWithEntities(ICDSPluginExecutionContext executionContext) { // TargetEntity - Provides access to the entity in the InputParameters Target parameter if it exists. Returns null if it does not exist. Entity target = executionContext.TargetEntity; // TargetReference - Provides and entity reference for the entity in the InputParameters Target parameter. Return null if the entity does not exist. EntityReference targetRef = executionContext.TargetReference; // PreImage - Provides access to the first entity image in the PreEntityImages collection. Returns null if a image does not exist. Entity preImage = executionContext.PreImage; // PreMergedTarget - Provides an entity with attributes from the TargetEntity merged into the PreImage entity. If an attribute exists in // both the TargetEntity and the PreImage, the merged target will show the attribute from the Target. Entity mergedTarget = executionContext.PreMergedTarget; // GetRecord is a simple retrieve shortcut that accepts an EntityReference, an optional list of columns, // and/or a cache timeout value for caching the result, and returns an earlybound entity. var myRecord1 = executionContext.GetRecord <Account>(targetRef); //Get record with all columns. var myRecord2 = executionContext.GetRecord <Account>(targetRef, new string[] { "name", "accountnumber" }); //retrieve 2 columns var myRecord3 = executionContext.GetRecord <Account>(targetRef, TimeSpan.FromSeconds(10)); //retrieve and cache for 10 seconds // ContainsAny Entity extension - Checks for existence of at least one of multiple attributes. Easier to read and understand than // target.Contains("name") || target.Contains("accountnumber") especially with a large set of attributes. if (target.ContainsAny(new string[] { "name", "accountnumber" })) { executionContext.Trace("Target contains at least one matching attribute"); // short cut to tracing service Trace method. } }
public void Invoke(ICDSPluginExecutionContext executionContext) { _ = executionContext.InputParameters["Query"] ?? throw new ArgumentNullException("RetrieveMultiple is missing required Query input parameter."); if (executionContext.InputParameters["Query"] is FetchExpression) { // Convert FetchXML to query expression. var fetchExpression = executionContext.InputParameters["Query"] as FetchExpression; var conversionRequest = new FetchXmlToQueryExpressionRequest { FetchXml = fetchExpression.Query }; var conversionResponse = (FetchXmlToQueryExpressionResponse)executionContext.OrganizationService.Execute(conversionRequest); executionContext.InputParameters["Query"] = conversionResponse.Query; } var qryExpression = executionContext.InputParameters["Query"] as QueryExpression; if (Stage == ePluginStage.PostOperation) { var response = (executionContext.OutputParameters["EntityCollection"] as EntityCollection) ?? throw new ArgumentNullException("PostOp RetrieveMultiple Message is missing required EntityCollection output parameter."); PluginAction.Invoke(executionContext, qryExpression, response); executionContext.OutputParameters["EntityColection"] = response; } else { PluginAction.Invoke(executionContext, qryExpression, null); } }
private void createPreOpTest(ICDSPluginExecutionContext executionContext, TestProxy.Account target, EntityReference response) { Assert.AreEqual(Ids.Account, target.Id); Assert.IsNull(response); //alter the target to see if it get saved to the input parameters collection. target.AccountNumber = "1"; }
private void createPostOpTest(ICDSPluginExecutionContext executionContext, TestProxy.Account target, EntityReference response) { Assert.AreEqual(Ids.Account, target.Id); Assert.AreEqual(default(Guid), response.Id); //alter the response to see if it gets saved to the outputs collection. response.Id = Guid.NewGuid(); }
private void PrepareForRetrieveDecryption(ICDSPluginExecutionContext executionContext, EntityReference target, ColumnSet columnSet, Entity retrievedRecord) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, target.LogicalName)) { encryptionService.PrepareForDecryption(ref columnSet); } }
private void LogEncryptedSearchHits(ICDSPluginExecutionContext executionContext, QueryExpression query, EntityCollection retrievedRecords) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, query.EntityName)) { encryptionService.LogEncryptedSearchHits(retrievedRecords); } }
private void EncryptedSearchHandler(ICDSPluginExecutionContext executionContext, QueryExpression query, EntityCollection entityCollection) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, query.EntityName)) { encryptionService.GenerateEncryptedFieldQuery(ref query); } }
private void EncryptOnUpdateHandler(ICDSPluginExecutionContext executionContext, Entity target) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, target.LogicalName)) { encryptionService.EncryptFields(ref target); } }
private void PostQueryDecryption(ICDSPluginExecutionContext executionContext, QueryExpression query, EntityCollection entityCollection) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, entityCollection.EntityName)) { encryptionService.DecryptFields(ref entityCollection); } }
internal EncryptedFieldService(ICDSPluginExecutionContext executionContext, string recordType, IServiceConfiguration configuration, IEncryptionServiceFactory encryptionServiceFactory, IUserRoleEvaluator roleEvaluator, IEncryptedFieldAccessLoggerFactory accessLoggerFactory) { this.ExecutionContext = executionContext ?? throw new ArgumentNullException("executionContext"); this.RecordType = recordType ?? throw new ArgumentNullException("recordType"); this.Configuration = configuration ?? throw new ArgumentNullException("configuration"); this.EncryptionServiceFactory = encryptionServiceFactory ?? throw new ArgumentNullException("encryptionServiceFactory"); this.RoleEvaluator = roleEvaluator ?? throw new ArgumentNullException("roleEvaluator"); this.AccessLoggerFactory = accessLoggerFactory; }
private void PrepareForQueryDecryption(ICDSPluginExecutionContext executionContext, QueryExpression query, EntityCollection entityCollection) { var factory = Container.Resolve <IEncryptedFieldServiceFactory>(); using (var encryptionService = factory.Create(executionContext, query.EntityName)) { var columnSet = query.ColumnSet; encryptionService.PrepareForDecryption(ref columnSet); } }
/// <summary> /// Demonstrates a simple GET operation using built in web request support. Will automatically /// generate dependency telemetry. /// </summary> /// <param name="executionContext"></param> private void demonstrateWebRequest(ICDSPluginExecutionContext executionContext) { Uri googleUri = new Uri("https://www.google.com"); using (var webRequest = executionContext.CreateWebRequest(googleUri)) { var result = webRequest.Get(); executionContext.Trace("Returned {0} characters", result.Content.Length); } }
public void Invoke(ICDSPluginExecutionContext executionContext) { var target = (EntityReference)executionContext.InputParameters["Target"]; var columnSet = (ColumnSet)executionContext.InputParameters["ColumnSet"]; if (Stage == ePluginStage.PostOperation) { var response = ((Entity)(executionContext.OutputParameters["Entity"])).ToEntity <E>(); PluginAction.Invoke(executionContext, target, columnSet, response); executionContext.OutputParameters["Entity"] = response; } else { PluginAction.Invoke(executionContext, target, columnSet, null); } }
/// <summary> /// Prior to a new process step record creation, set the step parameter value to the template value /// defined on the associated step type if the value is currently blank. /// </summary> /// <param name="executionContext"></param> /// <param name="target"></param> /// <param name="createdProcessStepId"></param> private void addStepParameterTemplate( ICDSPluginExecutionContext executionContext, ccllc_processstep target, EntityReference createdProcessStepId) { if (target.ccllc_StepParameters == null && target.ccllc_ProcessStepTypeId != null) { var stepType = executionContext.OrganizationService .GetRecord <ccllc_processsteptype>(target.ccllc_ProcessStepTypeId, cols => new { cols.Id, cols.ccllc_StepParameterTemplate }); if (stepType.ccllc_StepParameterTemplate != null) { target.ccllc_StepParameters = stepType.ccllc_StepParameterTemplate; } } }
/// <summary> /// Prior to a new transaction type record creation, set the data record configuration parameter /// to a template guide value if it is blank. /// </summary> /// <param name="executionContext"></param> /// <param name="target"></param> /// <param name="createdTransactionTypeId"></param> private void addDataRecordParameterTemplate( ICDSPluginExecutionContext executionContext, ccllc_transactiontype target, EntityReference createdTransactionTypeId) { if (target.ccllc_DataRecordConfiguration is null) { target.ccllc_DataRecordConfiguration = "{" + Environment.NewLine + "\"RecordType\":\"new_entitylogicalname\"," + Environment.NewLine + "\"NameField\":\"new_name\"," + Environment.NewLine + "\"TransactionField\":\"new_transactionid\"," + Environment.NewLine + "\"CustomerField\":\"new_customerid\"" + Environment.NewLine + "}"; } }
/// <summary> /// After a new transaction process is created, check the startup process value on the parent transaction type record /// and set it to this newly created transaction process if the value is currently blank. /// </summary> /// <param name="executionContext"></param> /// <param name="target"></param> /// <param name="createdProcessId"></param> private void setTransactionTypeStartupProcessIfBlank( ICDSPluginExecutionContext executionContext, ccllc_transactionprocess target, EntityReference createdProcessId) { if (target.ccllc_TransactionTypeId != null) { var transactionType = executionContext.OrganizationService .GetRecord <ccllc_transactiontype>(target.ccllc_TransactionTypeId, cols => new { cols.Id, cols.ccllc_StartupProcessId }); if (transactionType.ccllc_StartupProcessId is null) { transactionType.ccllc_StartupProcessId = createdProcessId ?? throw new ArgumentNullException("createdProcessId is null"); executionContext.OrganizationService.Update(transactionType); } } }
public void Invoke(ICDSPluginExecutionContext executionContext) { E target = executionContext.TargetEntity.ToEntity <E>(); if (Stage == ePluginStage.PostOperation) { var response = new EntityReference(this.EntityName, (Guid)executionContext.OutputParameters["id"]); PluginAction.Invoke(executionContext, target, response); executionContext.OutputParameters["id"] = response?.Id; } else { PluginAction.Invoke(executionContext, target, null); } }
/// <summary> /// Telemetry Sink that gathers and transmits telemetry. /// </summary> /// <param name="cdsExecutionContext"></param> /// <returns></returns> public virtual bool ConfigureTelemetrySink(ICDSPluginExecutionContext cdsExecutionContext) { if (cdsExecutionContext != null) { var key = cdsExecutionContext.Settings.GetValue <string>("Telemetry.InstrumentationKey", this.DefaultInstrumentationKey); if (!string.IsNullOrEmpty(key)) { TelemetrySink.ProcessChain.TelemetryProcessors.Add(new SequencePropertyProcessor()); TelemetrySink.ProcessChain.TelemetryProcessors.Add(new InstrumentationKeyPropertyProcessor(key)); return(true); //telemetry sink is configured. } } return(false); //telemetry sink is not configured. }
internal void CanNavigateForwardHandler(ICDSPluginExecutionContext executionContext) { var req = executionContext.CreateOrganizationRequest <ccllc_BTF_CanNavigateForwardRequest>(); EntityReference transactionId = req.Target ?? throw new NullReferenceException("Target cannot be null"); EntityReference userId = req.UserId ?? new EntityReference("systemuser", executionContext.InitiatingUserId); var systemUser = new SystemUser(userId.LogicalName, userId.Id, userId.Name); var platformService = Container.Resolve <IPlatformService>(); var session = platformService.GenerateSession(executionContext, systemUser); var managerFactory = Container.Resolve <ITransactionServiceFactory>(); var manager = managerFactory.CreateTransactionService(executionContext); var transaction = manager.LoadTransaction(executionContext, transactionId.ToRecordPointer()); bool canNavigate = transaction.CanNavigateForward(session); executionContext.OutputParameters["IsAllowed"] = canNavigate; }
public void Invoke(ICDSPluginExecutionContext executionContext) { var request = new TRequest() { Parameters = executionContext.InputParameters }; if (Stage == ePluginStage.PostOperation) { var response = new TResponse() { Results = executionContext.OutputParameters }; PluginAction.Invoke(executionContext, request, response); } else { PluginAction.Invoke(executionContext, request, null); } }
internal void NavigateBackwardHandler(ICDSPluginExecutionContext executionContext) { var req = executionContext.CreateOrganizationRequest <ccllc_BTF_NavigateBackwardRequest>(); EntityReference transactionId = req.Target ?? throw new NullReferenceException("Target cannot be null"); EntityReference userId = req.UserId ?? new EntityReference("systemuser", executionContext.InitiatingUserId); var systemUser = new SystemUser(userId.LogicalName, userId.Id, userId.Name); var platformService = Container.Resolve <IPlatformService>(); var session = platformService.GenerateSession(executionContext, systemUser); var managerFactory = Container.Resolve <ITransactionServiceFactory>(); var manager = managerFactory.CreateTransactionService(executionContext); var transaction = manager.LoadTransaction(executionContext, transactionId.ToRecordPointer()); IUIPointer uiPointer = null; var step = transaction.NavigateBackward(session); if (step.Type.IsUIStep) { uiPointer = step.GetUIPointer(executionContext, transaction); } if (uiPointer == null) { // At this point something is wrong so navigate the user to the transaction error form. uiPointer = new UIPointer { UIDefinition = "TransactionError", UIRecordId = transaction.Id, UIRecordType = "ccllc_transaction", UIType = eUIStepTypeEnum.DataForm }; } executionContext.OutputParameters["UIPointer"] = uiPointer.Serialize(); }
internal void GetAvailableTransactionTypeHandler(ICDSPluginExecutionContext executionContext) { var req = executionContext.CreateOrganizationRequest <ccllc_BTF_GetAvailableTransactionTypesRequest>(); if (string.IsNullOrEmpty(req.ContextRecordType)) { throw new ArgumentNullException("ContextRecordType cannot be null."); } if (string.IsNullOrEmpty(req.ContextRecordId)) { throw new ArgumentNullException("ContextRecordId cannot be null."); } if (!Guid.TryParse(req.ContextRecordId, out Guid recordId)) { throw new ArgumentException("ContextRecordId cannot be converted to a GUID."); } var contextRecordId = new RecordPointer <Guid>(req.ContextRecordType, recordId); var userId = req.UserId ?? new EntityReference("systemuser", executionContext.InitiatingUserId); var systemUser = new SystemUser(userId.LogicalName, userId.Id, userId.Name); var platformManager = Container.Resolve <IPlatformService>(); var session = platformManager.GenerateSession(executionContext, systemUser); var contextFactory = Container.Resolve <ITransactionContextFactory>(); var transactionContext = contextFactory.CreateTransactionContext(executionContext, contextRecordId); var serviceFactory = Container.Resolve <ITransactionServiceFactory>(); var service = serviceFactory.CreateTransactionService(executionContext); var available = service.GetAvaialbleTransactionTypes(executionContext, session, transactionContext); executionContext.OutputParameters["TransactionTypes"] = available.Serialize(); }
/// <summary> /// After creation of a new process step, link it up to the current last step in the process so that the /// new step becomes the last step in the process. /// </summary> /// <param name="executionContext"></param> /// <param name="target"></param> /// <param name="createdProcessStepId"></param> private void addAsLastProcessStep( ICDSPluginExecutionContext executionContext, ccllc_processstep target, EntityReference createdProcessStepId) { if (target.ccllc_TransactionProcessId != null) { var process = executionContext.OrganizationService .GetRecord <ccllc_transactionprocess>(target.ccllc_TransactionProcessId, cols => new { cols.Id, cols.ccllc_InitialProcessStepId }); // set the process initial step to this step if it is currently null. if (process.ccllc_InitialProcessStepId is null) { process.ccllc_InitialProcessStepId = createdProcessStepId; executionContext.OrganizationService.Update(process); } // find last step that has a blank subsequent step id that is not the newly created step. var lastStep = executionContext.OrganizationService.Query <ccllc_processstep>() .Select(cols => new { cols.Id, cols.ccllc_SubsequentStepId }) .WhereAll(s => s .IsActive() .Attribute("ccllc_transactionprocessid").IsEqualTo(process.Id) .Attribute("ccllc_subsequentstepid").IsNull() .Attribute("ccllc_processstepid").Is(Microsoft.Xrm.Sdk.Query.ConditionOperator.NotEqual, createdProcessStepId.Id)) .OrderByDesc("createdon") .FirstOrDefault(); // Set the subsequent step on the last step to the newly created step. if (lastStep != null) { lastStep.ccllc_SubsequentStepId = createdProcessStepId; executionContext.OrganizationService.Update(lastStep); } } }
/// <summary> /// Demonstrates basic tracing and tracking methods built into the execution context. /// </summary> /// <param name="executionContext"></param> private void demonstrateTelemetry(ICDSPluginExecutionContext executionContext) { // Information message written to the standard tracing service and also to ApplicationInsights. executionContext.Trace("The primary entity type is '{0}'", executionContext.PrimaryEntityName); // Waring message written to the standard tracing service and also to ApplicationInsights. executionContext.Trace(eSeverityLevel.Warning, "A warning message for record '{0}'", executionContext.PrimaryEntityId); // Create an Event marker in ApplicationInsights executionContext.TrackEvent("Event_1"); // Capture exception information for a handled exception in ApplicationInsights // Note that capturing exception telemetry for unhandled exceptions is taken care of // in the InstrumentedCDSPlugin abstract class. try { throw new Exception("Sample exception"); } catch (Exception ex) { executionContext.TrackException(ex); // do something to handle exception } }
public void Invoke(ICDSPluginExecutionContext executionContext) { var target = executionContext.TargetReference; PluginAction.Invoke(executionContext, target); }
internal void InitiateTransactionHandler(ICDSPluginExecutionContext executionContext) { var req = (executionContext.CreateOrganizationRequest <ccllc_BTF_InitiateTransactionRequest>()); if (string.IsNullOrEmpty(req.ContextRecordType)) { throw new ArgumentNullException("ContextRecordType cannot be null."); } if (string.IsNullOrEmpty(req.ContextRecordId)) { throw new ArgumentNullException("ContextRecordId cannot be null."); } if (!Guid.TryParse(req.ContextRecordId, out Guid recordId)) { throw new ArgumentException("ContextRecordId cannot be converted to a GUID."); } var contextRecordId = new RecordPointer <Guid>(req.ContextRecordType, recordId); var transactionTypeId = req.TransactionTypeId ?? throw new NullReferenceException("TransactionTypeId cannot be null"); var userId = req.UserId ?? new EntityReference("systemuser", executionContext.InitiatingUserId); var systemUser = new SystemUser(userId.LogicalName, userId.Id, userId.Name); var platformService = Container.Resolve <IPlatformService>(); var session = platformService.GenerateSession(executionContext, systemUser); var contextFactory = Container.Resolve <ITransactionContextFactory>(); var transactionContext = contextFactory.CreateTransactionContext(executionContext, contextRecordId); var serviceFactory = Container.Resolve <ITransactionServiceFactory>(); var service = serviceFactory.CreateTransactionService(executionContext); var transactionType = service.GetAvaialbleTransactionTypes(executionContext, session, transactionContext).Where(r => r.Id == transactionTypeId.Id).FirstOrDefault(); if (transactionType == null) { throw TransactionException.BuildException(TransactionException.ErrorCode.TransactionTypeNotFound); } var transaction = service.NewTransaction(executionContext, session, transactionContext, transactionType); IUIPointer uiPointer = null; if (transaction.CurrentStep.Type.IsUIStep) { uiPointer = transaction.CurrentStep.GetUIPointer(executionContext, transaction); } if (uiPointer == null) { // When current step is not a UI step, navigate the process forward which will execute process steps // until a UI step is found or the process is blocked by a validation issue. var step = transaction.NavigateForward(session); if (step.Type.IsUIStep) { uiPointer = step.GetUIPointer(executionContext, transaction); } } if (uiPointer == null) { // At this point something is wrong so navigate the user to the transaction error form. uiPointer = new UIPointer { UIDefinition = "TransactionError", UIRecordId = transaction.Id, UIRecordType = "ccllc_transaction", UIType = eUIStepTypeEnum.DataForm }; } executionContext.Trace("Adding UI Pointer to output parameters."); executionContext.OutputParameters["UIPointer"] = uiPointer.Serialize(); }