public void ConsumptionDefaulstDoNotOverrideCustomerOptions()
        {
            var connectionStringResolver = new TestConnectionStringResolver();
            var options = new DurableTaskOptions();

            options.StorageProvider.Add("ControlQueueBufferThreshold", 999);
            options.MaxConcurrentOrchestratorFunctions = 888;
            options.MaxConcurrentActivityFunctions     = 777;

            var mockOptions  = new OptionsWrapper <DurableTaskOptions>(options);
            var nameResolver = new Mock <INameResolver>().Object;
            var factory      = new AzureStorageDurabilityProviderFactory(
                mockOptions,
                connectionStringResolver,
                nameResolver,
                NullLoggerFactory.Instance,
                TestHelpers.GetMockPlatformInformationService(inConsumption: true));

            var settings = factory.GetAzureStorageOrchestrationServiceSettings();

            // We want to make sure that the consumption defaults (listed below)
            // aren't applied on non-consumption plans.
            Assert.Equal(999, settings.ControlQueueBufferThreshold);
            Assert.Equal(888, settings.MaxConcurrentTaskOrchestrationWorkItems);
            Assert.Equal(777, settings.MaxConcurrentTaskActivityWorkItems);
        }
        private static DurableTaskExtension GetDurableTaskConfig()
        {
            var options = new DurableTaskOptions();

            options.HubName = "DurableTaskHub";
            options.WebhookUriProviderOverride = () => new Uri("https://sampleurl.net");
            var wrappedOptions             = new OptionsWrapper <DurableTaskOptions>(options);
            var nameResolver               = TestHelpers.GetTestNameResolver();
            var connectionStringResolver   = new TestConnectionStringResolver();
            var platformInformationService = TestHelpers.GetMockPlatformInformationService();
            var serviceFactory             = new AzureStorageDurabilityProviderFactory(
                wrappedOptions,
                connectionStringResolver,
                nameResolver,
                NullLoggerFactory.Instance,
                platformInformationService);

            return(new DurableTaskExtension(
                       wrappedOptions,
                       new LoggerFactory(),
                       nameResolver,
                       new[] { serviceFactory },
                       new TestHostShutdownNotificationService(),
                       new DurableHttpMessageHandlerFactory(),
                       platformInformationService: platformInformationService));
        }
Beispiel #3
0
        private static DurableTaskExtension GetTestExtension()
        {
            var options = new DurableTaskOptions();

            options.NotificationUrl = new Uri(TestConstants.NotificationUrl);

            return(GetTestExtension(options));
        }
