示例#1
0
        public void PartitioningJsonTranscode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonPartitioningKey));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, new PartitioningExtension());

            Assert.Equal("1", cloudEvent.Extension <PartitioningExtension>().PartitioningKeyValue);
        }
示例#2
0
        public void Transcode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, Sequence.AllAttributes);

            Assert.Equal("Integer", cloudEvent[Sequence.SequenceTypeAttribute]);
            Assert.Equal("25", cloudEvent[Sequence.SequenceAttribute]);
        }
示例#3
0
        public void Transcode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out _);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData);

            Assert.Equal("abc", cloudEvent["partitionkey"]);
            Assert.Equal("abc", cloudEvent[Partitioning.PartitionKeyAttribute]);
            Assert.Equal("abc", cloudEvent.GetPartitionKey());
        }
示例#4
0
        public void Transcode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out _);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, DistributedTracing.AllAttributes);

            Assert.Equal(SampleParent, cloudEvent[DistributedTracing.TraceParentAttribute]);
            Assert.Equal(SampleParent, cloudEvent.GetTraceParent());
            Assert.Equal(SampleState, cloudEvent[DistributedTracing.TraceStateAttribute]);
            Assert.Equal(SampleState, cloudEvent.GetTraceState());
        }
示例#5
0
        public void ReserializeTest()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent, out var contentType);
            var cloudEvent2   = jsonFormatter.DecodeStructuredEvent(jsonData);

            Assert.Equal(cloudEvent2.SpecVersion, cloudEvent.SpecVersion);
            Assert.Equal(cloudEvent2.Type, cloudEvent.Type);
            Assert.Equal(cloudEvent2.Source, cloudEvent.Source);
            Assert.Equal(cloudEvent2.Id, cloudEvent.Id);
            Assert.Equal(cloudEvent2.Time.Value.ToUniversalTime(), cloudEvent.Time.Value.ToUniversalTime());
            Assert.Equal(cloudEvent2.ContentType, cloudEvent.ContentType);
            Assert.Equal(cloudEvent2.Data, cloudEvent.Data);
        }
示例#6
0
        public void SamplingJsonTranscode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSampledRate));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, new SamplingExtension());

            Assert.Equal(CloudEventsSpecVersion.Default, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);

            Assert.Equal(1, cloudEvent.Extension <SamplingExtension>().SampledRate.Value);
        }
示例#7
0
        public void SamplingJsonTranscode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson));

            // Note that the value is just a string here, as we don't know the attribute type.
            Assert.Equal("1", cloudEvent1["sampledrate"]);

            var jsonData   = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out _);
            var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, Sampling.AllAttributes);

            // When parsing with the attributes in place, the value is propagated as an integer.
            Assert.Equal(1, cloudEvent["sampledrate"]);
            Assert.Equal(1, cloudEvent.GetSampledRate());
        }
示例#8
0
        public void ReserializeTest10()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent, out var contentType);
            var cloudEvent2   = jsonFormatter.DecodeStructuredEvent(jsonData);

            Assert.Equal(cloudEvent2.SpecVersion, cloudEvent.SpecVersion);
            Assert.Equal(cloudEvent2.Type, cloudEvent.Type);
            Assert.Equal(cloudEvent2.Source, cloudEvent.Source);
            Assert.Equal(cloudEvent2.Id, cloudEvent.Id);
            AssertTimestampsEqual(cloudEvent2.Time, cloudEvent.Time);
            Assert.Equal(cloudEvent2.DataContentType, cloudEvent.DataContentType);
            Assert.Equal(cloudEvent2.Data, cloudEvent.Data);
        }
示例#9
0
        public void PartitioningParse()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonPartitioningKey), new PartitioningExtension());

            Assert.Equal("1", cloudEvent.Extension <PartitioningExtension>().PartitioningKeyValue);
        }
示例#10
0
        public void IntegerSequenceJsonTranscode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, new IntegerSequenceExtension());

            Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                         cloudEvent.Time.Value.ToUniversalTime());

            Assert.Equal(25, cloudEvent.Extension <IntegerSequenceExtension>().Sequence);
        }
