예제 #1
0
 public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
 {
     if (message.Direction().IsInbound())
     {
         var correlationId = message.GetProperty(SBMessagingProperties.CorrelationId);
         if (!correlationId.IsNullOrEmpty())
         {
             message.PromoteCorrelationToken(correlationId);
         }
         var messageType = message.GetProperty(BrokeredProperties.MessageType);
         if (!messageType.IsNullOrEmpty())
         {
             message.Promote(BtsProperties.MessageType, messageType);
         }
     }
     else
     {
         var correlationToken = message.GetProperty(BizTalkFactoryProperties.CorrelationToken);
         if (!correlationToken.IsNullOrEmpty())
         {
             message.SetProperty(SBMessagingProperties.CorrelationId, correlationToken);
         }
         var messageType = message.GetOrProbeMessageType(pipelineContext);
         if (!messageType.IsNullOrEmpty())
         {
             message.SetProperty(BrokeredProperties.MessageType, messageType);
         }
     }
     return(message);
 }
 private static bool IsSolicitResponse(this IBaseMessage message)
 {
     if (message.GetProperty(BtsProperties.IsSolicitResponse) ?? false)
     {
         return(true);
     }
     return(message.Direction().IsInbound() && (message.GetProperty(BtsProperties.WasSolicitResponse) ?? false));
 }
 /// <summary>
 /// Returns the <see cref="TrackingContext"/> associated to the <paramref name="message"/>.
 /// </summary>
 /// <param name="message">
 /// Message whose associated <see cref="TrackingContext"/> will be returned.
 /// </param>
 /// <returns>
 /// The <see cref="TrackingContext"/> associated to the <paramref name="message"/>.
 /// </returns>
 public static TrackingContext GetTrackingContext(this IBaseMessage message)
 {
     if (message == null)
     {
         throw new ArgumentNullException(nameof(message));
     }
     return(new TrackingContext {
         ProcessActivityId = message.GetProperty(TrackingProperties.ProcessActivityId),
         ProcessingStepActivityId = message.GetProperty(TrackingProperties.ProcessingStepActivityId),
         MessagingStepActivityId = message.GetProperty(TrackingProperties.MessagingStepActivityId)
     });
 }
 public static MessageDirection FailedDirection(this IBaseMessage message)
 {
     if (!message.GetProperty(ErrorReportProperties.OutboundTransportLocation).IsNullOrEmpty())
     {
         return(MessageDirection.Outbound);
     }
     if (!message.GetProperty(ErrorReportProperties.InboundTransportLocation).IsNullOrEmpty())
     {
         return(MessageDirection.Inbound);
     }
     throw new Exception("Unable to determine message direction.");
 }
 public static MessageDirection Direction(this IBaseMessage message)
 {
     // It's imperative to check outbound context properties first. If send port subscribes to a receive port, all
     // of the context properties of the receive location will also be present in the outbound context, though
     // demoted, which would confuse this code if it'd check the inbound context properties first.
     if (!message.GetProperty(BtsProperties.OutboundTransportLocation).IsNullOrEmpty())
     {
         return(MessageDirection.Outbound);
     }
     if (!message.GetProperty(BtsProperties.InboundTransportLocation).IsNullOrEmpty())
     {
         return(MessageDirection.Inbound);
     }
     throw new Exception("Unable to determine message direction.");
 }
예제 #6
0
        public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
        {
            if (pipelineContext == null)
            {
                throw new ArgumentNullException(nameof(pipelineContext));
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            var location = message.GetProperty(BizTalkFactoryProperties.OutboundTransportLocation);

            if (location.IsNullOrEmpty())
            {
                throw new InvalidOperationException("BizTalkFactoryProperties.OutboundTransportLocation has to be set in context in order to determine zip entry name.");
            }

            message.BodyPart.WrapOriginalDataStream(
                originalStream => {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Wrapping message stream in a zip-compressing stream.");
                }
                var zipEntryName = Path.GetFileName(location);
                return(new ZipOutputStream(originalStream, zipEntryName));
            },
                pipelineContext.ResourceTracker);

            var zipLocation = Path.Combine(Path.GetDirectoryName(location), Path.GetFileNameWithoutExtension(location) + ".zip");

            message.SetProperty(BizTalkFactoryProperties.OutboundTransportLocation, zipLocation);

            return(message);
        }