Beispiel #4
0
 public MockDurableTaskExtension(DurableTaskOptions options)
     : base(
         new OptionsWrapper <DurableTaskOptions>(options),
         new LoggerFactory(),
         TestHelpers.GetTestNameResolver(),
         new TestConnectionStringResolver())
 {
 }
 internal FunctionsV2HostWrapper(
     IHost innerHost,
     IOptions <DurableTaskOptions> options)
 {
     this.innerHost        = innerHost;
     this.innerWebJobsHost = (JobHost)this.innerHost.Services.GetService <IJobHost>();
     this.options          = options.Value;
 }
        public static JobHost GetJobHost(
            ILoggerProvider loggerProvider,
            string testName,
            bool enableExtendedSessions,
            string eventGridKeySettingName  = null,
            INameResolver nameResolver      = null,
            string eventGridTopicEndpoint   = null,
            int?eventGridRetryCount         = null,
            TimeSpan?eventGridRetryInterval = null,
            int[] eventGridRetryHttpStatus  = null,
            bool logReplayEvents            = true,
            Uri notificationUrl             = null,
            HttpMessageHandler eventGridNotificationHandler = null,
            TimeSpan?maxQueuePollingInterval    = null,
            string[] eventGridPublishEventTypes = null,
            bool autoFetchLargeMessages         = true)
        {
            var durableTaskOptions = new DurableTaskOptions
            {
                HubName = GetTaskHubNameFromTestName(testName, enableExtendedSessions),
                TraceInputsAndOutputs              = true,
                EventGridKeySettingName            = eventGridKeySettingName,
                EventGridTopicEndpoint             = eventGridTopicEndpoint,
                ExtendedSessionsEnabled            = enableExtendedSessions,
                MaxConcurrentOrchestratorFunctions = 200,
                MaxConcurrentActivityFunctions     = 200,
                LogReplayEvents                 = logReplayEvents,
                NotificationUrl                 = notificationUrl,
                NotificationHandler             = eventGridNotificationHandler,
                EventGridPublishEventTypes      = eventGridPublishEventTypes,
                FetchLargeMessagesAutomatically = autoFetchLargeMessages,
            };

            if (eventGridRetryCount.HasValue)
            {
                durableTaskOptions.EventGridPublishRetryCount = eventGridRetryCount.Value;
            }

            if (eventGridRetryInterval.HasValue)
            {
                durableTaskOptions.EventGridPublishRetryInterval = eventGridRetryInterval.Value;
            }

            if (eventGridRetryHttpStatus != null)
            {
                durableTaskOptions.EventGridPublishRetryHttpStatus = eventGridRetryHttpStatus;
            }

            if (maxQueuePollingInterval != null)
            {
                durableTaskOptions.MaxQueuePollingInterval = maxQueuePollingInterval.Value;
            }

            var optionsWrapper   = new OptionsWrapper <DurableTaskOptions>(durableTaskOptions);
            var testNameResolver = new TestNameResolver(nameResolver);

            return(PlatformSpecificHelpers.CreateJobHost(optionsWrapper, loggerProvider, testNameResolver));
        }
 // Called by the Azure Functions runtime dependency injection infrastructure
 public SqlDurabilityProviderFactory(
     IOptions <DurableTaskOptions> extensionOptions,
     ILoggerFactory loggerFactory,
     IConnectionStringResolver connectionStringResolver)
 {
     this.extensionOptions         = extensionOptions?.Value ?? throw new ArgumentNullException(nameof(extensionOptions));
     this.loggerFactory            = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
     this.connectionStringResolver = connectionStringResolver ?? throw new ArgumentNullException(nameof(connectionStringResolver));
 }
 public FunctionsV1HostWrapper(
     JobHost innerHost,
     IOptions <DurableTaskOptions> options,
     IConnectionStringResolver connectionResolver)
 {
     this.innerHost          = innerHost ?? throw new ArgumentNullException(nameof(innerHost));
     this.options            = options.Value;
     this.connectionResolver = connectionResolver;
 }
 public FunctionsV2HostWrapper(
     IHost innerHost,
     IOptions <DurableTaskOptions> options,
     INameResolver nameResolver)
 {
     this.innerHost        = innerHost ?? throw new ArgumentNullException(nameof(innerHost));
     this.innerWebJobsHost = (JobHost)this.innerHost.Services.GetService <IJobHost>();
     this.options          = options.Value;
     this.nameResolver     = nameResolver;
 }
Beispiel #10
0
        private void SetUpDistributedTracing()
        {
            DurableTaskOptions durableTaskOptions = this.options;

            CorrelationSettings.Current.EnableDistributedTracing =
                durableTaskOptions.Tracing.DistributedTracingEnabled;
            CorrelationSettings.Current.Protocol =
                durableTaskOptions.Tracing.DistributedTracingProtocol == Protocol.W3CTraceContext.ToString()
                    ? Protocol.W3CTraceContext
                    : Protocol.HttpCorrelationProtocol;
        }
