Exemple #1
0
        /// <summary>
        /// Ascertain, i.e. assess and setup, whether the payload of a message body <paramref name="trackingStream"/>
        /// needs to be captured outside of the BAM monitoring database, that is in the <see cref="ClaimStore"/>, or not.
        /// </summary>
        /// <param name="trackingStream">
        /// The stream to assess.
        /// </param>
        /// <param name="trackingModes">
        /// The extent to which a messaging activity will be recorded.
        /// </param>
        /// <param name="transactionFactory">
        /// The <see cref="IKernelTransaction"/> factory method whose offspring transaction has to be piggybacked if the
        /// message body's payload needs to be claimed to disk. It can be <c>null</c> if piggybacking is not desired nor
        /// possible, like for instance when calling this method from a send pipeline, as BizTalk does not provide for
        /// transaction piggybacking in send pipelines.
        /// </param>
        /// <returns>
        /// The ascertained <see cref="ActivityTrackingModes"/>, that is the one that will actually be applied.
        /// </returns>
        /// <remarks>
        /// <para>
        /// If the size of the <see cref="TrackingStream"/> does not exceed a 512KB threshold, the <see
        /// cref="TrackingStream"/>'s capture will be setup according to a <see cref="MessageBodyCaptureDescriptor"/>
        /// whose <see cref="MessageBodyCaptureDescriptor.Data"/> will contain a base64-encoding of the compressed stream
        /// content.
        /// </para>
        /// <para>
        /// If the size of the <see cref="TrackingStream"/> exceeds the 512KB threshold, the <see
        /// cref="TrackingStream"/>'s capture will be setup according to a <see cref="MessageBodyCaptureDescriptor"/>
        /// whose <see cref="MessageBodyCaptureDescriptor.Data"/> will contain the relative URL that can be used to get
        /// back the payload from the <see cref="ClaimStore"/>.
        /// </para>
        /// <para>
        /// The 512KB threshold has been chosen according to the BizTalk documentation which proscribes BAM
        /// <c>LongReferenceData</c> item of more than 512 KB.
        /// </para>
        /// </remarks>
        public virtual void SetupMessageBodyCapture(TrackingStream trackingStream, ActivityTrackingModes trackingModes, Func <IKernelTransaction> transactionFactory)
        {
            if (trackingStream == null)
            {
                throw new ArgumentNullException("trackingStream");
            }

            if (_logger.IsDebugEnabled)
            {
                _logger.DebugFormat(
                    "Message body capture is being set up for '{0}' tracking requirements.",
                    Convert.ToString(trackingModes));
            }

            // never want to claim (save to disk) a payload if it is small, hence always probe for its size
            string encodedCompression;
            var    isCompressible = trackingStream.AsMarkable().TryCompressToBase64String(PAYLOAD_SIZE_THRESHOLD, out encodedCompression);

            if (isCompressible)
            {
                var captureDescriptor = new MessageBodyCaptureDescriptor(encodedCompression, MessageBodyCaptureMode.Unclaimed);
                trackingStream.SetupCapture(captureDescriptor);
            }
            else
            {
                var captureDescriptor = new MessageBodyCaptureDescriptor(GenerateClaimStoreEntry(), MessageBodyCaptureMode.Claimed);
                var capturingStream   = CreateCapturingStream(captureDescriptor.Data, trackingModes, transactionFactory);
                trackingStream.SetupCapture(captureDescriptor, capturingStream);
            }
        }
        public void StepOnly()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Step;

            sut.RequiresStepTracking().Should().BeTrue();
            sut.RequiresContextTracking().Should().BeFalse();
            sut.RequiresBodyTracking().Should().BeFalse();
            sut.RequiresBodyClaimChecking().Should().BeFalse();

            Convert.ToString(sut).Should().Be("Step");
        }
Exemple #3
0
        public void StepOnly()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Step;

            Assert.That(sut.RequiresStepTracking());
            Assert.That(sut.RequiresContextTracking(), Is.False);
            Assert.That(sut.RequiresBodyTracking(), Is.False);
            Assert.That(sut.RequiresBodyClaimChecking(), Is.False);

            Assert.That(Convert.ToString(sut), Is.EqualTo("Step"));
        }