예제 #7
0
        public static Type ResolvePluginType <T>(this IBaseMessage message, MessageContextProperty <T, string> messageContextProperty, Type configuredPluginType)
            where T : MessageContextPropertyBase, new()
        {
            // look after plugin type name in message context
            var pluginTypeName = message.GetProperty(messageContextProperty);

            if (!pluginTypeName.IsNullOrEmpty())
            {
                // remove plugin type name from context to ensure no one else will use it too
                message.DeleteProperty(messageContextProperty);
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug($"Using message context's plugin type '{pluginTypeName}'.");
                }
                return(Type.GetType(pluginTypeName, true));
            }
            // use plugin type configured at pipeline level if no one found in context
            if (configuredPluginType != null)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug($"Using configured plugin type '{configuredPluginType.AssemblyQualifiedName}'.");
                }
                return(configuredPluginType);
            }
            return(null);
        }
예제 #8
0
        public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
        {
            var location = message.GetProperty(BizTalkFactoryProperties.OutboundTransportLocation);

            if (location.IsNullOrEmpty())
            {
                throw new InvalidOperationException("BizTalkFactoryProperties.OutboundTransportLocation has to be set in context in order to determine zip entry name.");
            }

            // TODO instead of SharpZipLib's ZipOutputStream use BCL's System.IO.Compression.ZipArchive or System.IO.Compression.GZipStream or System.IO.Compression.DeflateStream as only one zip entry is supported
            message.BodyPart.WrapOriginalDataStream(
                originalStream => {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Wrapping message stream in a zip-compressing stream.");
                }
                var zipEntryName = Path.GetFileName(location);
                return(new ZipOutputStream(originalStream, zipEntryName));
            },
                pipelineContext.ResourceTracker);

            // ReSharper disable once AssignNullToNotNullAttribute
            var zipLocation = Path.Combine(Path.GetDirectoryName(location), Path.GetFileNameWithoutExtension(location) + ".zip");

            message.SetProperty(BizTalkFactoryProperties.OutboundTransportLocation, zipLocation);

            return(message);
        }
예제 #9
0
        public static string GetOrProbeMessageType(this IBaseMessage message, IResourceTracker resourceTracker)
        {
            var messageType = message.GetProperty(BtsProperties.MessageType);

            return(messageType.IsNullOrEmpty()
                                ? message.ProbeMessageType(resourceTracker)
                                : messageType);
        }
        public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
        {
            var disableTransportRetries = message.GetProperty(BizTalkFactoryProperties.DisableTransportRetries);

            if (disableTransportRetries.HasValue && disableTransportRetries.Value)
            {
                message.DisableTransportRetries();
            }
            return(message);
        }
예제 #11
0
        protected void RestoreCachedTrackingContext(IBaseMessage message)
        {
            var duration = (int)TrackingContextCacheDuration.TotalSeconds;

            // if propagation of TrackingContext is not disabled, restore a previously cached TrackingContext
            if (duration > -1)
            {
                _logger.Debug("Restoring cached tracking context");
                var trackingContext = TrackingContextCache.Instance.Get(message.GetProperty(BtsProperties.TransmitWorkId));
                message.SetTrackingContext(trackingContext);
            }
        }
예제 #12
0
        public static int ResolveTrackingContextCacheDuration(this IBaseMessage message, TimeSpan configuredDuration)
        {
            // TODO ? assert that WCF transport is used
            var wcfTimeout = message.GetProperty(WcfProperties.SendTimeout);

            if (!wcfTimeout.IsNullOrEmpty())
            {
                return((int)TimeSpan.Parse(wcfTimeout, CultureInfo.InvariantCulture).TotalSeconds);
            }

            // TODO ? assert that HTTP transport is used
            var httpTimeout = message.GetProperty(HttpProperties.RequestTimeout);

            // TODO ? assert Timeout.Value > 0
            if (httpTimeout.HasValue)
            {
                return(httpTimeout.Value);
            }

            return((int)configuredDuration.TotalSeconds);
        }