示例#11
0
        public static CloudEvent ToCloudEvent(this Message <string, byte[]> message,
                                              ICloudEventFormatter eventFormatter = null, params ICloudEventExtension[] extensions)
        {
            if (!IsCloudEvent(message))
            {
                throw new InvalidOperationException();
            }

            var contentType = ExtractContentType(message);

            CloudEvent cloudEvent;

            if (!string.IsNullOrEmpty(contentType) &&
                contentType.StartsWith(CloudEvent.MediaType, StringComparison.InvariantCultureIgnoreCase))
            {
                // structured mode
                if (eventFormatter == null)
                {
                    if (contentType.EndsWith(JsonEventFormatter.MediaTypeSuffix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        eventFormatter = _jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Not supported CloudEvents media formatter.");
                    }
                }

                cloudEvent = _jsonFormatter.DecodeStructuredEvent(message.Value, extensions);
            }
            else
            {
                // binary mode
                var specVersion = ExtractVersion(message);

                cloudEvent = new CloudEvent(specVersion, extensions);
                var attributes        = cloudEvent.GetAttributes();
                var cloudEventHeaders = message.Headers.Where(h => h.Key.StartsWith(KafkaCloudEventMessage.KafkaHeaderPerfix));

                foreach (var header in cloudEventHeaders)
                {
                    if (string.Equals(header.Key, SpecVersionKafkaHeader1, StringComparison.InvariantCultureIgnoreCase) ||
                        string.Equals(header.Key, SpecVersionKafkaHeader2, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    var attributeName = header.Key.Substring(KafkaCloudEventMessage.KafkaHeaderPerfix.Length);
                    attributes.Add(attributeName,
                                   eventFormatter.DecodeAttribute(specVersion, attributeName, header.GetValueBytes(), extensions));
                }

                cloudEvent.DataContentType = contentType != null ? new ContentType(contentType) : null;
                cloudEvent.Data            = message.Value;
            }

            InitPartitioningKey(message, cloudEvent);

            return(cloudEvent);
        }
示例#12
0
        /// <summary>
        ///     Parses a string to a <see cref="EventBatch{TEvent}"/> from either a <see cref="CloudEvent"/> or <see cref="EventGridEvent"/> implementation.
        /// </summary>
        /// <param name="rawJsonBody">Raw JSON body</param>
        /// <param name="sessionId">Session id for event grid message</param>
        public static EventBatch <Event> Parse(string rawJsonBody, string sessionId)
        {
            Guard.NotNullOrWhitespace(rawJsonBody, nameof(rawJsonBody));
            Guard.NotNullOrWhitespace(sessionId, nameof(sessionId));

            var array = JArray.Parse(rawJsonBody);

            var deserializedEvents = new List <Event>();

            foreach (var eventObject in array.Children <JObject>())
            {
                var rawEvent = eventObject.ToString();

                if (eventObject.ContainsKey("cloudEventsVersion"))
                {
                    var jsonFormatter = new JsonEventFormatter();
                    var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(rawEvent));

                    deserializedEvents.Add(cloudEvent);
                }
                else
                {
                    var gridEvent = JsonConvert.DeserializeObject <EventGridEvent>(rawEvent, JsonSerializerSettings);
                    deserializedEvents.Add(gridEvent);
                }
            }

            var result = new EventBatch <Event>(sessionId, deserializedEvents);

            return(result);
        }
示例#13
0
        public void DistTraceJsonTranscode()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent1   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonDistTrace));
            var jsonData      = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(jsonData, new DistributedTracingExtension());

            Assert.Equal(CloudEventsSpecVersion.Default, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);

            Assert.Equal("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", cloudEvent.Extension <DistributedTracingExtension>().TraceParent);
            Assert.Equal("rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01,congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4=", cloudEvent.Extension <DistributedTracingExtension>().TraceState);
        }
示例#14
0
        public void Parse()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson), Sequence.AllAttributes);

            Assert.Equal("Integer", cloudEvent[Sequence.SequenceTypeAttribute]);
            Assert.Equal("25", cloudEvent[Sequence.SequenceAttribute]);
        }
示例#15
0
        public void SamplingParse()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(sampleJson), Sampling.AllAttributes);

            Assert.Equal(1, cloudEvent["sampledrate"]);
            Assert.Equal(1, cloudEvent.GetSampledRate());
        }
        public void StructuredParseWithExtensionsSuccess10()
        {
            // Register comexampleextension2 as an integer extension before parsing.
            var extension = CloudEventAttribute.CreateExtension("comexampleextension2", CloudEventAttributeType.Integer);

            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10), extension);

            // Instead of getting it as a string (as before), we now have it as an integer.
            Assert.Equal(10, cloudEvent["comexampleextension2"]);
        }
示例#17
0
        public void IntegerSequenceParse()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence), new IntegerSequenceExtension());

            Assert.Equal(CloudEventsSpecVersion.Default, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);

            Assert.Equal(25, cloudEvent.Extension <IntegerSequenceExtension>().Sequence);
        }