Exemple #4
0
        public void ClaimRequiresBody()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Claim;

            Assert.That(sut, Is.EqualTo(ActivityTrackingModes.Claim | ActivityTrackingModes.Body));
            Assert.That(sut.RequiresBodyClaimChecking());
            Assert.That(sut.RequiresBodyTracking());

            Assert.That(Convert.ToString(sut), Is.EqualTo("Claim"));

            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Claim"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Claim, Body"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Body"), Is.Not.EqualTo(sut));
        }
        public void ContextRequiresStep()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Context;

            sut.Should().Be(ActivityTrackingModes.Context | ActivityTrackingModes.Step);
            sut.RequiresContextTracking().Should().BeTrue();
            sut.RequiresStepTracking().Should().BeTrue();

            Convert.ToString(sut).Should().Be("Context");

            Enum.Parse(typeof(ActivityTrackingModes), "Context").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Context, Step").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Step").Should().NotBe(sut);
        }
Exemple #6
0
        public void ContextRequiresStep()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Context;

            Assert.That(sut, Is.EqualTo(ActivityTrackingModes.Context | ActivityTrackingModes.Step));
            Assert.That(sut.RequiresContextTracking());
            Assert.That(sut.RequiresStepTracking());

            Assert.That(Convert.ToString(sut), Is.EqualTo("Context"));

            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Context"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Context, Step"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Step"), Is.Not.EqualTo(sut));
        }
        public void ClaimRequiresBody()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Claim;

            sut.Should().Be(ActivityTrackingModes.Claim | ActivityTrackingModes.Body);
            sut.RequiresBodyClaimChecking().Should().BeTrue();
            sut.RequiresBodyTracking().Should().BeTrue();

            Convert.ToString(sut).Should().Be("Claim");

            Enum.Parse(typeof(ActivityTrackingModes), "Claim").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Claim, Body").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Body").Should().NotBe(sut);
        }
        public void BodyRequiresContext()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Body;

            sut.Should().Be(ActivityTrackingModes.Body | ActivityTrackingModes.Context);
            sut.RequiresBodyTracking().Should().BeTrue();
            sut.RequiresContextTracking().Should().BeTrue();
            sut.RequiresBodyClaimChecking().Should().BeFalse();

            Convert.ToString(sut).Should().Be("Body");

            Enum.Parse(typeof(ActivityTrackingModes), "Body").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Body, Context").Should().Be(sut);
            Enum.Parse(typeof(ActivityTrackingModes), "Context").Should().NotBe(sut);
        }
 /// <summary>
 /// Creates a BAM <c>MessagingStep</c> activity that captures descriptive information about the <see
 /// cref="IBaseMessage"/> being processed.
 /// </summary>
 /// <param name="trackingModes">
 /// The extent to which information about a messaging step activity will be tracked and recorded.
 /// </param>
 /// <param name="trackingStream">
 /// The <see cref="TrackingStream"/> that wraps the actual message body's stream that will captured.
 /// </param>
 internal virtual void TrackActivity(ActivityTrackingModes trackingModes, TrackingStream trackingStream)
 {
     if (trackingModes.RequiresStepTracking())
     {
         TrackStep(trackingStream.Length);
     }
     if (trackingModes.RequiresContextTracking())
     {
         TrackMessageContext();
     }
     if (trackingModes.RequiresBodyTracking())
     {
         TrackMessageBody(trackingStream.CaptureDescriptor);
     }
 }
Exemple #10
0
        public void BodyRequiresContext()
        {
            const ActivityTrackingModes sut = ActivityTrackingModes.Body;

            Assert.That(sut, Is.EqualTo(ActivityTrackingModes.Body | ActivityTrackingModes.Context));
            Assert.That(sut.RequiresBodyTracking());
            Assert.That(sut.RequiresContextTracking());
            Assert.That(sut.RequiresBodyClaimChecking(), Is.False);

            Assert.That(Convert.ToString(sut), Is.EqualTo("Body"));

            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Body"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Body, Context"), Is.EqualTo(sut));
            Assert.That(Enum.Parse(typeof(ActivityTrackingModes), "Context"), Is.Not.EqualTo(sut));
        }
        private void Complete(ActivityTrackingModes trackingModes, TrackingStream trackingStream)
        {
            var isMessagingProcess = _previousMessagingStep != null;

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug($"Completing tracking of a messaging {(isMessagingProcess ? "process" : "step")}.");
            }

            // track the whole wealth of messaging activity, it might be a complete process or a single messaging step
            if (isMessagingProcess)
            {
                _process.TrackActivity();
                _process.AddStep(_previousMessagingStep);
            }
            _messagingStep.TrackActivity(trackingModes, trackingStream);
            _process.IfNotNull(p => p.AddStep(_messagingStep));
        }
