Exemplo n.º 1
0
        /// <summary>
        ///     Executes the plug-in.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <remarks>
        ///     For improved performance, Microsoft Dynamics CRM caches plug-in instances.
        ///     The plug-in's Execute method should be written to be stateless as the constructor
        ///     is not called for every invocation of the plug-in. Also, multiple system threads
        ///     could execute the plug-in at the same time. All per invocation state information
        ///     is stored in the context. This means that you should not use global variables in plug-ins.
        /// </remarks>
        public void Execute(IServiceProvider serviceProvider)
        {
            var sw = new Stopwatch();

            if (serviceProvider == null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }

            // Construct the Local plug-in context.
            var localContext = new LocalPluginContext(serviceProvider);

            localContext.Log($"Entity: {localContext.PrimaryEntityName}, Message: {localContext.MessageName}, Stage: {Enum.ToObject(typeof(Stages), localContext.Stage)}, Mode: {localContext.Mode}");

            localContext.Log($"\r\nClass {ChildClassName}");
            localContext.Log($"\r\nUserId\t\t\t\t{localContext.UserId}\r\nInitiatingUserId\t{localContext.InitiatingUserId}");
            localContext.Log($"\r\nStart : {DateTime.Now:dd/MM/yyyy HH:mm:ss.fff}");
            sw.Restart();


            try
            {
                if (SendToRemoteDebugger(localContext))
                {
                    return;
                }

                IEnumerable <Step> steps;

                if (_isCustomApi)
                {
                    steps = new List <Step>
                    {
                        new Step(this, localContext.MessageName, Stages.PostOperation, Modes.Synchronous, _customApiEntityName, _customApiMethodName)
                    };
                }
                else
                {
                    steps =
                        (from a in _newRegisteredEvents
                         where (
                             localContext.IsStage(a.Stage) &&
                             localContext.IsMessage(a.Message) &&
                             localContext.Mode == a.Mode &&
                             (string.IsNullOrWhiteSpace(a.EntityName) ||
                              a.EntityName == localContext.PrimaryEntityName)
                             )
                         select a);
                }

                var stage = Enum.ToObject(typeof(Stages), localContext.Stage);
                sw.Restart();
                localContext.Log("------------------ Input Variables (before) ------------------");
                localContext.DumpInputParameters();
                localContext.Log("\r\n------------------ Shared Variables (before) ------------------");
                localContext.DumpSharedVariables();
                localContext.Log("\r\n---------------------------------------------------------------");

                foreach (var step in steps)
                {
                    sw.Restart();
                    if (step.Message == Messages.Update && step.FilteringAttributes.Any())
                    {
                        var target = localContext.GetInputParameter <Entity>(InputParameters.Target);

                        var useStep = false;

                        foreach (var attributeName in target.Attributes.Select(a => a.Key))
                        {
                            useStep |= step.FilteringAttributes.Contains(attributeName);
                        }

                        if (!useStep)
                        {
                            localContext.Log(
                                "\r\n{0}.{5} is not fired because filteringAttributes filter is not met.",
                                ChildClassName,
                                localContext.PrimaryEntityName,
                                localContext.MessageName,
                                stage,
                                localContext.Mode, step.Method.Name);
                            continue;
                        }
                    }

                    var entityAction = step.Method;

                    localContext.Log($"\r\n\r\n{ChildClassName}.{step.Method.Name} is firing");

                    sw.Restart();

                    localContext.Log($"{ChildClassName}.{step.Method.Name} Start");

                    localContext.InvokeMethod(this, entityAction);

                    localContext.Log($"{ChildClassName}.{step.Method.Name} End, duration : {sw.Elapsed}");
                }

                if (localContext.IsStage(Stages.PreValidation) || localContext.IsStage(Stages.PreOperation))
                {
                    localContext.Log("\r\n\r\n------------------ Input Variables (after) ------------------");
                    localContext.DumpInputParameters();
                    localContext.Log("\r\n------------------ Shared Variables (after) ------------------");
                    localContext.DumpSharedVariables();
                    localContext.Log("\r\n---------------------------------------------------------------");
                }
            }
            catch (FaultException <OrganizationServiceFault> e)
            {
                localContext.Log($"Exception: {e}");

                // Handle the exception.
                throw;
            }
            catch (TargetInvocationException e)
            {
                localContext.Log($"Exception : {e.InnerException}");

                if (e.InnerException != null)
                {
                    if (e.InnerException is InvalidPluginExecutionException invalidPluginExecutionException)
                    {
                        throw invalidPluginExecutionException;
                    }
                    else
                    {
                        throw new InvalidPluginExecutionException(e.InnerException.Message);
                    }
                }
            }
            catch (JsonException e)
            {
                throw new InvalidPluginExecutionException(e.ToString());
            }
            finally
            {
                localContext.Log($"Exiting {ChildClassName}.Execute()");

                localContext.Log($"End : {DateTime.Now:dd/MM/yyyy HH:mm:ss.fff}\r\n");
            }
        }
