Beispiel #1
0
        //=============================================================================================
        //[SuppressMessage(FxCop.Category.Security, FxCop.Rule.AptcaMethodsShouldOnlyCallAptcaMethods, Justification = "We call PartialTrustHelpers.DemandForFullTrust().")]
        CoordinationService GetCoordinationService()
        {
            if (this.coordinationService == null)
            {
                lock (this.proxyLock)
                {
                    if (this.coordinationService == null)
                    {
                        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

                        /*
                         * // We demand full trust because CoordinationService is defined in a non-APTCA assembly and can call Environment.FailFast.
                         * // It's recommended to not let partially trusted callers to bring down the process.
                         * System.Runtime.PartialTrustHelpers.DemandForFullTrust();
                         */

                        try
                        {
                            CoordinationServiceConfiguration config = new CoordinationServiceConfiguration();
                            config.Mode = CoordinationServiceMode.Formatter;
                            config.RemoteClientsEnabled = this.wsatConfig.RemoteActivationService(this.protocolVersion) != null;
                            this.coordinationService    = new CoordinationService(config, this.protocolVersion);
                        }
                        catch (MessagingInitializationException e)
                        {
                            DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                      new TransactionException(SR.GetString(SR.WsatMessagingInitializationFailed), e));
                        }
                    }
                }
            }

            return(this.coordinationService);
        }
Beispiel #2
0
        static byte[] CreateFixedPropagationToken()
        {
            if (fixedPropagationToken == null)
            {
                CommittableTransaction tx = new CommittableTransaction();
                byte[] token = TransactionInterop.GetTransmitterPropagationToken(tx);

                // Don't abort the transaction. People notice this and do not like it.
                try
                {
                    tx.Commit();
                }
                catch (TransactionException e)
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                }

                Interlocked.CompareExchange <byte[]>(ref fixedPropagationToken, token, null);
            }

            byte[] tokenCopy = new byte[fixedPropagationToken.Length];
            Array.Copy(fixedPropagationToken, tokenCopy, fixedPropagationToken.Length);

            return(tokenCopy);
        }
Beispiel #3
0
        //=============================================================================================
        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

        /*
         * // We demand full trust because we call ActivationProxy.Release(), which is defined in a non-APTCA assembly and can do Environment.FailFast.
         * // It's recommended to not let partially trusted callers to bring down the process.
         * // WSATs are not supported in partial trust, so customers should not be broken by this demand.
         * [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
         */
        void RefreshActivationProxy(EndpointAddress suggestedAddress)
        {
            // Pick an address in the following order...
            EndpointAddress address = suggestedAddress;

            if (address == null)
            {
                address = this.wsatConfig.LocalActivationService(this.protocolVersion);

                if (address == null)
                {
                    address = this.wsatConfig.RemoteActivationService(this.protocolVersion);
                }
            }

            if (!(address != null))
            {
                // tx processing requires failfast when state is inconsistent
                DiagnosticUtility.FailFast("Must have valid activation service address");
            }

            lock (this.proxyLock)
            {
                ActivationProxy newProxy = CreateActivationProxy(address);
                if (this.activationProxy != null)
                {
                    this.activationProxy.Release();
                }
                this.activationProxy = newProxy;
            }
        }
Beispiel #4
0
        //=============================================================================================
        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

        /*
         * // We demand full trust because we use CreateCoordinationContext from a non-APTCA assembly and the CreateCoordinationContext constructor does an Environment.FailFast
         * // if the argument is invalid. It's recommended to not let partially trusted callers to bring down the process.
         * // WSATs are not supported in partial trust, so customers should not be broken by this demand.
         * [PermissionSet(SecurityAction.Demand, Unrestricted = true)]
         */
        CoordinationContext CreateCoordinationContext(WsatTransactionInfo info)
        {
            CreateCoordinationContext cccMessage = new CreateCoordinationContext(this.protocolVersion);

            cccMessage.CurrentContext = info.Context;
            cccMessage.IssuedToken    = info.IssuedToken;

            try
            {
                // This was necessary during some portions of WCF 1.0 development
                // It is probably not needed now. However, it seems conceptually
                // solid to separate this operation from the incoming app message as
                // much as possible.  There have also been enough ServiceModel bugs in
                // this area that it does not seem wise to remove this at the moment
                // (2006/3/30, WCF 1.0 RC1 milestone)
                using (new OperationContextScope((OperationContext)null))
                {
                    return(Enlist(ref cccMessage).CoordinationContext);
                }
            }
            catch (WsatFaultException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new TransactionException(SR.GetString(SR.UnmarshalTransactionFaulted, e.Message), e));
            }
            catch (WsatSendFailureException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new TransactionManagerCommunicationException(SR.GetString(SR.TMCommunicationError), e));
            }
        }
Beispiel #5
0
 //=============================================================================================
 void TryStartMsdtcService()
 {
     try
     {
         TransactionInterop.GetWhereabouts();
     }
     catch (TransactionException e)
     {
         DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
     }
 }