示例#18
0
        public void SamplingParse()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSampledRate), new SamplingExtension());

            Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                         cloudEvent.Time.Value.ToUniversalTime());

            Assert.Equal(1, cloudEvent.Extension <SamplingExtension>().SampledRate.Value);
        }
示例#19
0
        public T ToEvent <T>(EventData eventData) where T : EventBase
        {
            var        formatter  = new JsonEventFormatter();
            CloudEvent cloudEvent = formatter.DecodeStructuredEvent(eventData.Body.Array, new ICloudEventExtension[] { });

            if (cloudEvent.Data is T t)
            {
                return(t);
            }
            else if (cloudEvent.Data is JObject jObject)
            {
                return(jObject.ToObject <T>());
            }

            return(default);
        public void StructuredParseSuccess10()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10));

            Assert.Equal(CloudEventsSpecVersion.V1_0, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);
            Assert.Equal(MediaTypeNames.Text.Xml, cloudEvent.DataContentType);
            Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);
            Assert.Equal("value", cloudEvent["comexampleextension1"]);
            Assert.Equal("10", cloudEvent["comexampleextension2"]);
        }
示例#21
0
        public void StructuredParseWithExtensionsSuccess10()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10), new ComExampleExtension1Extension());

            Assert.Equal(CloudEventsSpecVersion.V1_0, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                         cloudEvent.Time.Value.ToUniversalTime());
            Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), cloudEvent.DataContentType);
            Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);

            Assert.Equal("value", cloudEvent.Extension <ComExampleExtension1Extension>().ComExampleExtension1);
        }
        private static List <CloudEvent> DeserializeRequest(Request request)
        {
            var content = request.Content;
            var stream  = new MemoryStream();

            content.WriteTo(stream, CancellationToken.None);
            stream.Position = 0;
            JsonDocument requestDocument = JsonDocument.Parse(stream);
            var          cloudEvents     = new List <CloudEvent>();

            foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
            {
                var bytes = JsonSerializer.SerializeToUtf8Bytes(property, typeof(JsonElement));
                cloudEvents.Add(s_eventFormatter.DecodeStructuredEvent(bytes));
            }

            return(cloudEvents);
        }
示例#23
0
        public void StructuredParseSuccess02()
        {
            var jsonFormatter = new JsonEventFormatter();
            var cloudEvent    = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv02));

            Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);
            Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), cloudEvent.DataContentType);
            Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);

            var attr = cloudEvent.GetAttributes();

            Assert.Equal("value", (string)attr["comexampleextension1"]);
            Assert.Equal(5, (int)((dynamic)attr["comexampleextension2"]).othervalue);
        }
        public void StructuredParseWithExtensionsSuccess()
        {
            var jsonFormatter      = new JsonEventFormatter();
            var avroFormatter      = new AvroEventFormatter();
            var extensionAttribute = CloudEventAttribute.CreateExtension("comexampleextension1", CloudEventAttributeType.String);
            var cloudEventJ        = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10), extensionAttribute);
            var avroData           = avroFormatter.EncodeStructuredEvent(cloudEventJ, out var contentType);
            var cloudEvent         = avroFormatter.DecodeStructuredEvent(avroData, extensionAttribute);

            Assert.Equal(CloudEventsSpecVersion.V1_0, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            AssertTimestampsEqual("2018-04-05T17:31:00Z", cloudEvent.Time.Value);
            Assert.Equal(MediaTypeNames.Text.Xml, cloudEvent.DataContentType);
            Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);

            Assert.Equal("value", cloudEvent[extensionAttribute]);
        }
        /// <summary>
        /// Tries to parse the given raw <paramref name="message" /> to the contract of the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />.
        /// </summary>
        /// <param name="message">The raw incoming message that will be tried to parse against the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />'s message contract.</param>
        /// <param name="messageType">The type of the message that the message handler can process.</param>
        /// <param name="result">The resulted parsed message when the <paramref name="message" /> conforms with the message handlers' contract.</param>
        /// <returns>
        ///     [true] if the <paramref name="message" /> conforms the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />'s contract; otherwise [false].
        /// </returns>
        public override bool TryDeserializeToMessageFormat(string message, Type messageType, out object result)
        {
            try
            {
                if (messageType == typeof(CloudEvent))
                {
                    CloudEvent cloudEvent = JsonEventFormatter.DecodeStructuredEvent(DefaultEncoding.GetBytes(message));

                    result = cloudEvent;
                    return(true);
                }
            }
            catch (Exception exception)
            {
                Logger.LogWarning(exception, "Unable to deserialize the CloudEvent");
            }

            result = null;
            return(false);
        }
        public static async Task SBQueueStart(
            [ServiceBusTrigger("q-shipping-in", Connection = "SB-Queue-In-AppSettings")] string paymentItem,
            [OrchestrationClient] DurableOrchestrationClient starter,
            ILogger log)
        {
            _currentActivity = Activity.Current;

            var jsonFormatter = new JsonEventFormatter();
            var inboundEvent  = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(paymentItem));
            var paymentCtx    = JsonConvert.DeserializeObject <PaymentContext>((string)inboundEvent.Data);

            log.LogInformation($" message type : { inboundEvent.Type}");
            log.LogInformation($"Processing shipment for OrderId : {paymentCtx.OrderId} - Token {paymentCtx.Token}");

            string instanceId = await starter.StartNewAsync("ox_shipping_orchestrator", paymentCtx.OrderId);

            log.LogInformation($"Started orchestration with ID = '{instanceId}' OrderId '{paymentCtx.OrderId}'.");

            return;
        }
