public async Task Should_allow_reconfiguration() { IRequestClient <SetConcurrencyLimit, ConcurrencyLimitUpdated> client = new PublishRequestClient <SetConcurrencyLimit, ConcurrencyLimitUpdated>(Bus, TestTimeout); SetConcurrencyLimit request = TypeMetadataCache <SetConcurrencyLimit> .InitializeFromObject(new { ConcurrencyLimit = 16, Timestamp = DateTime.UtcNow }); await client.Request(request, TestCancellationToken); }
public void ConfigureConsumer <T>(IReceiveEndpointConfigurator configurator, Action <IConsumerConfigurator <T> > configure) where T : class, IConsumer { if (!Consumers.TryGetValue(typeof(T), out var consumer)) { throw new ArgumentException($"The consumer type was not found: {TypeMetadataCache.GetShortName(typeof(T))}", nameof(T)); } consumer.AddConfigureAction(configure); consumer.Configure(configurator, this); _configuredTypes.Add(typeof(T)); }
static IConsumeObserverConverter CreateConverter(Type type) { if (type.ClosesType(typeof(ConsumeContext <>))) { var messageType = type.GetClosingArguments(typeof(ConsumeContext <>)).Single(); var converterType = typeof(ConsumeObserverConverter <>).MakeGenericType(messageType); return((IConsumeObserverConverter)Activator.CreateInstance(converterType)); } throw new ArgumentException($"The context was not a ConsumeContext: {TypeMetadataCache.GetShortName(type)}", nameof(type)); }
public void ConfigureSaga <T>(IReceiveEndpointConfigurator configurator, Action <ISagaConfigurator <T> > configure) where T : class, ISaga { if (!Sagas.TryGetValue(typeof(T), out var saga)) { throw new ArgumentException($"The saga type was not found: {TypeMetadataCache.GetShortName(typeof(T))}", nameof(T)); } saga.AddConfigureAction(configure); saga.Configure(configurator, this); _configuredTypes.Add(typeof(T)); }
Task IPublishEndpoint.Publish <T>(object values, CancellationToken cancellationToken) { if (values == null) { throw new ArgumentNullException(nameof(values)); } var message = TypeMetadataCache <T> .InitializeFromObject(values); var adapter = new PublishPipeContextAdapter <T>(_publishPipe, _publishObserver, _sourceAddress, _consumeContext, message); return(Publish(cancellationToken, message, adapter)); }
/// <summary> /// Send a message /// </summary> /// <param name="provider"></param> /// <param name="message">The message</param> /// <param name="messageType"></param> /// <param name="cancellationToken"></param> /// <returns>The task which is completed once the Send is acknowledged by the broker</returns> public static async Task Send(this ISendEndpointProvider provider, object message, Type messageType, CancellationToken cancellationToken = default(CancellationToken)) { Uri destinationAddress; if (!EndpointConvention.TryGetDestinationAddress(message, out destinationAddress)) { throw new ArgumentException($"A convention for the message type {TypeMetadataCache.GetShortName(messageType)} was not found"); } var endpoint = await provider.GetSendEndpoint(destinationAddress).ConfigureAwait(false); await endpoint.Send(message, messageType, cancellationToken).ConfigureAwait(false); }
public async Task Should_be_faster_than_json() { var now = DateTime.UtcNow; var inputObject = new { StringValue = "Hello", IntValue = 27, DateTimeValue = now, NullableValue = 42, NotNullableValue = (int?)69, NullableDecimalValue = 123.45m, Numbers = new[] { 12, 24, 36 }, Names = new[] { "Curly", "Larry", "Moe" }, Exception = new IntentionalTestException("It Happens"), SubValue = new { Text = "Mary" }, SubValues = new object[] { new { Text = "Frank" }, new { Text = "Lola" }, }, Amount = 867.53m, // AsyncValue = GetIntResult().Select(x => x.Number), EngineStatus = Status.Started, NumberStatus = 12, StringStatus = "Started", // Strings = new Dictionary<string, string> {{"Hello", "World"}, {"Thank You", "Next"}} }; var context = await MessageInitializerCache <SuperComplexRequest> .Initialize(inputObject); var timer = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { context = await MessageInitializerCache <SuperComplexRequest> .Initialize(inputObject); } timer.Stop(); var message = TypeMetadataCache <SuperComplexRequest> .InitializeFromObject(inputObject); var jsonTimer = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { message = TypeMetadataCache <SuperComplexRequest> .InitializeFromObject(inputObject); } jsonTimer.Stop(); Console.WriteLine("Initializer: {0}", timer.ElapsedMilliseconds); Console.WriteLine("JsonMessage: {0}", jsonTimer.ElapsedMilliseconds); }
Task IPublishEndpointConverter.Publish(IPublishEndpoint endpoint, object message, IPipe<PublishContext> pipe, CancellationToken cancellationToken) { if (endpoint == null) throw new ArgumentNullException(nameof(endpoint)); if (message == null) throw new ArgumentNullException(nameof(message)); if (pipe == null) throw new ArgumentNullException(nameof(pipe)); if (message is T msg) return endpoint.Publish(msg, pipe, cancellationToken); throw new ArgumentException("Unexpected message type: " + TypeMetadataCache.GetShortName(message.GetType())); }
bool IsHostBusFactoryType(Type type) { foreach (var interfaceType in type.GetInterfaces()) { var name = TypeMetadataCache.GetShortName(interfaceType); if (name.Equals(_hostBusFactoryTypeName, StringComparison.InvariantCultureIgnoreCase)) { return(true); } } return(false); }
/// <summary> /// Send a message /// </summary> /// <typeparam name="T">The message type</typeparam> /// <param name="provider"></param> /// <param name="values"></param> /// <param name="cancellationToken"></param> /// <returns>The task which is completed once the Send is acknowledged by the broker</returns> public static async Task Send <T>(this ISendEndpointProvider provider, object values, CancellationToken cancellationToken = default) where T : class { var message = TypeMetadataCache <T> .InitializeFromObject(values); if (!EndpointConvention.TryGetDestinationAddress <T>(out var destinationAddress)) { throw new ArgumentException($"A convention for the message type {TypeMetadataCache<T>.ShortName} was not found"); } var endpoint = await provider.GetSendEndpoint(destinationAddress).ConfigureAwait(false); await endpoint.Send(message, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Sends an interface message, initializing the properties of the interface using the anonymous /// object specified /// </summary> /// <typeparam name="T">The interface type to send</typeparam> /// <param name="context">The consume context</param> /// <param name="scheduledTime">The time at which the message should be delivered to the queue</param> /// <param name="values">The property values to initialize on the interface</param> /// <param name="pipe"></param> /// <param name="cancellationToken"></param> /// <returns>The task which is completed once the Send is acknowledged by the broker</returns> public static Task <ScheduledMessage <T> > SchedulePublish <T>(this ConsumeContext context, DateTime scheduledTime, object values, IPipe <SendContext> pipe, CancellationToken cancellationToken = default(CancellationToken)) where T : class { if (values == null) { throw new ArgumentNullException(nameof(values)); } var pipeProxy = new ServiceBusScheduleMessagePipe <T>(scheduledTime, pipe); var message = TypeMetadataCache <T> .InitializeFromObject(values); return(Schedule(context, scheduledTime, message, pipeProxy, cancellationToken)); }
Task <ScheduledMessage <T> > IMessageScheduler.ScheduleSend <T>(Uri destinationAddress, DateTime scheduledTime, object values, CancellationToken cancellationToken) { if (destinationAddress == null) { throw new ArgumentNullException(nameof(destinationAddress)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } var message = TypeMetadataCache <T> .InitializeFromObject(values); return(ScheduleSend(destinationAddress, scheduledTime, message, Pipe.Empty <SendContext <T> >(), cancellationToken)); }
static IMessageFactory CreateMessageFactory(Type contractType) { if (!TypeMetadataCache.IsValidMessageType(contractType)) { throw new ArgumentException(nameof(contractType)); } Type[] parameterTypes = new Type[0]; if (contractType.GetConstructor(parameterTypes) == null) { throw new ArgumentException("No default constructor available for message type", nameof(contractType)); } return((IMessageFactory)Activator.CreateInstance(typeof(DynamicMessageFactory <>).MakeGenericType(contractType))); }
public Uri GetDestinationAddress(Type messageType, Action <ITopicConfigurator> configure = null) { var isTemporary = TypeMetadataCache.IsTemporaryMessageType(messageType); var durable = !isTemporary; var autoDelete = isTemporary; var name = _messageNameFormatter.GetMessageName(messageType).ToString(); var settings = new TopicSendSettings(name, durable, autoDelete); configure?.Invoke(settings); return(settings.GetSendAddress(_hostAddress)); }
public Uri GetDestinationAddress(Type messageType, Action <IQueueConfigurator> configure = null) { var queueName = _messageNameFormatter.GetMessageName(messageType).ToString(); var configurator = new QueueConfigurator(queueName); if (TypeMetadataCache.IsTemporaryMessageType(messageType)) { configurator.AutoDeleteOnIdle = Defaults.TemporaryAutoDeleteOnIdle; } configure?.Invoke(configurator); return(configurator.GetQueueAddress(_hostAddress)); }
public FaultExceptionInfo(Exception exception) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } ExceptionType = TypeMetadataCache.GetShortName(exception.GetType()); InnerException = exception.InnerException != null ? new FaultExceptionInfo(exception.InnerException) : null; StackTrace = ExceptionUtil.GetStackTrace(exception); Message = ExceptionUtil.GetMessage(exception); Source = exception.Source; }
/// <summary> /// Adds all consumers in the specified assemblies matching the namespace /// </summary> /// <param name="configurator"></param> /// <param name="type">The type to use to identify the assembly and namespace to scan</param> public static void AddConsumersFromNamespaceContaining(this IRegistrationConfigurator configurator, Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (type.Assembly == null || type.Namespace == null) { throw new ArgumentException($"The type {TypeMetadataCache.GetShortName(type)} is not in an assembly with a valid namespace", nameof(type)); } IEnumerable <Type> types = FindTypesInNamespace(type, IsConsumerOrDefinition); AddConsumers(configurator, types.ToArray()); }
public Task Send <T>(object values, IPipe <SendContext> pipe, CancellationToken cancellationToken) where T : class { if (values == null) { throw new ArgumentNullException(nameof(values)); } if (pipe == null) { throw new ArgumentNullException(nameof(pipe)); } T message = TypeMetadataCache <T> .InitializeFromObject(values); return(Send(message, pipe, cancellationToken)); }
Task <ScheduledRecurringMessage <T> > IRecurringMessageScheduler.ScheduleRecurringSend <T>(Uri destinationAddress, RecurringSchedule schedule, object values, CancellationToken cancellationToken) { if (destinationAddress == null) { throw new ArgumentNullException(nameof(destinationAddress)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } var message = TypeMetadataCache <T> .InitializeFromObject(values); return(ScheduleRecurringSend(destinationAddress, schedule, message, cancellationToken)); }
public void Should_property_initialize_the_values() { var values = new { CorrelationId = Guid.NewGuid(), Name = "Dru", Timestamp = DateTime.UtcNow, }; IMessageType message = TypeMetadataCache <IMessageType> .InitializeFromObject(values); message.CorrelationId.ShouldBe(values.CorrelationId); message.Name.ShouldBe(values.Name); message.Timestamp.ShouldBe(values.Timestamp); }
static CachedRegistration Factory(Type activityType) { if (!activityType.HasInterface(typeof(IExecuteActivity <>))) { throw new ArgumentException($"The type is not an execute activity: {TypeMetadataCache.GetShortName(activityType)}", nameof(activityType)); } if (activityType.HasInterface(typeof(ICompensateActivity <>))) { throw new ArgumentException($"The type is an activity, which supports compensation: {TypeMetadataCache.GetShortName(activityType)}", nameof(activityType)); } var argumentType = activityType.GetClosingArguments(typeof(IExecuteActivity <>)).Single(); return((CachedRegistration)Activator.CreateInstance(typeof(CachedRegistration <,>).MakeGenericType(activityType, argumentType))); }
Task <ScheduledMessage <T> > IMessageScheduler.ScheduleSend <T>(Uri destinationAddress, DateTime scheduledTime, object values, CancellationToken cancellationToken = default(CancellationToken)) { if (destinationAddress == null) { throw new ArgumentNullException(nameof(destinationAddress)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } var message = TypeMetadataCache <T> .InitializeFromObject(values); var pipeProxy = new ServiceBusScheduleMessagePipe <T>(scheduledTime); return(ScheduleSend(destinationAddress, scheduledTime, message, pipeProxy, cancellationToken)); }
Task <ISendEndpoint> CreateSendEndpoint(Type messageType) { SendSettings sendSettings = _host.GetSendSettings(messageType); ExchangeBindingSettings[] bindings = TypeMetadataCache.GetMessageTypes(messageType) .SelectMany(type => type.GetExchangeBindings(_host.MessageNameFormatter)) .Where(binding => !sendSettings.ExchangeName.Equals(binding.Exchange.ExchangeName)) .ToArray(); Uri destinationAddress = _host.Settings.GetSendAddress(sendSettings); var modelCache = new RabbitMqModelCache(_host.ConnectionCache); var sendTransport = new RabbitMqSendTransport(modelCache, sendSettings, bindings); return(Task.FromResult <ISendEndpoint>(new SendEndpoint(sendTransport, _serializer, destinationAddress, _sourceAddress, SendPipe.Empty))); }
/// <summary> /// Sends an interface message, initializing the properties of the interface using the anonymous /// object specified /// </summary> /// <typeparam name="T">The interface type to send</typeparam> /// <param name="context">The consume context</param> /// <param name="scheduledTime">The time at which the message should be delivered to the queue</param> /// <param name="values">The property values to initialize on the interface</param> /// <param name="pipe"></param> /// <param name="cancellationToken"></param> /// <returns>The task which is completed once the Send is acknowledged by the broker</returns> public static Task <ScheduledMessage <T> > SchedulePublish <T>(this ConsumeContext context, DateTime scheduledTime, object values, IPipe <SendContext> pipe, CancellationToken cancellationToken = default(CancellationToken)) where T : class { if (values == null) { throw new ArgumentNullException(nameof(values)); } var message = TypeMetadataCache <T> .InitializeFromObject(values); var destinationAddress = GetDestinationAddress <T>(context); var scheduler = context.GetPayload <MessageSchedulerContext>(); return(scheduler.ScheduleSend(destinationAddress, scheduledTime, message, pipe, cancellationToken)); }
void IRegistrationConfigurator.AddConsumer(Type consumerType, Type consumerDefinitionType) { if (TypeMetadataCache.HasSagaInterfaces(consumerType)) throw new ArgumentException($"{TypeMetadataCache.GetShortName(consumerType)} is a saga, and cannot be registered as a consumer", nameof(consumerType)); IConsumerRegistration ValueFactory(Type type) { ConsumerRegistrationCache.Register(type, _containerRegistrar); if (consumerDefinitionType != null) ConsumerDefinitionRegistrationCache.Register(consumerDefinitionType, _containerRegistrar); return (IConsumerRegistration)Activator.CreateInstance(typeof(ConsumerRegistration<>).MakeGenericType(type)); } _consumerRegistrations.GetOrAdd(consumerType, ValueFactory); }
public Uri GetDestinationAddress(Type messageType, Action <ITopicConfigurator> configure = null) { var isTemporary = TypeMetadataCache.IsTemporaryMessageType(messageType); _topologyConfiguration.Publish.TryGetPublishAddress(messageType, _hostConfiguration.HostAddress, out var address); var settings = new TopicSendSettings(new ActiveMqEndpointAddress(_hostConfiguration.HostAddress, address)); if (isTemporary) { settings.AutoDelete = true; settings.Durable = false; } configure?.Invoke(settings); return(settings.GetSendAddress(_hostConfiguration.HostAddress)); }
Task ISendEndpointConverter.Send(ISendEndpoint endpoint, object message, CancellationToken cancellationToken) { if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message is T msg) { return(endpoint.Send(msg, cancellationToken)); } throw new ArgumentException("Unexpected message type: " + TypeMetadataCache.GetShortName(message.GetType())); }
Task IResponseEndpointConverter.Respond(ConsumeContext consumeContext, object message) { if (consumeContext == null) { throw new ArgumentNullException(nameof(consumeContext)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message is T msg) { return(consumeContext.RespondAsync(msg)); } throw new ArgumentException("Unexpected message type: " + TypeMetadataCache.GetShortName(message.GetType())); }
public async Task Should_be_faster_than_json() { var inputObject = new { StringValue = _stringValue, BoolValue = _boolValue, ByteValue = _byteValue, ShortValue = _shortValue, IntValue = _intValue, LongValue = _longValue, DoubleValue = _doubleValue, DecimalValue = _decimalValue, DateTimeValue = _dateTimeValue, DateTimeOffsetValue = _dateTimeOffsetValue, TimeSpanValue = _timeSpanValue, DayValue = _dayValue, ObjectValue = _objectValue, }; var context = await MessageInitializerCache <TestInitializerMessage> .Initialize(inputObject); var timer = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { context = await MessageInitializerCache <TestInitializerMessage> .Initialize(inputObject); } timer.Stop(); var message = TypeMetadataCache <TestInitializerMessage> .InitializeFromObject(inputObject); var jsonTimer = Stopwatch.StartNew(); for (int i = 0; i < 100000; i++) { message = TypeMetadataCache <TestInitializerMessage> .InitializeFromObject(inputObject); } jsonTimer.Stop(); Console.WriteLine("Initializer: {0}", timer.ElapsedMilliseconds); Console.WriteLine("JsonMessage: {0}", jsonTimer.ElapsedMilliseconds); }
public async Task <ScheduledMessage> ScheduleSend(IMessageScheduler scheduler, Uri destinationAddress, DateTime scheduledTime, object message, CancellationToken cancellationToken = default) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message is T msg) { return(await scheduler.ScheduleSend(destinationAddress, scheduledTime, msg, cancellationToken).ConfigureAwait(false)); } throw new ArgumentException("Unexpected message type: " + TypeMetadataCache.GetShortName(message.GetType())); }