Beispiel #11
0
        private void CreateCheckStatusResponse_Throws_Exception_When_NotificationUrl_Missing()
        {
            var options = new DurableTaskOptions();

            options.NotificationUrl = null;

            var httpApiHandler = new HttpApiHandler(GetTestExtension(options), null);
            var ex             = Assert.Throws <InvalidOperationException>(() => httpApiHandler.CreateCheckStatusResponse(new HttpRequestMessage(), string.Empty, null));

            Assert.Equal("Webhooks are not configured", ex.Message);
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="DurableClientFactory"/> class.
        /// </summary>
        /// <param name="defaultDurableClientOptions">Default Options to Build Durable Clients.</param>
        /// <param name="orchestrationServiceFactory">The factory used to create orchestration service based on the configured storage provider.</param>
        /// <param name="loggerFactory">The logger factory used for extension-specific logging and orchestration tracking.</param>
        /// <param name="durableTaskOptions">The configuration options for this extension.</param>
        /// <param name="messageSerializerSettingsFactory">The factory used to create <see cref="JsonSerializerSettings"/> for message settings.</param>
        public DurableClientFactory(
            IOptions <DurableClientOptions> defaultDurableClientOptions,
            IOptions <DurableTaskOptions> durableTaskOptions,
            IDurabilityProviderFactory orchestrationServiceFactory,
            ILoggerFactory loggerFactory,
            IMessageSerializerSettingsFactory messageSerializerSettingsFactory = null)
        {
            this.logger = loggerFactory.CreateLogger(DurableTaskExtension.LoggerCategoryName);

            this.durabilityProviderFactory   = orchestrationServiceFactory;
            this.defaultDurableClientOptions = defaultDurableClientOptions.Value;
            this.durableTaskOptions          = durableTaskOptions?.Value ?? new DurableTaskOptions();

            this.MessageDataConverter = DurableTaskExtension.CreateMessageDataConverter(messageSerializerSettingsFactory);
            this.TraceHelper          = new EndToEndTraceHelper(this.logger, this.durableTaskOptions.Tracing.TraceReplayEvents);
        }
Beispiel #13
0
        internal SqlOrchestrationServiceSettings GetOrchestrationServiceSettings(
            DurableTaskOptions extensionOptions,
            IConnectionStringResolver connectionStringResolver)
        {
            if (connectionStringResolver == null)
            {
                throw new ArgumentNullException(nameof(connectionStringResolver));
            }

            string?connectionString = connectionStringResolver.Resolve(this.ConnectionStringName);

            if (string.IsNullOrEmpty(connectionString))
            {
                throw new InvalidOperationException(
                          $"No SQL connection string configuration was found for the app setting or environment variable named '{this.ConnectionStringName}'.");
            }

            // Validate the connection string
            try
            {
                new SqlConnectionStringBuilder(connectionString);
            }
            catch (ArgumentException e)
            {
                throw new ArgumentException("The provided connection string is invalid.", e);
            }

            var settings = new SqlOrchestrationServiceSettings(connectionString, this.TaskHubName)
            {
                CreateDatabaseIfNotExists = this.CreateDatabaseIfNotExists,
                LoggerFactory             = this.LoggerFactory,
                WorkItemBatchSize         = this.TaskEventBatchSize,
                WorkItemLockTimeout       = this.TaskEventLockTimeout,
            };

            if (extensionOptions.MaxConcurrentActivityFunctions.HasValue)
            {
                settings.MaxConcurrentActivities = extensionOptions.MaxConcurrentActivityFunctions.Value;
            }

            if (extensionOptions.MaxConcurrentOrchestratorFunctions.HasValue)
            {
                settings.MaxActiveOrchestrations = extensionOptions.MaxConcurrentOrchestratorFunctions.Value;
            }

            return(settings);
        }
        private static DurableTaskExtension GetDurableTaskConfig()
        {
            var options = new DurableTaskOptions();

            options.HubName         = "DurableTaskHub";
            options.NotificationUrl = new Uri("https://sampleurl.net");
            var wrappedOptions           = new OptionsWrapper <DurableTaskOptions>(options);
            var connectionStringResolver = new TestConnectionStringResolver();
            var serviceFactory           = new AzureStorageDurabilityProviderFactory(wrappedOptions, connectionStringResolver);

            return(new DurableTaskExtension(
                       wrappedOptions,
                       new LoggerFactory(),
                       TestHelpers.GetTestNameResolver(),
                       serviceFactory,
                       new DurableHttpMessageHandlerFactory()));
        }
Beispiel #15
0
        private IDurableOrchestrationClient GetDurableClient(IOrchestrationServiceClient orchestrationServiceClientMockObject)
        {
            var storageProvider = new DurabilityProvider("test", new Mock <IOrchestrationService>().Object, orchestrationServiceClientMockObject, "test");
            DurableClientOptions durableClientOptions = new DurableClientOptions
            {
                ConnectionName = "Storage",
                TaskHub        = "TestTaskHub",
            };
            DurableTaskOptions          durableTaskOptions          = new DurableTaskOptions();
            DurableClientAttribute      attribute                   = new DurableClientAttribute(durableClientOptions);
            MessagePayloadDataConverter messagePayloadDataConverter = new MessagePayloadDataConverter(new JsonSerializerSettings(), true);
            var traceHelper = new EndToEndTraceHelper(new NullLogger <EndToEndTraceHelper>(), durableTaskOptions.Tracing.TraceReplayEvents);

            var durableOrchestrationClient = (IDurableOrchestrationClient) new DurableClient(storageProvider, null, attribute, messagePayloadDataConverter, traceHelper, durableTaskOptions);

            return(durableOrchestrationClient);
        }
        // Called by the Azure Functions runtime dependency injection infrastructure
        public NetheriteProviderFactory(
            IOptions <DurableTaskOptions> extensionOptions,
            ILoggerFactory loggerFactory,
            IConnectionStringResolver connectionStringResolver,
            IHostIdProvider hostIdProvider)
        {
            this.extensionOptions         = extensionOptions?.Value ?? throw new ArgumentNullException(nameof(extensionOptions));
            this.loggerFactory            = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
            this.connectionStringResolver = connectionStringResolver ?? throw new ArgumentNullException(nameof(connectionStringResolver));
            this.hostIdProvider           = hostIdProvider;

            bool ReadBooleanSetting(string name) => this.extensionOptions.StorageProvider.TryGetValue(name, out object objValue) &&
            objValue is string stringValue && bool.TryParse(stringValue, out bool boolValue) && boolValue;

            this.TraceToConsole = ReadBooleanSetting(nameof(this.TraceToConsole));
            this.TraceToBlob    = ReadBooleanSetting(nameof(this.TraceToBlob));
        }
        public void StorageProviderTypeSpecified_CorrectStorageProviderFactoryUsed(string storageProvider)
        {
            var orchestrationServiceClientMock = new Mock <IOrchestrationServiceClient>();
            Mock <IDurabilityProviderFactory> azureStorageMock = GetAzureStorageStorageProviderMock(orchestrationServiceClientMock);
            Mock <IDurabilityProviderFactory> microsoftSQLMock = GetMicrosoftSQLStorageProviderMock(orchestrationServiceClientMock);
            Mock <IDurabilityProviderFactory> netheriteMock    = GetNetheriteStorageProviderMock(orchestrationServiceClientMock);

            IEnumerable <IDurabilityProviderFactory> durabilityProviderFactories = new[] { azureStorageMock.Object, microsoftSQLMock.Object, netheriteMock.Object };

            DurableTaskOptions options = new DurableTaskOptions();

            options.StorageProvider["type"] = storageProvider;

            using (ITestHost host = TestHelpers.GetJobHostWithMultipleDurabilityProviders(
                       options: options,
                       durabilityProviderFactories: durabilityProviderFactories))
            {
                azureStorageMock.Verify(a => a.GetDurabilityProvider(), string.Equals(storageProvider, "AzureStorage") ? Times.Once() : Times.Never());
                microsoftSQLMock.Verify(m => m.GetDurabilityProvider(), string.Equals(storageProvider, "MicrosoftSQL") ? Times.Once() : Times.Never());
                netheriteMock.Verify(n => n.GetDurabilityProvider(), string.Equals(storageProvider, "Netherite") ? Times.Once() : Times.Never());
            }
        }
        public void SelectingUnavailableStorageProviderThrowsException(string storageProvider)
        {
            var orchestrationServiceClientMock = new Mock <IOrchestrationServiceClient>();
            Mock <IDurabilityProviderFactory> azureStorageMock = GetAzureStorageStorageProviderMock(orchestrationServiceClientMock);
            Mock <IDurabilityProviderFactory> microsoftSQLMock = GetMicrosoftSQLStorageProviderMock(orchestrationServiceClientMock);
            Mock <IDurabilityProviderFactory> netheriteMock    = GetNetheriteStorageProviderMock(orchestrationServiceClientMock);

            IEnumerable <IDurabilityProviderFactory> durabilityProviderFactories = new[] { azureStorageMock.Object, microsoftSQLMock.Object, netheriteMock.Object };

            DurableTaskOptions options = new DurableTaskOptions();

            options.StorageProvider["type"] = storageProvider;

            var ex = Assert.Throws <InvalidOperationException>(() =>
                                                               TestHelpers.GetJobHostWithMultipleDurabilityProviders(
                                                                   options: options,
                                                                   durabilityProviderFactories: durabilityProviderFactories));

            IList <string> factoryNames = durabilityProviderFactories.Select(f => f.Name).ToList();

            Assert.Equal($"Storage provider type ({storageProvider}) was not found. Available storage providers: {string.Join(", ", factoryNames)}.", ex.Message);
        }
Beispiel #19
0
 private static DurableTaskExtension GetTestExtension(DurableTaskOptions options)
 {
     return(new MockDurableTaskExtension(options));
 }
Beispiel #20
0
 /// <summary>
 /// Constructor for initializing Distributed Tracing.
 /// </summary>
 /// <param name="options">DurableTask options.</param>
 /// <param name="nameResolver">Name resolver used for environment variables.</param>
 public TelemetryActivator(IOptions <DurableTaskOptions> options, INameResolver nameResolver)
 {
     this.options      = options.Value;
     this.nameResolver = nameResolver;
 }