public void SendFault(Exception exception, IDictionary <string, string> outgoingContextProperties)
        {
            if (exception == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exception");
            }

            if (!(exception is FaultException)) //Wrap the exception if it is not FaultException.
            {
                exception = WorkflowOperationErrorHandler.CreateUnhandledException(exception);
            }

            WorkflowOperationAsyncResult asyncResult = this.GetAsyncResult();

            asyncResult.SendFault(exception, outgoingContextProperties);
            this.SetOperationCompleted();

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                string traceText = SR.GetString(SR.TraceCodeWorkflowRequestContextFaultSent, asyncResult.InstanceId);
                TraceUtility.TraceEvent(TraceEventType.Information,
                                        TraceCode.WorkflowRequestContextFaultSent, traceText,
                                        new StringTraceRecord("Details", traceText),
                                        this,
                                        exception);
            }
        }
Esempio n. 2
0
        void OnWorkflowActivationCompleted(object state)
        {
            WorkflowActivationCompletedCallbackState callbackState = (WorkflowActivationCompletedCallbackState)state;

            lock (callbackState.InstanceContext.ThisLock)
            {
                if (base.Cache.Contains(callbackState.InstanceId, callbackState.InstanceContext))
                {
                    WorkflowDurableInstance durableInstance = callbackState.InstanceContext.Extensions.Find <WorkflowDurableInstance>();
                    if (durableInstance != null &&
                        durableInstance.CurrentOperationInvocation != null &&
                        durableInstance.CurrentOperationInvocation.HasWorkflowRequestContextBeenSerialized &&
                        !durableInstance.CurrentOperationInvocation.IsCompleted)
                    {
                        // If we are here, it means the workflow instance completed, terminated, or otherwise unloaded without
                        // completing the current operation invocation. In such case, we want to make the best effort to let
                        // service model to consider this operation invocation failed.
                        try
                        {
                            durableInstance.CurrentOperationInvocation.SendFault(
                                WorkflowOperationErrorHandler.CreateUnhandledException(
                                    new InvalidOperationException(SR2.GetString(SR2.WorkflowServiceUnloadedWithoutSendingResponse))),
                                null);
                        }
                        catch (Exception e)
                        {
                            if (Fx.IsFatal(e))
                            {
                                throw;
                            }
                        }
                    }

                    IChannel[] incomingChannels = new IChannel[callbackState.InstanceContext.IncomingChannels.Count];
                    callbackState.InstanceContext.IncomingChannels.CopyTo(incomingChannels, 0);

                    if (callbackState.InstanceContext.IncomingChannels.Count != 0)
                    {
                        foreach (IChannel channel in incomingChannels)
                        {
                            callbackState.InstanceContext.IncomingChannels.Remove(channel);
                        }
                    }
                    else
                    {
                        //Call notify only when IncomingChannels Collection is empty.
                        if (callbackState.InstanceContextIdleCallback != null)
                        {
                            callbackState.InstanceContextIdleCallback(callbackState.InstanceContext);
                        }
                    }
                }
            }
        }
        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            if (description == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");
            }

            if (serviceHostBase == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceHostBase");
            }
            if (description.Behaviors == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("description", SR2.GetString(SR2.NoBehaviors));
            }
            if (description.Endpoints == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("description", SR2.GetString(SR2.NoEndpoints));
            }

            bool syncContextRegistered = false;
            WorkflowRuntimeBehavior workflowRuntimeBehavior = description.Behaviors.Find<WorkflowRuntimeBehavior>();

            if (workflowRuntimeBehavior == null)
            {
                workflowRuntimeBehavior = new WorkflowRuntimeBehavior();
                description.Behaviors.Add(workflowRuntimeBehavior);
            }

            WorkflowPersistenceService persistenceService = workflowRuntimeBehavior.WorkflowRuntime.GetService<WorkflowPersistenceService>();
            if (persistenceService != null)
            {
                bool wasRuntimeStarted = workflowRuntimeBehavior.WorkflowRuntime.IsStarted;
                if (wasRuntimeStarted)
                {
                    workflowRuntimeBehavior.WorkflowRuntime.StopRuntime();
                }
                workflowRuntimeBehavior.WorkflowRuntime.RemoveService(persistenceService);
                workflowRuntimeBehavior.WorkflowRuntime.AddService(new SkipUnloadOnFirstIdleWorkflowPersistenceService(persistenceService));
                if (wasRuntimeStarted)
                {
                    workflowRuntimeBehavior.WorkflowRuntime.StartRuntime();
                }
            }

            this.workflowDefinitionContext.Register(workflowRuntimeBehavior.WorkflowRuntime, workflowRuntimeBehavior.ValidateOnCreate);

            WorkflowInstanceContextProvider instanceContextProvider = new WorkflowInstanceContextProvider(
                serviceHostBase,
                false,
                this.workflowDefinitionContext
                );

            WorkflowInstanceContextProvider singleCallInstanceContextProvider = null;

            IInstanceProvider instanceProvider = new WorkflowInstanceProvider(instanceContextProvider);
            ServiceDebugBehavior serviceDebugBehavior = description.Behaviors.Find<ServiceDebugBehavior>();

            bool includeExceptionDetailsInFaults = this.IncludeExceptionDetailInFaults;
            if (serviceDebugBehavior != null)
            {
                includeExceptionDetailsInFaults |= serviceDebugBehavior.IncludeExceptionDetailInFaults;
            }

            IErrorHandler workflowOperationErrorHandler = new WorkflowOperationErrorHandler(includeExceptionDetailsInFaults);

            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;

                if (channelDispatcher != null && channelDispatcher.HasApplicationEndpoints())
                {
                    channelDispatcher.IncludeExceptionDetailInFaults = includeExceptionDetailsInFaults;
                    channelDispatcher.ErrorHandlers.Add(workflowOperationErrorHandler);
                    foreach (EndpointDispatcher endPointDispatcher in channelDispatcher.Endpoints)
                    {
                        if (endPointDispatcher.IsSystemEndpoint)
                        {
                            continue;
                        }

                        ServiceEndpoint serviceEndPoint = description.Endpoints.Find(new XmlQualifiedName(endPointDispatcher.ContractName, endPointDispatcher.ContractNamespace));

                        if (serviceEndPoint != null)
                        {

                            DispatchRuntime dispatchRuntime = endPointDispatcher.DispatchRuntime;

                            dispatchRuntime.AutomaticInputSessionShutdown = true;
                            dispatchRuntime.ConcurrencyMode = ConcurrencyMode.Single;
                            dispatchRuntime.ValidateMustUnderstand = this.ValidateMustUnderstand;

                            if (!this.UseSynchronizationContext)
                            {
                                dispatchRuntime.SynchronizationContext = null;
                            }
                            else if (!syncContextRegistered)
                            {
                                SynchronizationContextWorkflowSchedulerService syncSchedulerService = workflowRuntimeBehavior.WorkflowRuntime.GetService<SynchronizationContextWorkflowSchedulerService>();
                                Fx.Assert(syncSchedulerService != null, "Wrong Synchronization Context Set");
                                syncSchedulerService.SetSynchronizationContext(dispatchRuntime.SynchronizationContext);
                                syncContextRegistered = true;
                            }

                            if (!endPointDispatcher.AddressFilterSetExplicit)
                            {
                                EndpointAddress endPointAddress = endPointDispatcher.OriginalAddress;
                                if ((endPointAddress == null) || (this.AddressFilterMode == AddressFilterMode.Any))
                                {
                                    endPointDispatcher.AddressFilter = new MatchAllMessageFilter();
                                }
                                else if (this.AddressFilterMode == AddressFilterMode.Prefix)
                                {
                                    endPointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(endPointAddress);
                                }
                                else if (this.AddressFilterMode == AddressFilterMode.Exact)
                                {
                                    endPointDispatcher.AddressFilter = new EndpointAddressMessageFilter(endPointAddress);
                                }
                            }

                            if (serviceEndPoint.Contract.SessionMode != SessionMode.NotAllowed)
                            {
                                endPointDispatcher.DispatchRuntime.InstanceContextProvider = instanceContextProvider;
                            }
                            else
                            {
                                if (singleCallInstanceContextProvider == null)
                                {
                                    singleCallInstanceContextProvider = new WorkflowInstanceContextProvider(
                                        serviceHostBase,
                                        true,
                                        this.workflowDefinitionContext);
                                }
                                endPointDispatcher.DispatchRuntime.InstanceContextProvider = singleCallInstanceContextProvider;
                            }
                            endPointDispatcher.DispatchRuntime.MessageInspectors.Add(new DurableMessageDispatchInspector(serviceEndPoint.Contract.SessionMode));
                            endPointDispatcher.DispatchRuntime.InstanceProvider = instanceProvider;
                            SetContractFilterToIncludeAllOperations(endPointDispatcher, serviceEndPoint.Contract);
                        }
                    }
                }
            }
            DataContractSerializerServiceBehavior.ApplySerializationSettings(description, this.ignoreExtensionDataObject, this.maxItemsInObjectGraph);
        }