示例#27
0
        public void StructuredParseSuccess10()
        {
            var jsonFormatter = new JsonEventFormatter();
            var avroFormatter = new AvroEventFormatter();
            var cloudEventJ   = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonv10));
            var avroData      = avroFormatter.EncodeStructuredEvent(cloudEventJ, out var contentType);
            var cloudEvent    = avroFormatter.DecodeStructuredEvent(avroData);

            Assert.Equal(CloudEventsSpecVersion.V1_0, cloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", cloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
            Assert.Equal("A234-1234-1234", cloudEvent.Id);
            Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                         cloudEvent.Time.Value.ToUniversalTime());
            Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), cloudEvent.DataContentType);
            Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);

            var attr = cloudEvent.GetAttributes();

            Assert.Equal("value", (string)attr["comexampleextension1"]);
        }
示例#28
0
        public static void Run(
            [ServiceBusTrigger("q-payment-in", Connection = "SB-Queue-In-AppSettings")]
            string paymentItem,
            [ServiceBus("q-notifications", Connection = "SB-Queue-In-AppSettings")] out string notificationEventString,
            [ServiceBus("q-shipping-in", Connection = "SB-Queue-In-AppSettings")] out string outboundEventString,
            ILogger log,
            ExecutionContext context)
        {
            log.LogInformation("start fx_payment function");
            outboundEventString     = null;
            notificationEventString = null;
            byte[] messageBody;

            var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);

            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            var securityVault = new VaultService(config["Values:VaultName"]);

            var sbConnectionString = String.Empty;

            try
            {
                sbConnectionString = securityVault.GetSecret("cn-servicebus").Result;
            }
            catch (Exception)
            {
                sbConnectionString = config["Values:SB-Queue-In-AppSettings"];
            }

            try
            {
                ContentType contentType;
                var         jsonFormatter = new JsonEventFormatter();
                var         inboundEvent  = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(paymentItem));
                log.LogInformation($" message type : { inboundEvent.Type}");

                // TODO: This should be done with a DURABLE function
                // or implement compensation
                var text = new AsciiArt("payment");
                log.LogInformation(text.ToString());

                // 1. perform the payment
                var paymentCtx = JsonConvert.DeserializeObject <PaymentContext>((string)inboundEvent.Data);
                Pay(paymentCtx);
                log.LogInformation("Payment is done for {paymentCtx.Attendee}. OrderId : {paymentCtx.OrderId} - Token {paymentCtx.Token}");

                log.LogInformation(new EventId((int)LoggingContext.EventId.Processing),
                                   LoggingContext.Template,
                                   "cloud event publishing [command://order.pay]",
                                   LoggingContext.EntityType.Order.ToString(),
                                   LoggingContext.EventId.Processing.ToString(),
                                   LoggingContext.Status.Pending.ToString(),
                                   "correlationId",
                                   LoggingContext.CheckPoint.Publisher.ToString(),
                                   "long description");

                #region "command://order.update"

                // new activity introduced for better readibility in E2E dependency tree
                var requestActivity  = new Activity("command://order.update");
                var requestOperation = telemetryClient.StartOperation <RequestTelemetry>(requestActivity);
                try
                {
                    // 2. notify the change
                    var notificationEvent = new CloudEvent(
                        "command://order.update",
                        new Uri("app://ticketing.services.payment"))
                    {
                        Id          = Guid.NewGuid().ToString(),
                        ContentType = new ContentType(MediaTypeNames.Application.Json),
                        Data        = JsonConvert.SerializeObject(new ObjectStatus()
                        {
                            Id     = paymentCtx.OrderId,
                            Status = "Paid"
                        })
                    };
                    // return as string to avoid ContentType deserialization problem
                    messageBody             = jsonFormatter.EncodeStructuredEvent(notificationEvent, out contentType);
                    notificationEventString = Encoding.UTF8.GetString(messageBody);
                }
                catch (Exception ex)
                {
                    // dependency tracking
                    telemetryClient.TrackException(ex);
                    throw;
                }
                finally
                {
                    // dependency tracking
                    telemetryClient.StopOperation(requestOperation);
                }

                #endregion

                #region "command://order.deliver"
                requestActivity  = new Activity("command://order.deliver");
                requestOperation = telemetryClient.StartOperation <RequestTelemetry>(requestActivity);
                try
                {
                    // 3. trigger next step
                    var outboundEvent = new CloudEvent(
                        "command://order.deliver",
                        new Uri("app://ticketing.services.payment"))
                    {
                        Id          = Guid.NewGuid().ToString(),
                        ContentType = new ContentType(MediaTypeNames.Application.Json),
                        Data        = JsonConvert.SerializeObject(paymentCtx)
                    };
                    messageBody         = jsonFormatter.EncodeStructuredEvent(outboundEvent, out contentType);
                    outboundEventString = Encoding.UTF8.GetString(messageBody);
                }
                catch (Exception ex)
                {
                    // dependency tracking
                    telemetryClient.TrackException(ex);
                    throw;
                }
                finally
                {
                    // dependency tracking
                    telemetryClient.StopOperation(requestOperation);
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                // TODO : compensation
                var pub    = new Publisher("q-errors", sbConnectionString);
                var result = pub.SendMessagesAsync(paymentItem);
                log.LogError(ex.Message);
            }

            log.LogInformation("end function");
        }