Beispiel #6
0
        //=============================================================================================
        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

        /*
         * [PermissionSet(SecurityAction.Demand, Unrestricted = true)] // because we call code from a non-APTCA assembly; WSATs are not supported in partial trust, so customers should not be broken by this demand
         */
        ActivationProxy CreateActivationProxy(EndpointAddress address)
        {
            CoordinationService coordination = GetCoordinationService();

            try
            {
                return(coordination.CreateActivationProxy(address, false));
            }
            catch (CreateChannelFailureException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new TransactionException(SR.GetString(SR.WsatProxyCreationFailed), e));
            }
        }
Beispiel #7
0
        public Transaction UnmarshalTransaction(WsatTransactionInfo info)
        {
            if (info.Context.ProtocolVersion != this.protocolVersion)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new ArgumentException(SR.GetString(SR.InvalidWsatProtocolVersion)));
            }

            if (wsatConfig.OleTxUpgradeEnabled)
            {
                byte[] propToken = info.Context.PropagationToken;
                if (propToken != null)
                {
                    try
                    {
                        return(OleTxTransactionInfo.UnmarshalPropagationToken(propToken));
                    }
                    catch (TransactionException e)
                    {
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
                    }

                    // Fall back to WS-AT unmarshal
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        TraceUtility.TraceEvent(TraceEventType.Information,
                                                TraceCode.TxFailedToNegotiateOleTx,
                                                SR.GetString(SR.TraceCodeTxFailedToNegotiateOleTx, info.Context.Identifier));
                    }
                }
            }

            // Optimization: if the context's registration service points to our local TM, we can
            // skip the CreateCoordinationContext step
            CoordinationContext localContext = info.Context;

            if (!this.wsatConfig.IsLocalRegistrationService(localContext.RegistrationService, this.protocolVersion))
            {
                // Our WS-AT protocol service for the context's protocol version should be enabled
                if (!this.wsatConfig.IsProtocolServiceEnabled(this.protocolVersion))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              new TransactionException(SR.GetString(SR.WsatProtocolServiceDisabled, this.protocolVersion)));
                }

                // We should have enabled inbound transactions
                if (!this.wsatConfig.InboundEnabled)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              new TransactionException(SR.GetString(SR.InboundTransactionsDisabled)));
                }

                // The sender should have enabled both WS-AT and outbound transactions
                if (this.wsatConfig.IsDisabledRegistrationService(localContext.RegistrationService))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              new TransactionException(SR.GetString(SR.SourceTransactionsDisabled)));
                }

                // Ask the WS-AT protocol service to unmarshal the transaction
                localContext = CreateCoordinationContext(info);
            }

            Guid transactionId = localContext.LocalTransactionId;

            if (transactionId == Guid.Empty)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new TransactionException(SR.GetString(SR.InvalidCoordinationContextTransactionId)));
            }

            byte[] propagationToken = MarshalPropagationToken(ref transactionId,
                                                              localContext.IsolationLevel,
                                                              localContext.IsolationFlags,
                                                              localContext.Description);

            return(OleTxTransactionInfo.UnmarshalPropagationToken(propagationToken));
        }
Beispiel #8
0
        //=============================================================================================
        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

        /*
         * [PermissionSet(SecurityAction.Demand, Unrestricted = true)] // because we call code from a non-APTCA assembly; WSATs are not supported in partial trust, so customers should not be broken by this demand
         */
        CreateCoordinationContextResponse Enlist(ref CreateCoordinationContext cccMessage)
        {
            int attempts = 0;

            while (true)
            {
                ActivationProxy proxy   = GetActivationProxy();
                EndpointAddress address = proxy.To;

                EndpointAddress localActivationService  = this.wsatConfig.LocalActivationService(this.protocolVersion);
                EndpointAddress remoteActivationService = this.wsatConfig.RemoteActivationService(this.protocolVersion);

                try
                {
                    return(proxy.SendCreateCoordinationContext(ref cccMessage));
                }
                catch (WsatSendFailureException e)
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);

                    // Don't retry if we're not likely to succeed on the next pass
                    Exception inner = e.InnerException;
                    if (inner is TimeoutException ||
                        inner is QuotaExceededException ||
                        inner is FaultException)
                    {
                        throw;
                    }

                    // Give up after 10 attempts
                    if (attempts > 10)
                    {
                        throw;
                    }

                    if (attempts > 5 &&
                        remoteActivationService != null &&
                        ReferenceEquals(address, localActivationService))
                    {
                        // Switch over to the remote activation service.
                        // In clustered scenarios this uses the cluster name,
                        // so it should always work if the resource is online
                        // This covers the case where we were using a local cluster
                        // resource which failed over to another node
                        address = remoteActivationService;
                    }
                }
                finally
                {
                    proxy.Release();
                }

                TryStartMsdtcService();

                // We need to refresh our proxy here because the channel is sessionful
                // and may simply decided to enter the faulted state if something fails.
                RefreshActivationProxy(address);

                // Don't spin
                Thread.Sleep(0);
                attempts++;
            }
        }