Exemple #12
0
        /// <summary>
        /// Create a <see cref="Stream"/> to an entry in the claim store that piggies back a kernel transaction if one can
        /// be factored.
        /// </summary>
        /// <param name="url">
        /// The claim store entry.
        /// </param>
        /// <param name="trackingModes">
        /// </param>
        /// <param name="transactionFactory">
        /// The <see cref="IKernelTransaction"/> factory.
        /// </param>
        /// <returns>
        /// The <see cref="Stream"/> to the claim store entry.
        /// </returns>
        private Stream CreateCapturingStream(string url, ActivityTrackingModes trackingModes, Func <IKernelTransaction> transactionFactory)
        {
            // RequiresCheckInAndOut entails payloads are first saved locally and moved by ClaimStore.Agent into claim
            // store where there will be a subfolder for each date that some payload has been saved/tracked to disk. To
            // ease the job of the ClaimStore.Agent the subfolder is not created locally (but the current date is however
            // kept in the name). When not RequiresCheckInAndOut, the payloads are tracked/saved to disk at the exact same
            // place that it will be redeemed from afterwards, that is in a subfolder corresponding to the current date (of
            // course, one needs to ensure the folders get created).

            string filePath;

            if (RequiresCheckInAndOut)
            {
                // .trk extension is used to denote simple message body's payload tracking scenarios, i.e. where the
                // message's payload is large enough that it would not fit in the BAM tracking database. Message body's
                // payload are therefore tracked to the local disk are then brought asynchronously to the central claim
                // store by the ClaimStore.Agent.

                // .chk extension is used to denote full-fledged claim check scenarios, i.e. where the actual message's
                // payload is claimed to disk (as with regular tracking) but also replaced by a token that needs to be
                // checked in and out. Message body's payload are claimed to the local disk and then brought asynchronously
                // to the central claim store by the ClaimStore.Agent. Because claims are brought asynchronously to the
                // central claim store, one has therefore to ensure a claim is available in the central claim store before
                // it could be redeemed.

                // The .chk and .trk extensions are there to allow the ClaimStore.Agent to distinguish these scenarios so
                // that it can, (1) bring claimed or tracked payloads to the central claim store and (2) make claims
                // available for redeem as soon as they have been brought to the central store.

                var extension = trackingModes.RequiresBodyClaimChecking() ? ".chk" : ".trk";
                filePath = Path.Combine(CheckInDirectory, url.Replace("\\", "") + extension);
            }
            else
            {
                filePath = Path.Combine(CheckInDirectory, url);
                // ReSharper disable once AssignNullToNotNullAttribute
                Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            }
            return(FileTransacted.Create(filePath, 8192, transactionFactory.IfNotNull(ktf => ktf())));
        }
Exemple #13
0
 public static bool RequiresBodyClaimChecking(this ActivityTrackingModes modes)
 {
     return((modes & ActivityTrackingModes.Claim) == ActivityTrackingModes.Claim);
 }
Exemple #14
0
 public static bool RequiresBodyTracking(this ActivityTrackingModes modes)
 {
     return((modes & ActivityTrackingModes.Body) == ActivityTrackingModes.Body);
 }
Exemple #15
0
 public static bool RequiresContextTracking(this ActivityTrackingModes modes)
 {
     return((modes & ActivityTrackingModes.Context) == ActivityTrackingModes.Context);
 }
Exemple #16
0
 public static bool RequiresStepTracking(this ActivityTrackingModes modes)
 {
     return((modes & ActivityTrackingModes.Step) == ActivityTrackingModes.Step);
 }
Exemple #17
0
 internal override void TrackActivity(ActivityTrackingModes trackingModes, TrackingStream trackingStream)
 {
     throw new NotSupportedException();
 }