예제 #13
0
 protected void CacheTrackingContext(IBaseMessage message, int duration)
 {
     // if propagation of TrackingContext is not disabled, cache the current TrackingContext
     if (duration > -1)
     {
         _logger.DebugFormat("Caching current tracking context for {0} seconds", duration);
         TrackingContextCache.Instance.Set(
             message.GetProperty(BtsProperties.TransmitWorkId),
             message.GetTrackingContext(),
             duration + 1);
     }
 }
        internal XmlTranslationSet BuildXmlTranslationSet(IBaseMessage message)
        {
            var translations = message.GetProperty(BizTalkFactoryProperties.XmlTranslations);

            if (translations.IsNullOrEmpty())
            {
                return(Translations);
            }

            var contextReplacements = XmlTranslationSetConverter.Deserialize(translations);

            return(contextReplacements.Union(Translations));
        }
        public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
        {
            var customBrokeredMessagePropertyNamespace = message.GetProperty(SBMessagingProperties.CustomBrokeredMessagePropertyNamespace)
                                                         ?? throw new InvalidOperationException($"{nameof(CustomBrokeredMessagePropertyNamespace)} has no value defined in SB-Messaging adapter configuration.");

            if (message.Direction().IsInbound())
            {
                var correlationId = message.GetProperty(SBMessagingProperties.CorrelationId);
                // use the native BTS API instead of the message.PromoteCorrelationId(correlationId) to have no dependency on
                // BizTalk.Schemas which would reversed the desired dependency order, i.e. from an artifact component
                // (BizTalk.Schemas) to a runtime one (BizTalk.Pipeline.MicroComponents itself)
                if (!correlationId.IsNullOrEmpty())
                {
                    message.Context.Promote(nameof(SBMessagingProperties.CorrelationId), PropertySchemaNamespaces.BizTalkFactory, correlationId);
                }
                var messageType = (string)message.Context.Read(nameof(BizTalkFactoryProperties.MessageType), customBrokeredMessagePropertyNamespace);
                if (!messageType.IsNullOrEmpty())
                {
                    message.Promote(BtsProperties.MessageType, messageType);
                }
            }
            else
            {
                // use the native BTS API instead of the message.GetProperty(BizTalkFactoryProperties.CorrelationId) to have no
                // dependency on BizTalk.Schemas which would reversed the desired dependency order, i.e. from an artifact component
                // (BizTalk.Schemas) to a runtime one (BizTalk.Pipeline.MicroComponents itself)
                var correlationId = (string)message.Context.Read(nameof(SBMessagingProperties.CorrelationId), BizTalkFactoryProperties.MessageType.Namespace);
                if (!correlationId.IsNullOrEmpty())
                {
                    message.SetProperty(SBMessagingProperties.CorrelationId, correlationId);
                }
                var messageType = message.GetOrProbeMessageType(pipelineContext);
                if (!messageType.IsNullOrEmpty())
                {
                    message.Context.Write(nameof(BizTalkFactoryProperties.MessageType), customBrokeredMessagePropertyNamespace, messageType);
                }
            }
            return(message);
        }
예제 #16
0
        public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage message)
        {
            message.EnsureFileOutboundTransport();
            var location = Path.GetDirectoryName(message.GetProperty(BtsProperties.OutboundTransportLocation));

            if (ImpersonationEnabled)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Impersonating file adapter's configured user to create directory.");
                }
                Delegate.InvokeAs(
                    message.GetProperty(FileProperties.Username),
                    message.GetProperty(FileProperties.Password),
                    () => CreateDirectory(location));
            }
            else
            {
                CreateDirectory(location);
            }
            return(message);
        }
