コード例 #1
0
        async Task SendSubscribeMessageWithRetries(string destination, OutgoingMessage subscriptionMessage, string messageType, ContextBag context, int retriesCount = 0)
        {
            var state = context.GetOrCreate <Settings>();

            try
            {
                var transportOperation   = new TransportOperation(subscriptionMessage, new UnicastAddressTag(destination));
                var transportTransaction = context.GetOrCreate <TransportTransaction>();
                await dispatcher.Dispatch(new TransportOperations(transportOperation), transportTransaction, context).ConfigureAwait(false);
            }
            catch (QueueNotFoundException ex)
            {
                if (retriesCount < state.MaxRetries)
                {
                    await Task.Delay(state.RetryDelay).ConfigureAwait(false);
                    await SendSubscribeMessageWithRetries(destination, subscriptionMessage, messageType, context, ++retriesCount).ConfigureAwait(false);
                }
                else
                {
                    var message = $"Failed to subscribe to {messageType} at publisher queue {destination}, reason {ex.Message}";
                    Logger.Error(message, ex);
                    throw new QueueNotFoundException(destination, message, ex);
                }
            }
        }
コード例 #2
0
        public override async Task <IContainSagaData> Find(IServiceProvider builder, SagaFinderDefinition finderDefinition, SynchronizedStorageSession storageSession, ContextBag context, object message, IReadOnlyDictionary <string, string> messageHeaders, CancellationToken cancellationToken = default)
        {
            var propertyAccessor = (Func <object, object>)finderDefinition.Properties["property-accessor"];
            var propertyValue    = propertyAccessor(message);

            var sagaPropertyName = (string)finderDefinition.Properties["saga-property-name"];

            var lookupValues = context.GetOrCreate <SagaLookupValues>();

            lookupValues.Add <TSagaData>(sagaPropertyName, propertyValue);

            if (propertyValue == null)
            {
                var saga           = context.Get <ActiveSagaInstance>();
                var sagaEntityName = saga.Metadata.Name;
                var messageName    = finderDefinition.MessageTypeName;

                throw new Exception($"Message {messageName} mapped to saga {sagaEntityName} has attempted to assign null to the correlation property {sagaPropertyName}. Correlation properties cannot be assigned null.");
            }

            if (sagaPropertyName.ToLower() == "id")
            {
                return(await sagaPersister.Get <TSagaData>((Guid)propertyValue, storageSession, context, cancellationToken).ConfigureAwait(false));
            }

            return(await sagaPersister.Get <TSagaData>(sagaPropertyName, propertyValue, storageSession, context, cancellationToken).ConfigureAwait(false));
        }
コード例 #3
0
        async Task <CompletableSynchronizedStorageSession> OpenSession(ContextBag context)
        {
            var transportTransaction = context.GetOrCreate <TransportTransaction>();
            var session = await transportTransactionAdapter.TryAdapt(transportTransaction, context).ConfigureAwait(false)
                          ?? await synchronizedStorage.OpenSession(context).ConfigureAwait(false);

            return(session);
        }
コード例 #4
0
        public override async Task <IContainSagaData> Find(IServiceProvider builder, SagaFinderDefinition finderDefinition, SynchronizedStorageSession storageSession, ContextBag context, object message, IReadOnlyDictionary <string, string> messageHeaders, CancellationToken cancellationToken)
        {
            var headerName = (string)finderDefinition.Properties["message-header-name"];

            if (!messageHeaders.TryGetValue(headerName, out var messageHeaderValue))
            {
                var saga           = context.Get <ActiveSagaInstance>();
                var sagaEntityName = saga.Metadata.Name;
                var messageName    = finderDefinition.MessageTypeName;

                throw new Exception($"Message {messageName} mapped to saga {sagaEntityName} is missing a header used for correlation: {headerName}.");
            }

            var correlationPropertyName = (string)finderDefinition.Properties["saga-property-name"];
            var correlationPropertyType = (Type)finderDefinition.Properties["saga-property-type"];

            object convertedHeaderValue;

            try
            {
                convertedHeaderValue = TypeDescriptor.GetConverter(correlationPropertyType).ConvertFromInvariantString(messageHeaderValue);
            }
            catch (Exception exception)
            {
                var saga           = context.Get <ActiveSagaInstance>();
                var sagaEntityName = saga.Metadata.Name;
                var messageName    = finderDefinition.MessageTypeName;

                throw new Exception($"Message {messageName} mapped to saga {sagaEntityName} contains correlation header {headerName} value that cannot be cast to correlation property type {correlationPropertyType}: {messageHeaderValue}", exception);
            }

            var lookupValues = context.GetOrCreate <SagaLookupValues>();

            lookupValues.Add <TSagaData>(correlationPropertyName, convertedHeaderValue);

            if (convertedHeaderValue == null)
            {
                var saga           = context.Get <ActiveSagaInstance>();
                var sagaEntityName = saga.Metadata.Name;
                var messageName    = finderDefinition.MessageTypeName;

                throw new Exception($"Message {messageName} mapped to saga {sagaEntityName} has attempted to assign null to the correlation property {correlationPropertyName}. Correlation properties cannot be assigned null.");
            }

            if (correlationPropertyName.ToLower() == "id")
            {
                return(await persister.Get <TSagaData>((Guid)convertedHeaderValue, storageSession, context, cancellationToken).ConfigureAwait(false));
            }

            return(await persister.Get <TSagaData>(correlationPropertyName, convertedHeaderValue, storageSession, context, cancellationToken).ConfigureAwait(false));
        }
コード例 #5
0
        static TSagaData Resolve <TSagaData>(byte[] data, ContextBag context)
            where TSagaData : IContainSagaData
        {
            var serializer = new DataContractSerializer(typeof(TSagaData));

            using (var ms = new MemoryStream(data))
            {
                var saga = (TSagaData)serializer.ReadObject(ms);

                context.GetOrCreate <Metadata>().SagaData[saga.Id] = data;

                return(saga);
            }
        }
コード例 #6
0
        public override async Task <IContainSagaData> Find(IBuilder builder, SagaFinderDefinition finderDefinition, SynchronizedStorageSession storageSession, ContextBag context, object message)
        {
            var propertyAccessor = (Func <object, object>)finderDefinition.Properties["property-accessor"];
            var propertyValue    = propertyAccessor(message);

            var sagaPropertyName = (string)finderDefinition.Properties["saga-property-name"];

            if (sagaPropertyName.ToLower() == "id")
            {
                return(await sagaPersister.Get <TSagaData>((Guid)propertyValue, storageSession, context).ConfigureAwait(false));
            }

            var lookupValues = context.GetOrCreate <SagaLookupValues>();

            lookupValues.Add <TSagaData>(sagaPropertyName, propertyValue);

            return(await sagaPersister.Get <TSagaData>(sagaPropertyName, propertyValue, storageSession, context).ConfigureAwait(false));
        }