public Task <ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent <InputMessage> dataCloudEvent, CancellationToken token = default) { var msg = dataCloudEvent?.TypedData; Console.WriteLine(msg); return(Task.FromResult(ProcessedMessageStatus.Success)); }
public async Task StartAsync_CreateSpanAsReference_ContextIsReferenced() { PrepareQueues(); var host = GetReverseStringService(); var channel = _fixture.Connection.CreateModel(); await CreateQueueForServicePublisherWithPublisherBindingFromConfig(channel); await host.StartAsync(); var extensions = new List <ICloudEventExtension>(); var randomActivity = CreateRandomActivity(); var distributedTracingExtension = new DistributedTracingExtension(); distributedTracingExtension.SetActivity(randomActivity); extensions.Add(distributedTracingExtension); var motorCloudEvent = MotorCloudEvent.CreateTestCloudEvent(new byte[0], extensions: extensions); await PublishMessageIntoQueueOfService(channel, "12345", motorCloudEvent); var ctx = await GetActivityContextFromDestinationQueue(channel); Assert.Equal(randomActivity.Context.TraceId, ctx.TraceId); Assert.NotEqual(randomActivity.Context.SpanId, ctx.SpanId); await host.StopAsync(); }
public async Task PublishMessageAsync_WithConfig_BasicPropertiesAreSet() { var basicProperties = Mock.Of <IBasicProperties>(); var modelMock = new Mock <IModel>(); modelMock.Setup(x => x.CreateBasicProperties()).Returns(basicProperties); var rabbitConnectionFactoryMock = GetDefaultConnectionFactoryMock <string>(modelMock: modelMock, basicProperties: basicProperties); var publisher = GetPublisher(rabbitConnectionFactoryMock.Object, GetConfig()); const byte priority = 1; var activity = new Activity(nameof(RabbitMQMessagePublisherTests)); activity.SetIdFormat(ActivityIdFormat.W3C); activity.Start(); var motorCloudEvent = MotorCloudEvent.CreateTestCloudEvent(Array.Empty <byte>()); motorCloudEvent.SetActivity(activity); motorCloudEvent.SetRabbitMQPriority(priority); await publisher.PublishMessageAsync(motorCloudEvent); Assert.Equal(2, basicProperties.DeliveryMode); Assert.Equal(priority, basicProperties.Priority); var traceparent = Encoding.UTF8.GetString((byte[])basicProperties.Headers[ $"{BasicPropertiesExtensions.CloudEventPrefix}{DistributedTracingExtension.TraceParentAttribute.Name}"]); var activityContext = ActivityContext.Parse(traceparent, null); Assert.Equal(activity.Context.TraceId, activityContext.TraceId); Assert.Equal(activity.Context.SpanId, activityContext.SpanId); Assert.Equal(activity.Context.TraceFlags, activityContext.TraceFlags); }
public async Task <MotorCloudEvent <string> > ConvertMessageAsync(MotorCloudEvent <string> dataCloudEvent, CancellationToken token = default) { await Task.Delay(Timeout.InfiniteTimeSpan, token); return(dataCloudEvent); }
private async Task <ProcessedMessageStatus> SingleMessageConsumeAsync(MotorCloudEvent <byte[]> dataCloudEvent, CancellationToken token) { try { byte[] decoded; using (new AutoObserveStopwatch(() => _messageDecoding)) { decoded = await DecodeMessageAsync( dataCloudEvent.GetEncoding(), dataCloudEvent.TypedData, token); } TInput deserialized; using (new AutoObserveStopwatch(() => _messageDeserialization)) { deserialized = _deserializer.Deserialize(decoded); } return(await _queue .QueueBackgroundWorkItem(dataCloudEvent.CreateNew(deserialized, true)) .ConfigureAwait(true)); } catch (ArgumentException e) { _logger.LogError(LogEvents.InvalidInput, e, "Invalid Input"); return(ProcessedMessageStatus.InvalidInput); } catch (Exception e) { _logger.LogError(LogEvents.UnexpectedErrorOnMessageProcessing, e, "Invalid Input"); return(ProcessedMessageStatus.CriticalFailure); } }
public static Version?GetMotorVersion <TData>(this MotorCloudEvent <TData> cloudEvent) where TData : class { return(CloudEventValidation.CheckNotNull(cloudEvent, nameof(cloudEvent))[MotorVersionAttribute] is not string versionString ? null : System.Version.Parse(versionString)); }
public void UpdateAndExtractCloudEvent_V0_6_0Header_ExtensionsAddedToCloudEvent() { var channel = _fixture.Connection.CreateModel(); var basicProperties = channel.CreateBasicProperties(); var publisherOptions = new RabbitMQPublisherOptions <byte[]>(); var content = new byte[] { 1, 2, 3 }; var inputCloudEvent = MotorCloudEvent.CreateTestCloudEvent(content); var mockedApplicationNameService = Mock.Of <IApplicationNameService>(); basicProperties.SetPriority(inputCloudEvent, publisherOptions); basicProperties.WriteCloudEventIntoHeader(inputCloudEvent); // manipulate basic properties to simulate outdated version basicProperties.Headers.Remove($"{BasicPropertiesExtensions.CloudEventPrefix}{MotorVersionExtension.MotorVersionAttribute.Name}"); basicProperties.ContentEncoding = null; basicProperties.Headers.Add( $"{BasicPropertiesExtensions.CloudEventPrefix}{CloudEventsSpecVersion.V1_0.DataContentTypeAttribute.Name}", Encoding.UTF8.GetBytes($"{basicProperties.ContentType}")); foreach (var(key, value) in basicProperties.Headers) { if (value is byte[] byteValue) { basicProperties.Headers[key] = EscapeWithQuotes(byteValue); } } var outputCloudEvent = basicProperties.ExtractCloudEvent(mockedApplicationNameService, new ReadOnlyMemory <byte>(content)); Assert.Equal(MotorCloudEventInfo.RequiredAttributes(Version.Parse("0.6.0.0")).Count(), outputCloudEvent.GetPopulatedAttributes().Count()); foreach (var requiredAttribute in MotorCloudEventInfo.RequiredAttributes(Version.Parse("0.6.0.0"))) { Assert.Equal(inputCloudEvent[requiredAttribute], outputCloudEvent[requiredAttribute]); } }
public static MotorCloudEvent <TData> SetEncoding <TData>(this MotorCloudEvent <TData> cloudEvent, string?value) where TData : class { Validation.CheckNotNull(cloudEvent, nameof(cloudEvent)); cloudEvent[EncodingAttribute] = value; return(cloudEvent); }
public static void Update <T>(this IBasicProperties self, MotorCloudEvent <byte[]> cloudEvent, RabbitMQPublisherConfig <T> config, ICloudEventFormatter cloudEventFormatter) { var messagePriority = cloudEvent.Extension <RabbitMQPriorityExtension>()?.Priority ?? config.DefaultPriority; if (messagePriority.HasValue) { self.Priority = messagePriority.Value; } var dictionary = new Dictionary <string, object>(); foreach (var attr in cloudEvent.GetAttributes()) { if (string.Equals(attr.Key, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) || string.Equals(attr.Key, CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)) || string.Equals(attr.Key, RabbitMQPriorityExtension.PriorityAttributeName) || string.Equals(attr.Key, RabbitMQBindingConfigExtension.ExchangeAttributeName) || string.Equals(attr.Key, RabbitMQBindingConfigExtension.RoutingKeyAttributeName)) { continue; } dictionary.Add($"{CloudEventPrefix}{attr.Key}", cloudEventFormatter.EncodeAttribute(cloudEvent.SpecVersion, attr.Key, attr.Value, cloudEvent.GetExtensions().Values)); } self.Headers = dictionary; }
public static MotorCloudEvent <byte[]> ToMotorCloudEvent(this Message <string?, byte[]> message, IApplicationNameService applicationNameService, CloudEventFormatter cloudEventFormatter) { if (!message.IsCloudEvent()) { return(new MotorCloudEvent <byte[]>(applicationNameService, message.Value, new Uri("kafka://notset"))); } var cloudEvent = message.ToCloudEvent(cloudEventFormatter); if (cloudEvent.Data is null) { throw new ArgumentException("Data property of CloudEvent is null"); } if (cloudEvent.Source is null) { throw new ArgumentException("Source property of CloudEvent is null"); } var motorCloudEvent = new MotorCloudEvent <byte[]>(applicationNameService, (byte[])cloudEvent.Data, cloudEvent.Type, cloudEvent.Source, cloudEvent.Id, cloudEvent.Time, cloudEvent.DataContentType); foreach (var(key, value) in cloudEvent.GetPopulatedAttributes()) { if (motorCloudEvent.GetAttribute(key.Name) is null) { motorCloudEvent[key] = value; } } return(motorCloudEvent); }
public async Task Consume_PublishIntoExtensionDefinedTopic_ConsumedEqualsPublished() { var topic = randomizerString.Generate(); var message = "testMessage"; var publisher = GetPublisher <byte[]>("wrong_topic"); var motorCloudEvent = MotorCloudEvent.CreateTestCloudEvent(message).CreateNew(Encoding.UTF8.GetBytes(message)); motorCloudEvent.GetExtensionOrCreate(() => new KafkaTopicExtension(topic)); await publisher.PublishMessageAsync(motorCloudEvent, CancellationToken.None); var consumer = GetConsumer <byte[]>(topic); string id = null; var taskCompletionSource = new TaskCompletionSource(); consumer.ConsumeCallbackAsync = async(dataEvent, _) => { id = dataEvent.Id; taskCompletionSource.TrySetResult(); return(await Task.FromResult(ProcessedMessageStatus.Success)); }; await consumer.StartAsync(); var consumerStartTask = consumer.ExecuteAsync(); await Task.WhenAny(consumerStartTask, taskCompletionSource.Task); Assert.Equal(motorCloudEvent.Id, id); }
public override async Task <ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent <TInput> dataCloudEvent, CancellationToken token = default) { ProcessedMessageStatus processedMessageStatus; try { processedMessageStatus = await base.HandleMessageAsync(dataCloudEvent, token) .ConfigureAwait(false); } catch (ArgumentException ex) { _logger.LogWarning(LogEvents.InvalidInput, ex, "Invalid input (first 100 chars): {message}", dataCloudEvent.Data?.ToString()?.Take(100)); processedMessageStatus = ProcessedMessageStatus.InvalidInput; } catch (TemporaryFailureException ex) { _logger.LogError(LogEvents.ProcessingFailed, ex, "Processing failed"); processedMessageStatus = ProcessedMessageStatus.TemporaryFailure; } catch (Exception ex) { _logger.LogCritical(LogEvents.UnexpectedErrorOnMessageProcessing, ex, "Unexpected error on message processing."); processedMessageStatus = ProcessedMessageStatus.CriticalFailure; } return(processedMessageStatus); }
public async Task SingleMessageConsumeAsync_SomeEvent_PreprocessedEventAddedToQueue() { var inputMessage = new byte[] { 1, 2, 3 }; var inputEvent = MotorCloudEvent.CreateTestCloudEvent(inputMessage); var fakeDecoder = new Mock <IMessageDecoder>(); var decodedMessage = new byte[] { 4, 5, 6 }; fakeDecoder.Setup(f => f.DecodeAsync(inputMessage, It.IsAny <CancellationToken>())) .ReturnsAsync(decodedMessage); fakeDecoder.Setup(m => m.Encoding).Returns(NoOpMessageEncoder.NoEncoding); var preprocessedMessage = "test"; var fakeDeserializer = new Mock <IMessageDeserializer <string> >(); fakeDeserializer.Setup(f => f.Deserialize(decodedMessage)).Returns(preprocessedMessage); var mockQueue = new Mock <IBackgroundTaskQueue <MotorCloudEvent <string> > >(); var fakeMessageConsumer = new Mock <IMessageConsumer <string> >(); fakeMessageConsumer.SetupProperty(p => p.ConsumeCallbackAsync); CreateConsumerService(mockQueue.Object, fakeDeserializer.Object, fakeDecoder.Object, fakeMessageConsumer.Object); await fakeMessageConsumer.Object.ConsumeCallbackAsync?.Invoke(inputEvent, CancellationToken.None) !; mockQueue.Verify(m => m.QueueBackgroundWorkItem( It.Is <MotorCloudEvent <string> >(cloudEvent => cloudEvent.TypedData == preprocessedMessage))); }
public async Task <ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent <TInput> dataCloudEvent, CancellationToken token = default) { try { using (new AutoObserveStopwatch(() => _messageProcessing)) { await foreach (var message in _converter.ConvertMessageAsync(dataCloudEvent, token) .ConfigureAwait(false).WithCancellation(token)) { if (message?.Data is not null) { await _publisher.PublishMessageAsync(message, token) .ConfigureAwait(false); } } } return(ProcessedMessageStatus.Success); } catch (ArgumentException) { throw; } catch (Exception e) { _logger.LogError(LogEvents.ProcessingFailed, e, "Processing failed."); return(ProcessedMessageStatus.TemporaryFailure); } }
public async Task <MotorCloudEvent <string>?> ConvertMessageAsync(MotorCloudEvent <string> dataCloudEvent, CancellationToken token = default) { await Task.Delay(Timeout.InfiniteTimeSpan, token).ConfigureAwait(false); return(dataCloudEvent.CreateNew(string.Empty)); }
public async Task <IEnumerable <MotorCloudEvent <TOutput> > > ConvertMessageAsync( MotorCloudEvent <TInput> dataCloudEvent, CancellationToken token) { var convertMessage = await _service.ConvertMessageAsync(dataCloudEvent, token) .ConfigureAwait(false); return(convertMessage == null ? new MotorCloudEvent <TOutput> [0] : new[] { convertMessage }); }
public static MotorCloudEvent <TData> SetRabbitMQBinding <TData>(this MotorCloudEvent <TData> cloudEvent, string?exchange, string?routingKey) where TData : class { CloudEventValidation.CheckNotNull(cloudEvent, nameof(cloudEvent)); cloudEvent[RabbitMQExchangeAttribute] = exchange; cloudEvent[RabbitMQRoutingKeyAttribute] = routingKey; return(cloudEvent); }
private static MotorCloudEvent <byte[]> CreateMotorCloudEventWithEncoding(string encoding, byte[]?inputMessage = null) { var cloudEvent = MotorCloudEvent.CreateTestCloudEvent(inputMessage ?? Array.Empty <byte>()); cloudEvent.SetEncoding(encoding); return(cloudEvent); }
public static MotorCloudEvent <byte[]> ToMotorCloudEvent(this string message, IApplicationNameService applicationNameService) { var motorCloudEvent = new MotorCloudEvent <byte[]>(applicationNameService, Encoding.UTF8.GetBytes(message), new Uri("sqs://notset")); return(motorCloudEvent); }
public static MotorCloudEvent <byte[]> ToMotorCloudEvent(this byte[] message, IApplicationNameService applicationNameService) { var motorCloudEvent = new MotorCloudEvent <byte[]>(applicationNameService, message, new Uri("nats://notset")); return(motorCloudEvent); }
public static byte?GetRabbitMQPriority <TData>(this MotorCloudEvent <TData> cloudEvent) where TData : class { return(CloudEventValidation.CheckNotNull(cloudEvent, nameof(cloudEvent))[RabbitMQPriorityAttribute] switch { int and(< 0 or > 255) => null, int priority => (byte)priority, _ => null });
public static MotorCloudEvent <TData> SetMotorVersion <TData>(this MotorCloudEvent <TData> cloudEvent) where TData : class { CloudEventValidation.CheckNotNull(cloudEvent, nameof(cloudEvent)); cloudEvent[MotorVersionAttribute] = CurrentVersion ?? throw new InvalidOperationException("Motor.NET version is undefined."); return(cloudEvent); }
public override async Task <ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent <TInput> dataCloudEvent, CancellationToken token = default) { var processedMessageStatus = await base.HandleMessageAsync(dataCloudEvent, token).ConfigureAwait(false); await _statistics.RegisterMessageStatusAsync(processedMessageStatus).ConfigureAwait(false); return(processedMessageStatus); }
public static void SetActivity <TData>(this MotorCloudEvent <TData> cloudEvent, Activity activity) where TData : class { Validation.CheckNotNull(cloudEvent, nameof(cloudEvent)); cloudEvent[TraceParentAttribute] = activity.Id; if (!string.IsNullOrWhiteSpace(activity.TraceStateString)) { cloudEvent[TraceStateAttribute] = activity.TraceStateString; } }
public async Task PublishMessageAsync_WithConfig_ChannelEstablished() { var rabbitConnectionFactoryMock = GetDefaultConnectionFactoryMock <string>(); var publisher = GetPublisher(rabbitConnectionFactoryMock.Object, GetConfig()); await publisher.PublishMessageAsync(MotorCloudEvent.CreateTestCloudEvent(Array.Empty <byte>())); rabbitConnectionFactoryMock.Verify(x => x.CurrentChannel, Times.Exactly(1)); }
public virtual Task <ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent <TInput> dataCloudEvent, CancellationToken token = default) { if (InnerService is null) { throw new IndexOutOfRangeException("No message handler was set."); } return(InnerService.HandleMessageAsync(dataCloudEvent, token)); }
public async Task PublishMessageAsync_WithConfig_ConnectionFactoryIsSet() { var mock = GetDefaultConnectionFactoryMock(); var config = GetConfig(); var publisher = GetPublisher(mock.Object, config); await publisher.PublishMessageAsync(MotorCloudEvent.CreateTestCloudEvent(new byte [0])); mock.Verify(x => x.From(config), Times.Exactly(1)); }
public async Task PublishMessageAsync_WithConfig_ChannelEstablished() { var connectionMock = new Mock <IConnection>(); var rabbitConnectionFactoryMock = GetDefaultConnectionFactoryMock(connectionMock: connectionMock); var publisher = GetPublisher(rabbitConnectionFactoryMock.Object, GetConfig()); await publisher.PublishMessageAsync(MotorCloudEvent.CreateTestCloudEvent(new byte[0])); connectionMock.Verify(x => x.CreateModel(), Times.Exactly(1)); }
public Task <MotorCloudEvent <string> > ConvertMessageAsync(MotorCloudEvent <string> dataCloudEvent, CancellationToken token = default) { _logger.LogInformation("log your request"); var tmpChar = dataCloudEvent.TypedData.ToCharArray(); var reversed = tmpChar.Reverse().ToArray(); _summary.WithLabels("collect_your_metrics").Observe(1.0); return(Task.FromResult(dataCloudEvent.CreateNew(new string(reversed)))); }
public async Task PublishMessageAsync_WithConfig_BasicPropertiesAreCreated() { var modelMock = new Mock <IModel>(); var rabbitConnectionFactoryMock = GetDefaultConnectionFactoryMock <string>(modelMock: modelMock); var publisher = GetPublisher(rabbitConnectionFactoryMock.Object, GetConfig()); await publisher.PublishMessageAsync(MotorCloudEvent.CreateTestCloudEvent(Array.Empty <byte>())); modelMock.Verify(x => x.CreateBasicProperties(), Times.Exactly(1)); }