Exemplo n.º 2
0
        private bool SendToRemoteDebugger(LocalPluginContext localContext)
        {
            if (!localContext.IsDebugContext)
            {
                localContext.Log("The context is genuine");
                localContext.Log($"UnSecuredConfig : {UnSecuredConfig}");

                //if (!string.IsNullOrEmpty(UnSecuredConfig) && UnSecuredConfig.Contains("debugSessions"))
                //{
                //    var debuggerUnsecuredConfig = JsonConvert.DeserializeObject<DebuggerUnsecureConfig>(UnSecuredConfig);

                //    localContext.Log($"Debug session ids : {string.Join(",", debuggerUnsecuredConfig.DebugSessionIds)}");

                var initiatingUserId = localContext.GetInitiatingUserId();

                localContext.Log($"Initiating user Id : {initiatingUserId}");

                var queryDebugSessions = BindingModelHelper.GetRetrieveAllQuery <DebugSession>();
                queryDebugSessions.Criteria.AddCondition(DebugSessionDefinition.Columns.DebugeeId, ConditionOperator.Equal, initiatingUserId);
                queryDebugSessions.Criteria.AddCondition(DebugSessionDefinition.Columns.StateCode, ConditionOperator.Equal, DebugSessionState.Active.ToInt());

                //queryDebugSessions.Criteria.AddCondition(DebugSessionDefinition.Columns.Id, ConditionOperator.In, debuggerUnsecuredConfig.DebugSessionIds.Cast<object>().ToArray());

                var debugSession = localContext.AdminOrganizationService.RetrieveAll <DebugSession>(queryDebugSessions).FirstOrDefault();

                localContext.Log($"Debug session : {debugSession}");

                if (debugSession != null)
                {
                    if (debugSession.SessionEnd >= DateTime.Today)
                    {
                        var remoteContext = localContext.RemoteContext;
                        remoteContext.Id = Guid.NewGuid();
                        remoteContext.TypeAssemblyQualifiedName = GetType().AssemblyQualifiedName;
                        remoteContext.UnsecureConfig            = UnSecuredConfig;
                        remoteContext.SecureConfig = SecuredConfig;

                        var uri = new Uri($"{debugSession.RelayUrl}/{debugSession.HybridConnectionName}");

                        try
                        {
                            using var hybridConnection = new HybridConnection(debugSession.SasKeyName, debugSession.SasConnectionKey, uri.AbsoluteUri);
                            var message = new RemoteDebuggerMessage(RemoteDebuggerMessageType.Context, remoteContext, remoteContext.Id);

                            RemoteDebuggerMessage response;
                            while (true)
                            {
                                localContext.Log("Sending context to local machine : {0}", message);

                                response = hybridConnection.SendMessage(message).GetAwaiter().GetResult();

                                localContext.Log("Received response : {0}", response);

                                if (response.MessageType == RemoteDebuggerMessageType.Context || response.MessageType == RemoteDebuggerMessageType.Exception)
                                {
                                    break;
                                }

                                var request = response.GetOrganizationRequest();

                                var service = response.UserId.HasValue ? localContext.GetService(response.UserId.Value) : localContext.AdminOrganizationService;

                                var organizationResponse = service.Execute(request);

                                message = new RemoteDebuggerMessage(RemoteDebuggerMessageType.Response, organizationResponse, remoteContext.Id);
                            }

                            if (response.MessageType == RemoteDebuggerMessageType.Exception)
                            {
                                throw response.GetException();
                            }

                            var updatedContext = response.GetContext <RemoteDebugExecutionContext>();

                            localContext.UpdateContext(updatedContext);


                            return(true);
                        }
                        catch (HttpRequestException)
                        {
                            // Run the plugin as deploy if the remote debugger is not connected
                        }
                    }
                }
                //}
            }

            return(false);
        }