static Type GetSelectedFeatureForDataBus(SettingsHolder settings) { DataBusDefinition dataBusDefinition; if (!settings.TryGet("SelectedDataBus", out dataBusDefinition)) { dataBusDefinition = new FileShareDataBus(); } return dataBusDefinition.ProvidedByFeature(); }
/// <summary> /// Adds a namespace for partitioning. /// </summary> public void AddNamespace(string name, string connectionString) { NamespaceConfigurations namespaces; if (!settings.TryGet(WellKnownConfigurationKeys.Topology.Addressing.Namespaces, out namespaces)) { namespaces = new NamespaceConfigurations(); settings.Set(WellKnownConfigurationKeys.Topology.Addressing.Namespaces, namespaces); } namespaces.Add(name, connectionString, NamespacePurpose.Partitioning); }
public RabbitMQTransportInfrastructure(SettingsHolder settings, string connectionString) { this.settings = settings; var endpointName = settings.EndpointName(); var connectionConfiguration = ConnectionConfiguration.Create(connectionString, endpointName); settings.TryGet(SettingsKeys.ClientCertificates, out X509CertificateCollection clientCertificates); settings.TryGet(SettingsKeys.DisableRemoteCertificateValidation, out bool disableRemoteCertificateValidation); settings.TryGet(SettingsKeys.UseExternalAuthMechanism, out bool useExternalAuthMechanism); connectionFactory = new ConnectionFactory(endpointName, connectionConfiguration, clientCertificates, disableRemoteCertificateValidation, useExternalAuthMechanism); routingTopology = CreateRoutingTopology(); if (!settings.TryGet(SettingsKeys.UsePublisherConfirms, out bool usePublisherConfirms)) { usePublisherConfirms = true; } channelProvider = new ChannelProvider(connectionFactory, connectionConfiguration.RetryDelay, routingTopology, usePublisherConfirms); }
public RabbitMQTransportInfrastructure(SettingsHolder settings, string connectionString) { this.settings = settings; var connectionConfiguration = ConnectionConfiguration.Create(connectionString, settings.EndpointName()); X509CertificateCollection clientCertificates; settings.TryGet(SettingsKeys.ClientCertificates, out clientCertificates); connectionFactory = new ConnectionFactory(connectionConfiguration, clientCertificates); routingTopology = CreateRoutingTopology(); var routingTopologySupportsDelayedDelivery = routingTopology is ISupportDelayedDelivery; settings.Set(SettingsKeys.RoutingTopologySupportsDelayedDelivery, routingTopologySupportsDelayedDelivery); if (routingTopologySupportsDelayedDelivery) { var timeoutManagerFeatureDisabled = settings.GetOrDefault <FeatureState>(typeof(TimeoutManager).FullName) == FeatureState.Disabled; var sendOnlyEndpoint = settings.GetOrDefault <bool>(coreSendOnlyEndpointKey); if (timeoutManagerFeatureDisabled || sendOnlyEndpoint) { settings.Set(SettingsKeys.DisableTimeoutManager, true); } } bool usePublisherConfirms; if (!settings.TryGet(SettingsKeys.UsePublisherConfirms, out usePublisherConfirms)) { usePublisherConfirms = true; } channelProvider = new ChannelProvider(connectionFactory, routingTopology, usePublisherConfirms); RequireOutboxConsent = false; }
public AzureServiceBusTransportInfrastructure(SettingsHolder settings, string connectionString) { this.settings = settings; connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString); if (settings.TryGet(SettingsKeys.TransportType, out TransportType transportType)) { connectionStringBuilder.TransportType = transportType; } settings.TryGet(SettingsKeys.CustomTokenProvider, out tokenProvider); if (!settings.TryGet(SettingsKeys.TopicName, out topicName)) { topicName = defaultTopicName; } settings.EnableFeatureByDefault <TransactionScopeSuppressFeature>(); namespacePermissions = new NamespacePermissions(connectionStringBuilder, tokenProvider); WriteStartupDiagnostics(); }
static TransportInfrastructure CreateTransportInfrastructure(SettingsHolder settings) { settings.TryGet(WellKnownConfigurationKeys.Topology.Selected, out string configuredTopology); switch (configuredTopology) { case WellKnownConfigurationKeys.Topology.EndpointOrientedTopology: return(new EndpointOrientedTransportInfrastructure(settings)); case WellKnownConfigurationKeys.Topology.ForwardingTopology: return(new ForwardingTransportInfrastructure(settings)); default: throw new Exception("Azure Service Bus transport requires a topology to be specified. Use `.UseForwardingTopology()` or `.UseEndpointOrientedTopology()` configuration API to specify topology to use."); } }
public AcceptanceTestingTransportInfrastructure(SettingsHolder settings) { this.settings = settings; if (!settings.TryGet(UseNativeDelayedDeliveryKey, out nativeDelayedDelivery)) { nativeDelayedDelivery = true; } if (!settings.TryGet(UseNativePubSubKey, out nativePubSub)) { nativePubSub = true; } if (!settings.TryGet(StorageLocationKey, out storagePath)) { var solutionRoot = FindSolutionRoot(); storagePath = Path.Combine(solutionRoot, ".attransport"); } var errorQueueAddress = settings.ErrorQueueAddress(); PathChecker.ThrowForBadPath(errorQueueAddress, "ErrorQueueAddress"); }
static void AddScannerForPublisher(SettingsHolder settings, string publisherName, ITypesScanner scanner) { if (!settings.TryGet <Dictionary <string, List <ITypesScanner> > >(WellKnownConfigurationKeys.Topology.Publishers, out var map)) { map = new Dictionary <string, List <ITypesScanner> >(); settings.Set(WellKnownConfigurationKeys.Topology.Publishers, map); } if (!map.ContainsKey(publisherName)) { map[publisherName] = new List <ITypesScanner>(); } map[publisherName].Add(scanner); }
async Task TimerLoop() { int SecondsBetweenCommits; if (!settingsHolder.TryGet <int>(WellKnownConfigurationKeys.SecondsBetweenCommits, out SecondsBetweenCommits)) { SecondsBetweenCommits = 30; } var token = tokenSource.Token; while (!tokenSource.IsCancellationRequested) { try { await Task.WhenAny(Task.Delay(new TimeSpan(0, 0, 0, SecondsBetweenCommits, 0))).ConfigureAwait(false); await CommitOffsets().ConfigureAwait(false); } catch (Exception) { // intentionally ignored } } }
public LearningTransportInfrastructure(SettingsHolder settings) { this.settings = settings; if (!settings.TryGet(StorageLocationKey, out storagePath)) { storagePath = FindStoragePath(); } settings.SetDefault(new MessageProcessingOptimizationExtensions.ConcurrencyLimit { MaxValue = 1 }); var errorQueueAddress = settings.ErrorQueueAddress(); PathChecker.ThrowForBadPath(errorQueueAddress, "ErrorQueueAddress"); }
internal SqlServerTransportInfrastructure(string catalog, SettingsHolder settings, string connectionString, Func <string> localAddress, Func <LogicalAddress> logicalAddress) { this.settings = settings; this.connectionString = connectionString; this.localAddress = localAddress; this.logicalAddress = logicalAddress; if (settings.HasSetting(SettingsKeys.DisableNativePubSub)) { OutboundRoutingPolicy = new OutboundRoutingPolicy(OutboundRoutingType.Unicast, OutboundRoutingType.Unicast, OutboundRoutingType.Unicast); } else { OutboundRoutingPolicy = new OutboundRoutingPolicy(OutboundRoutingType.Unicast, OutboundRoutingType.Multicast, OutboundRoutingType.Unicast); } settings.TryGet(SettingsKeys.DefaultSchemaSettingsKey, out string defaultSchemaOverride); var queueSchemaSettings = settings.GetOrDefault <QueueSchemaAndCatalogSettings>(); addressTranslator = new QueueAddressTranslator(catalog, "dbo", defaultSchemaOverride, queueSchemaSettings); tableBasedQueueCache = new TableBasedQueueCache(addressTranslator); connectionFactory = CreateConnectionFactory(); //Configure the schema and catalog for logical endpoint-based routing var schemaAndCatalogSettings = settings.GetOrCreate <EndpointSchemaAndCatalogSettings>(); settings.GetOrCreate <EndpointInstances>().AddOrReplaceInstances("SqlServer", schemaAndCatalogSettings.ToEndpointInstances()); //Needs to be invoked here and not when configuring the receiving infrastructure because the EnableMigrationMode flag has to be set up before feature component is initialized. HandleTimeoutManagerCompatibilityMode(); var pubSubSettings = settings.GetOrCreate <SubscriptionSettings>(); var subscriptionTableName = pubSubSettings.SubscriptionTable.Qualify(defaultSchemaOverride ?? "dbo", catalog); subscriptionStore = new PolymorphicSubscriptionStore(new SubscriptionTable(subscriptionTableName.QuotedQualifiedName, connectionFactory)); var timeToCacheSubscriptions = pubSubSettings.TimeToCacheSubscriptions; if (timeToCacheSubscriptions.HasValue) { subscriptionStore = new CachedSubscriptionStore(subscriptionStore, timeToCacheSubscriptions.Value); } var subscriptionTableCreator = new SubscriptionTableCreator(subscriptionTableName, connectionFactory); settings.Set(subscriptionTableCreator); }
public LearningTransportInfrastructure(SettingsHolder settings) { this.settings = settings; if (!settings.TryGet(StorageLocationKey, out storagePath)) { storagePath = FindStoragePath(); } if (settings.TryGet <ReceiveComponent.Settings>(out var receiveSettings)) { receiveSettings.SetDefaultPushRuntimeSettings(new PushRuntimeSettings(1)); } var errorQueueAddress = settings.ErrorQueueAddress(); PathChecker.ThrowForBadPath(errorQueueAddress, "ErrorQueueAddress"); }
public TestTransportInfrastructure(SettingsHolder settings) { this.settings = settings; if (!settings.TryGet(StorageLocationKey, out storagePath)) { var solutionRoot = FindSolutionRoot(); storagePath = Path.Combine(solutionRoot, ".learningtransport"); } var errorQueueAddress = settings.ErrorQueueAddress(); PathChecker.ThrowForBadPath(errorQueueAddress, "ErrorQueueAddress"); OutboundRoutingPolicy = settings.GetOrDefault <bool>(NoNativePubSub) ? new OutboundRoutingPolicy(OutboundRoutingType.Unicast, OutboundRoutingType.Unicast, OutboundRoutingType.Unicast) : new OutboundRoutingPolicy(OutboundRoutingType.Unicast, OutboundRoutingType.Multicast, OutboundRoutingType.Unicast); }
/// <summary> /// Adds the specified exception type to be treated as an unrecoverable exception. /// </summary> /// <param name="settings">The extended settings.</param> /// <param name="exceptionType">The exception type.</param> public static void AddUnrecoverableException(this SettingsHolder settings, Type exceptionType) { Guard.AgainstNull(nameof(settings), settings); Guard.AgainstNull(nameof(exceptionType), exceptionType); if (!typeof(Exception).IsAssignableFrom(exceptionType)) { throw new ArgumentException("Exception type must be an exception", nameof(exceptionType)); } if (!settings.TryGet(Recoverability.UnrecoverableExceptions, out HashSet <Type> unrecoverableExceptions)) { unrecoverableExceptions = new HashSet <Type>(); settings.Set(Recoverability.UnrecoverableExceptions, unrecoverableExceptions); } unrecoverableExceptions.Add(exceptionType); }
/// <summary> /// <see cref="TransportDefinition.Initialize" /> /// </summary> public override TransportInfrastructure Initialize(SettingsHolder settings, string connectionString) { string defaultSchemaOverride; settings.TryGet(SettingsKeys.DefaultSchemaSettingsKey, out defaultSchemaOverride); var queueSchemaSettings = settings.GetOrDefault <QueueSchemaAndCatalogSettings>(); if (LegacyMultiInstanceModeTurnedOn(settings)) { var addressParser = new LegacyQueueAddressTranslator("dbo", defaultSchemaOverride, queueSchemaSettings); return(new LegacySqlServerTransportInfrastructure(addressParser, settings)); } else { var catalog = GetDefaultCatalog(settings, connectionString); var addressParser = new QueueAddressTranslator(catalog, "dbo", defaultSchemaOverride, queueSchemaSettings); return(new SqlServerTransportInfrastructure(addressParser, settings, connectionString)); } }
IRoutingTopology CreateRoutingTopology() { if (!settings.TryGet(out Func <bool, IRoutingTopology> topologyFactory)) { throw new InvalidOperationException("A routing topology must be configured with one of the 'EndpointConfiguration.UseTransport<RabbitMQTransport>().UseXXXXRoutingTopology()` methods."); } if (!settings.TryGet(SettingsKeys.UseDurableExchangesAndQueues, out bool useDurableExchangesAndQueues)) { useDurableExchangesAndQueues = true; } return(topologyFactory(useDurableExchangesAndQueues)); }
public LearningTransportInfrastructure(SettingsHolder settings) { this.settings = settings; if (!settings.TryGet(StorageLocationKey, out storagePath)) { var solutionRoot = FindSolutionRoot(); storagePath = Path.Combine(solutionRoot, ".learningtransport"); } settings.SetDefault <MessageProcessingOptimizationExtensions.ConcurrencyLimit>(new MessageProcessingOptimizationExtensions.ConcurrencyLimit { MaxValue = 1 }); var errorQueueAddress = settings.ErrorQueueAddress(); PathChecker.ThrowForBadPath(errorQueueAddress, "ErrorQueueAddress"); settings.Set(Recoverability.DisableLegacyRetriesSatellite, true); }
public RabbitMQTransportInfrastructure(SettingsHolder settings, string connectionString) { this.settings = settings; var connectionConfiguration = new ConnectionStringParser(settings).Parse(connectionString); connectionFactory = new ConnectionFactory(connectionConfiguration); routingTopology = CreateRoutingTopology(); bool usePublisherConfirms; if (!settings.TryGet(SettingsKeys.UsePublisherConfirms, out usePublisherConfirms)) { usePublisherConfirms = true; } channelProvider = new ChannelProvider(connectionFactory, routingTopology, usePublisherConfirms); RequireOutboxConsent = false; }
static bool IsEncrypted(SettingsHolder settings, string connectionString) { if (settings.TryGet(SettingsKeys.ConnectionFactoryOverride, out Func <Task <SqlConnection> > factoryOverride)) { using (var connection = factoryOverride().GetAwaiter().GetResult()) { connectionString = connection.ConnectionString; } } var parser = new DbConnectionStringBuilder { ConnectionString = connectionString }; if (parser.TryGetValue("Column Encryption Setting", out var enabled)) { return(((string)enabled).Equals("enabled", StringComparison.InvariantCultureIgnoreCase)); } return(false); }
public override TransportInfrastructure Initialize(SettingsHolder settings, string connectionString) { // configure JSON instead of XML as the default serializer: SetMainSerializer(settings, new JsonSerializer()); // register the MessageWrapper as a system message to have it registered in mappings and serializers settings.GetOrCreate <Conventions>().AddSystemMessagesConventions(t => t == typeof(MessageWrapper)); settings.Set("Recoverability.DisableLegacyRetriesSatellite", true); var appSettings = ConfigurationManager.AppSettings; settings.Set(WellKnownConfigurationKeys.KafkaDebugEnabled, Convert.ToBoolean(appSettings[WellKnownConfigurationKeys.KafkaDebugEnabled] ?? "false")); settings.Set(WellKnownConfigurationKeys.KafkaSessionTimeout, Convert.ToInt32(appSettings[WellKnownConfigurationKeys.KafkaSessionTimeout] ?? "30000")); settings.Set(WellKnownConfigurationKeys.KafkaHeartBeatInterval, Convert.ToInt32(appSettings[WellKnownConfigurationKeys.KafkaHeartBeatInterval] ?? "5000")); settings.Set(WellKnownConfigurationKeys.CreateQueues, Convert.ToBoolean(appSettings[WellKnownConfigurationKeys.CreateQueues] ?? "false")); settings.Set(WellKnownConfigurationKeys.KafkaPathToBin, appSettings[WellKnownConfigurationKeys.KafkaPathToBin] ?? @"C:\kafka_2.11-0.10.1.0\bin\windows"); settings.Set(WellKnownConfigurationKeys.KafkaZooKeeperUrl, appSettings[WellKnownConfigurationKeys.KafkaZooKeeperUrl] ?? @"localhost:2181"); settings.Set(WellKnownConfigurationKeys.NumberOfPartitions, appSettings[WellKnownConfigurationKeys.NumberOfPartitions] ?? @"1"); settings.Set(WellKnownConfigurationKeys.ReplicationFactor, appSettings[WellKnownConfigurationKeys.ReplicationFactor] ?? @"1"); // TODO: register metadata of the wrapper for the sake of XML serializer MessageMetadataRegistry registry; if (settings.TryGet(out registry) == false) { const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance; registry = (MessageMetadataRegistry)Activator.CreateInstance(typeof(MessageMetadataRegistry), flags, null, new object[] { settings.GetOrCreate <Conventions>() }, CultureInfo.InvariantCulture); settings.Set <MessageMetadataRegistry>(registry); } settings.Get <MessageMetadataRegistry>().GetMessageMetadata(typeof(MessageWrapper)); settings.SetDefault(WellKnownConfigurationKeys.ConnectionString, connectionString); return(new KafkaTransportInfrastructure(settings, connectionString)); }
public void Run(SettingsHolder settings) { if (!settings.TryGet("PersistenceDefinitions", out List <EnabledPersistence> definitions)) { return; } var enabledPersistences = PersistenceStorageMerger.Merge(definitions, settings); ValidateSagaAndOutboxUseSamePersistence(enabledPersistences, settings); var resultingSupportedStorages = new List <Type>(); var diagnostics = new Dictionary <string, object>(); foreach (var definition in enabledPersistences) { var persistenceDefinition = definition.DefinitionType.Construct <PersistenceDefinition>(); persistenceDefinition.ApplyDefaults(settings); foreach (var storageType in definition.SelectedStorages) { Logger.DebugFormat("Activating persistence '{0}' to provide storage for '{1}' storage.", definition.DefinitionType.Name, storageType); persistenceDefinition.ApplyActionForStorage(storageType, settings); resultingSupportedStorages.Add(storageType); diagnostics.Add(storageType.Name, new { Type = definition.DefinitionType.FullName, Version = FileVersionRetriever.GetFileVersion(definition.DefinitionType) }); } } settings.Set("ResultingSupportedStorages", resultingSupportedStorages); settings.AddStartupDiagnosticsSection("Persistence", diagnostics); }
IRoutingTopology CreateRoutingTopology() { if (!settings.TryGet(out Func <bool, IRoutingTopology> topologyFactory)) { throw new InvalidOperationException("A routing topology must be configured with one of the 'EndpointConfiguration.UseTransport<RabbitMQTransport>().UseXXXXRoutingTopology()` methods."); } if (!settings.TryGet(SettingsKeys.UseDurableExchangesAndQueues, out bool useDurableExchangesAndQueues)) { if (!settings.DurableMessagesEnabled()) { throw new Exception("When durable messages are disabled, 'EndpointConfiguration.UseTransport<RabbitMQTransport>().UseDurableExchangesAndQueues()' must also be called to specify exchange and queue durability settings."); } useDurableExchangesAndQueues = true; } return(topologyFactory(useDurableExchangesAndQueues)); }
private void CreateConsumer(List <string> topics = null) { var config = new RdKafka.Config() { GroupId = endpointName, EnableAutoCommit = false }; bool debugEnabled; if (settingsHolder.TryGet <bool>(WellKnownConfigurationKeys.KafkaDebugEnabled, out debugEnabled) && debugEnabled) { config["debug"] = "all"; } var defaultConfig = new TopicConfig(); defaultConfig["auto.offset.reset"] = "earliest"; string sessionTimeout; if (settingsHolder.TryGet <string>(WellKnownConfigurationKeys.KafkaSessionTimeout, out sessionTimeout)) { config["session.timeout.ms"] = sessionTimeout; } else { config["session.timeout.ms"] = "15000"; } string heartBeatInterval; if (settingsHolder.TryGet <string>(WellKnownConfigurationKeys.KafkaHeartBeatInterval, out heartBeatInterval)) { config["heartbeat.interval.ms"] = heartBeatInterval; } else { config["heartbeat.interval.ms"] = "5000"; } config.DefaultTopicConfig = defaultConfig; if (consumer != null) { // consumer.Dispose(); } consumer = new EventConsumer(config, connectionString); if (topics != null && consumer != null) { consumer.AddSubscriptions(topics); } consumer.OnPartitionsAssigned += Consumer_OnPartitionsAssigned; consumer.OnPartitionsRevoked += Consumer_OnPartitionsRevoked; consumer.OnEndReached += Consumer_OnEndReached; }
public async Task CreateQueueIfNecessary(QueueBindings queueBindings, string identity) { try { bool createQueues; if (!settings.TryGet <bool>(WellKnownConfigurationKeys.CreateQueues, out createQueues)) { return; } string pathToBin; if (!settings.TryGet <string>(WellKnownConfigurationKeys.KafkaPathToBin, out pathToBin)) { pathToBin = @"C:\kafka_2.11-0.10.1.0\bin\windows"; } string zookeeperUrl; if (!settings.TryGet <string>(WellKnownConfigurationKeys.KafkaZooKeeperUrl, out zookeeperUrl)) { zookeeperUrl = @"localhost:2181"; } string numberOfPartitions; if (!settings.TryGet <string>(WellKnownConfigurationKeys.NumberOfPartitions, out numberOfPartitions)) { numberOfPartitions = "1"; } string replicationFactor; if (!settings.TryGet <string>(WellKnownConfigurationKeys.ReplicationFactor, out replicationFactor)) { replicationFactor = "1"; } var process = new System.Diagnostics.Process(); var startInfo = new System.Diagnostics.ProcessStartInfo { WorkingDirectory = pathToBin, WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal, FileName = "cmd.exe", RedirectStandardInput = true, UseShellExecute = false }; process.StartInfo = startInfo; process.Start(); //delete /* string kafkaDeleteTopicCommand = @".\kafka-topics.bat --delete --zookeeper " + zookeeperUrl + " --topic "; * * foreach (var q in queueBindings.ReceivingAddresses) * { * await process.StandardInput.WriteLineAsync(kafkaDeleteTopicCommand + q).ConfigureAwait(false); * * } * * foreach (var q in queueBindings.SendingAddresses) * { * await process.StandardInput.WriteLineAsync(kafkaDeleteTopicCommand + q).ConfigureAwait(false); * * }*/ //create string kafkaCreateTopicCommand = @".\kafka-topics.bat --create --zookeeper " + zookeeperUrl + " --partitions " + numberOfPartitions + " --replication-factor " + replicationFactor + " --topic "; foreach (var q in queueBindings.ReceivingAddresses) { await process.StandardInput.WriteLineAsync(kafkaCreateTopicCommand + q).ConfigureAwait(false); } foreach (var q in queueBindings.SendingAddresses) { await process.StandardInput.WriteLineAsync(kafkaCreateTopicCommand + q).ConfigureAwait(false); } } catch (Exception ex) { Logger.Warn(ex.ToString()); } }
void WriteStartupDiagnostics() { settings.AddStartupDiagnosticsSection("Azure Service Bus transport", new { TopicName = settings.TryGet(SettingsKeys.TopicName, out string customTopicName) ? customTopicName : "default", EntityMaximumSize = settings.TryGet(SettingsKeys.MaximumSizeInGB, out int entityMaxSize) ? entityMaxSize.ToString() : "default", EnablePartitioning = settings.TryGet(SettingsKeys.EnablePartitioning, out bool enablePartitioning) ? enablePartitioning.ToString() : "default", SubscriptionNameShortener = settings.TryGet(SettingsKeys.SubscriptionNameFactory, out Func <string, string> _) ? "configured" : "default", RuleNameShortener = settings.TryGet(SettingsKeys.RuleNameFactory, out Func <Type, string> _) ? "configured" : "default", PrefetchMultiplier = settings.TryGet(SettingsKeys.PrefetchMultiplier, out int prefetchMultiplier) ? prefetchMultiplier.ToString() : "default", PrefetchCount = settings.TryGet(SettingsKeys.PrefetchCount, out int?prefetchCount) ? prefetchCount.ToString() : "default", UseWebSockets = settings.TryGet(SettingsKeys.TransportType, out TransportType _) ? "True" : "default", TimeToWaitBeforeTriggeringCircuitBreaker = settings.TryGet(SettingsKeys.TransportType, out TimeSpan timeToWait) ? timeToWait.ToString() : "default", CustomTokenProvider = settings.TryGet(SettingsKeys.CustomTokenProvider, out ITokenProvider customTokenProvider) ? customTokenProvider.ToString() : "default", CustomRetryPolicy = settings.TryGet(SettingsKeys.CustomRetryPolicy, out RetryPolicy customRetryPolicy) ? customRetryPolicy.ToString() : "default" });