예제 #17
0
        /// <summary>
        /// Replace the message body's payload stream with either a <see cref="Schemas.Xml.Claim.Check"/> or a <see
        /// cref="Schemas.Xml.Claim.CheckIn"/> token message if its content has been assessed to be saved to disk while
        /// being tracked (see <see cref="SetupMessageBodyCapture"/>). Leave the message body's payload stream unaltered
        /// otherwise.
        /// </summary>
        /// <param name="message">
        /// The <see cref="IBaseMessage"/> whose message body's payload stream is going to be claimed and replace by a
        /// token message.
        /// </param>
        /// <param name="resourceTracker">
        /// Pipeline's <see cref="IResourceTracker"/> to which to report the newly created message token stream.
        /// </param>
        /// <remarks>
        /// The <see cref="IBaseMessage"/>'s <see cref="IBaseMessageContext"/> is also updated with the message type of
        /// the token message that is put in place of the actual message body's payload.
        /// </remarks>
        public virtual void Claim(IBaseMessage message, IResourceTracker resourceTracker)
        {
            var trackingStream = message.BodyPart.GetOriginalDataStream() as TrackingStream;

            if (trackingStream == null)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Skipping claim of message body stream's payload; BodyPart's OriginalDataStream is not a TrackingStream.");
                }
            }
            else if (trackingStream.CaptureDescriptor.CaptureMode != MessageBodyCaptureMode.Claimed)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Skipping claim of message body stream's payload; CaptureDescriptor.CaptureMode is not MessageBodyCaptureMode.Claimed.");
                }
            }
            else
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.DebugFormat("Performing claim of message body stream's payload '{0}'.", trackingStream.CaptureDescriptor.Data);
                }
                var          claimedMessageType = message.GetProperty(BtsProperties.MessageType);
                DocumentSpec documentSpec;
                Stream       tokenMessageStream;
                if (RequiresCheckInAndOut)
                {
                    documentSpec       = typeof(Claim.CheckIn).GetMetadata().DocumentSpec;
                    tokenMessageStream = MessageFactory.CreateClaimCheckIn(claimedMessageType, trackingStream.CaptureDescriptor.Data).AsStream();
                }
                else
                {
                    documentSpec       = typeof(Claim.Check).GetMetadata().DocumentSpec;
                    tokenMessageStream = MessageFactory.CreateClaimCheck(claimedMessageType, trackingStream.CaptureDescriptor.Data).AsStream();
                }

                // fix the message type before capturing the body stream so that it get captured while tracking MessagingStep
                message.Promote(BtsProperties.MessageType, documentSpec.DocType);
                message.Promote(BtsProperties.SchemaStrongName, documentSpec.DocSpecStrongName);

                // drain and capture body stream
                trackingStream.Capture();

                // replace message body's payload with the token message stream
                message.BodyPart.SetDataStream(tokenMessageStream, resourceTracker);
            }
        }
예제 #18
0
 public static bool IsAbout <T>(this IBaseMessage message) where T : SchemaBase
 {
     return(message.GetProperty(BtsProperties.MessageType).IsOfType <T>());
 }
예제 #19
0
 public static bool IsPromoted <T>(this IBaseMessage message, MessageContextProperty <T, string> property)
     where T : MessageContextPropertyBase, new()
 {
     return(!message.GetProperty(property).IsNullOrEmpty() && message.Context.IsPromoted(property.Name, property.Namespace));
 }
예제 #20
0
 public static bool HasFailed(this IBaseMessage message)
 {
     return(message.GetProperty(ErrorReportProperties.ErrorType) != null);
 }
예제 #21
0
 public static bool IsPromoted <T, TV>(this IBaseMessage message, MessageContextProperty <T, TV> property)
     where T : MessageContextPropertyBase, new()
     where TV : struct
 {
     return(message.GetProperty(property).HasValue&& message.Context.IsPromoted(property.Name, property.Namespace));
 }
 private static bool IsRequestResponse(this IBaseMessage message)
 {
     return(message.GetProperty(BtsProperties.IsRequestResponse) ?? false);
 }