public void RequiredNoIdentifiersCached()
        {
            var config           = SetupConfig();
            var client           = new EndpointDiscoveryTestClient(config);
            var executionContext = CreateExecutionContext(client, config, true, null);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(1, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            var endpoints = client.WaitForCachedValue(CACHEKEY);

            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, "https://test123.amazonaws.com/shared/"));

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(2, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            endpoints = client.WaitForCachedValue(CACHEKEY);
            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, "https://test123.amazonaws.com/shared/"));
        }
        private ExecutionContext CreateExecutionContext(EndpointDiscoveryTestClient client, AmazonDynamoDBConfig config,
                                                        bool required, SortedDictionary <string, string> identifiers)
        {
            var request = new CreateTableRequest();
            var options = new InvokeOptions();

            options.RequestMarshaller           = new CreateTableRequestMarshaller();
            options.EndpointDiscoveryMarshaller = new TestEndpointDiscoveryMarshaller(required, identifiers);
            client.SetOptionsEndpointOperation(options);
            var credentials = new ImmutableCredentials(AWS_ACCESS_KEY_ID, "test", "test");

            var executionContext = new ExecutionContext(
                new RequestContext(true, new NullSigner())
            {
                ClientConfig         = config,
                Request              = options.RequestMarshaller.Marshall(request),
                ImmutableCredentials = credentials,
                OriginalRequest      = request,
                Options              = options
            },
                new ResponseContext()
                );

            return(executionContext);
        }
        public void RequiredWithIdentifiersCached()
        {
            var config = SetupConfig();
            var client = new EndpointDiscoveryTestClient(config);
            SortedDictionary <string, string> identifiers = new SortedDictionary <string, string>();

            identifiers.Add(IDENTIFIER_NAME, "test");
            var executionContext = CreateExecutionContext(client, config, true, identifiers);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/CreateTable",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(1, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            var endpoints = client.WaitForCachedValue(CACHEKEY_IDENTIFIERS);

            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, "https://test123.amazonaws.com/shared/CreateTable"));

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/CreateTable",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(2, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
        }
        public void RequiredNoIdentifiersEvictCache()
        {
            var config           = SetupConfig();
            var client           = new EndpointDiscoveryTestClient(config);
            var executionContext = CreateExecutionContext(client, config, true, null);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(1, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            var endpoints = client.WaitForCachedValue(CACHEKEY);

            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, "https://test123.amazonaws.com/shared/"));

            //Eviction happens on a invalid endpoint exception. In this case the endpoint is currently set to the invalid endpoint.
            executionContext.RequestContext.Request.Endpoint = new Uri("https://test123.amazonaws.com/shared/");
            EndpointDiscoveryHandler.EvictCacheKeyForRequest(executionContext.RequestContext, null);
            Assert.IsNull(executionContext.RequestContext.Request.Endpoint);
            Assert.AreEqual(2, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(0, client.CacheCount);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual("https://test123.amazonaws.com/shared/",
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(3, client.EndpointOperationCallCount);
            Assert.AreEqual(2, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            endpoints = client.WaitForCachedValue(CACHEKEY);
            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, "https://test123.amazonaws.com/shared/"));
        }
        public void CacheEvictionTestUsingEndpointDiscoveryCallStack()
        {
            var oldUtcNowSource = GetUtcNowSource();
            var currentDateTime = new DateTime(2021, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            try
            {
                SetUtcNowSource(() => currentDateTime);

                var config           = SetupConfig();
                var client           = new EndpointDiscoveryTestClient(config);
                var executionContext = CreateExecutionContext(client, config, true, null);
                EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);

                Assert.AreEqual(1, client.CacheCount);

                // Jump in the future so the endpoint we just cached will be evicted the next time we do discovery
                SetUtcNowSource(() => currentDateTime.AddDays(1));
                executionContext.RequestContext.ImmutableCredentials = new ImmutableCredentials("AWS_ACCESS_KEY_ID" + "2", "test2", "test2");
                EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);

                // First endpoint should be evicted, leaving us with only the second one
                Assert.AreEqual(1, client.CacheCount);
            }
            finally
            {
                SetUtcNowSource(oldUtcNowSource);
            }
        }
        public void NotRequiredEnabledNoIdentifiersNoWait()
        {
            var config           = SetupConfig(true);
            var client           = new EndpointDiscoveryTestClient(config);
            var executionContext = CreateExecutionContext(client, config, false, null);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);

            //Verify the endpoint has not been touched by the endpoint discovery resolver
            Assert.IsNull(executionContext.RequestContext.Request.Endpoint);
        }
        public void NotRequiredEnabledHasIdentifiersNoWait()
        {
            var config = SetupConfig(true);
            var client = new EndpointDiscoveryTestClient(config);
            SortedDictionary <string, string> identifiers = new SortedDictionary <string, string>();

            identifiers.Add(IDENTIFIER_NAME, "test");
            var executionContext = CreateExecutionContext(client, config, false, identifiers);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);

            //Verify the endpoint has not been touched by the endpoint discovery resolver
            Assert.IsNull(executionContext.RequestContext.Request.Endpoint);
        }
        public void RequiredNoIdentifiers(string endpoint, string expectedEndpoint)
        {
            var config           = SetupConfig();
            var client           = new EndpointDiscoveryTestClient(config, baseUrl: endpoint);
            var executionContext = CreateExecutionContext(client, config, true, null);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            Assert.AreEqual(expectedEndpoint,
                            executionContext.RequestContext.Request.Endpoint.ToString());
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
            var endpoints = client.WaitForCachedValue(CACHEKEY);

            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, expectedEndpoint));
        }
        public void NotRequiredNoIdentifiersFailedDiscoveryWait()
        {
            var config           = SetupConfig(true);
            var client           = new EndpointDiscoveryTestClient(config, true);
            var executionContext = CreateExecutionContext(client, config, false, null);

            EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false);
            var endpoints = client.WaitForCachedValue(CACHEKEY);

            Assert.IsNotNull(endpoints);
            Assert.IsTrue(HasEndpointAddress(endpoints, null));

            Assert.AreEqual(1, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(1, client.CacheCount);
        }
        public void RequiredNoIdentifiersFailedDiscovery()
        {
            var config = SetupConfig();
            var client = new EndpointDiscoveryTestClient(config, true);
            SortedDictionary <string, string> identifiers = new SortedDictionary <string, string>();

            identifiers.Add(IDENTIFIER_NAME, "test");
            var executionContext = CreateExecutionContext(client, config, true, identifiers);

            Utils.AssertExceptionExpected(
                () => { EndpointDiscoveryHandler.DiscoverEndpoints(executionContext.RequestContext, false); },
                typeof(AmazonClientException));

            Assert.AreEqual(1, client.EndpointOperationCallCount);
            Assert.AreEqual(1, client.FetchCallCount);
            Assert.AreEqual(0, client.CacheCount);
        }