示例#29
0
        public static async Task Run(
            [ServiceBusTrigger("q-notifications", Connection = "SB-Queue-In-AppSettings")]
            string notificationMsg,
            ILogger log,
            ExecutionContext context)
        {
            log.LogInformation("Incoming message from queue q-notifications");
            // TODO: This should be done with a DURABLE function
            // or implement compensation

            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            var sbConnectionString = config["Values:SB-Queue-In-AppSettings"];

            var jsonFormatter = new JsonEventFormatter();
            var inboundEvent  = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(notificationMsg));

            log.LogInformation($" message type : { inboundEvent.Type}");
            var     notification = JsonConvert.DeserializeObject <ObjectStatus>((string)inboundEvent.Data);
            dynamic jPatch       = new JObject();

            jPatch.op    = "replace";
            jPatch.path  = "/status";
            jPatch.value = notification.Status;
            var patchArray = new JArray(jPatch);

            log.LogInformation($" Status to be changed for the object {notification.Id}  value: { notification.Status}");
            var text = new AsciiArt(notification.Status);

            log.LogInformation(text.ToString());

            var httpContent = new StringContent(patchArray.ToString(), Encoding.UTF8, "application/json-patch+json");
            var url         = string.Format(config["Values:ApiUpdateOrderUrl"], notification.Id);

            //TODO add authentication
            //_httpClient.DefaultRequestHeaders.Authorization =new AuthenticationHeaderValue("Bearer", "to be added");

            log.LogInformation(" Call the web api ...");
            var response = await Policy
                           .HandleResult <HttpResponseMessage>(message => !message.IsSuccessStatusCode)
                           .WaitAndRetryAsync(new[]
            {
                TimeSpan.FromSeconds(1),
                TimeSpan.FromSeconds(2),
                TimeSpan.FromSeconds(5)
            }, (result, timeSpan, retryCount, ctx) =>
            {
                log.LogWarning($"Request failed with {result.Result.StatusCode}. Waiting {timeSpan} before next retry. Attempt #{retryCount}");
            })
                           .ExecuteAsync(() => _httpClient.PatchAsync(url, httpContent));

            if (!response.IsSuccessStatusCode)
            {
                var pub    = new Publisher("q-errors", sbConnectionString);
                var result = pub.SendMessagesAsync(notificationMsg);
            }

            return;
        }
示例#30
0
        private void Spigot_DataArrived(object sender, byte[] e)
        {
            var envelope = EnvelopeFormatter.DecodeStructuredEvent(e, null);

            Knobs[envelope.Type].Invoke(envelope);
        }