CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-amazonaws--aws-java-sdk-core

Core foundational library for AWS SDK for Java 1.x providing authentication, HTTP transport, regions, protocols, and shared utilities for all AWS service clients

Pending
Overview
Eval results
Files

endpoint-discovery.mddocs/

Endpoint Discovery & Dynamic Endpoints

AWS services may support endpoint discovery to optimize connectivity and performance. The AWS Java SDK Core provides endpoint discovery capabilities that automatically discover and cache service endpoints, especially useful for services with dynamic or regionalized endpoints.

Core Endpoint Discovery Interfaces

Endpoint Discovery Provider

// Core endpoint discovery provider interface
interface EndpointDiscoveryProvider {
    boolean isEndpointDiscoveryEnabled();
    void refresh();
}

// Base endpoint discovery provider
abstract class BaseEndpointDiscoveryProvider implements EndpointDiscoveryProvider {
    public abstract boolean isEndpointDiscoveryEnabled();
    public void refresh() {
        // Default refresh implementation
    }
}

Endpoint Discovery Provider Chain

// Chain of endpoint discovery providers
class EndpointDiscoveryProviderChain extends BaseEndpointDiscoveryProvider {
    public EndpointDiscoveryProviderChain(EndpointDiscoveryProvider... providers);
    public EndpointDiscoveryProviderChain(List<EndpointDiscoveryProvider> providers);
    
    public boolean isEndpointDiscoveryEnabled();
    public void refresh();
    
    // Get the current provider in the chain that provided the result
    public EndpointDiscoveryProvider getLastUsedProvider();
}

// Default endpoint discovery provider chain
class DefaultEndpointDiscoveryProviderChain extends EndpointDiscoveryProviderChain {
    public static DefaultEndpointDiscoveryProviderChain getInstance();
    
    // Uses the following provider chain:
    // 1. Environment variable provider
    // 2. System property provider  
    // 3. AWS profile provider
    // 4. Default disabled provider
}

Built-in Endpoint Discovery Providers

Environment Variable Provider

// Endpoint discovery from environment variables
class EnvironmentVariableEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    public static final String AWS_ENABLE_ENDPOINT_DISCOVERY = "AWS_ENABLE_ENDPOINT_DISCOVERY";
    
    public EnvironmentVariableEndpointDiscoveryProvider();
    public boolean isEndpointDiscoveryEnabled();
}

System Property Provider

// Endpoint discovery from system properties
class SystemPropertyEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    public static final String AWS_ENABLE_ENDPOINT_DISCOVERY = "aws.enableEndpointDiscovery";
    
    public SystemPropertyEndpointDiscoveryProvider();
    public boolean isEndpointDiscoveryEnabled();
}

AWS Profile Provider

// Endpoint discovery from AWS profile configuration
class AwsProfileEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    public AwsProfileEndpointDiscoveryProvider();
    public AwsProfileEndpointDiscoveryProvider(String profileName);
    public AwsProfileEndpointDiscoveryProvider(File profileFile);
    public AwsProfileEndpointDiscoveryProvider(File profileFile, String profileName);
    
    public boolean isEndpointDiscoveryEnabled();
}

Static Provider

// Static endpoint discovery configuration
class StaticEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    public StaticEndpointDiscoveryProvider(boolean endpointDiscoveryEnabled);
    public boolean isEndpointDiscoveryEnabled();
}

Endpoint Discovery Configuration

Client Builder Integration

import com.amazonaws.endpointdiscovery.DefaultEndpointDiscoveryProviderChain;
import com.amazonaws.endpointdiscovery.StaticEndpointDiscoveryProvider;
import com.amazonaws.services.timestreamwrite.AmazonTimestreamWrite;
import com.amazonaws.services.timestreamwrite.AmazonTimestreamWriteClientBuilder;

// Enable endpoint discovery using default provider chain
AmazonTimestreamWrite client = AmazonTimestreamWriteClientBuilder.standard()
    .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
    .withRegion(Regions.US_EAST_1)
    .withEndpointDiscoveryEnabled(true)
    .build();

// Or use explicit endpoint discovery provider
EndpointDiscoveryProvider provider = new StaticEndpointDiscoveryProvider(true);
AmazonTimestreamWrite clientWithProvider = AmazonTimestreamWriteClientBuilder.standard()
    .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
    .withRegion(Regions.US_EAST_1)
    .withEndpointDiscoveryProvider(provider)
    .build();

Environment Configuration

# Enable endpoint discovery via environment variable
export AWS_ENABLE_ENDPOINT_DISCOVERY=true

# Or via system property
java -Daws.enableEndpointDiscovery=true YourApplication

Profile Configuration

# In ~/.aws/config or credentials file
[profile my-profile]
endpoint_discovery_enabled = true
region = us-west-2

[default]
endpoint_discovery_enabled = false

Basic Usage Examples

Simple Endpoint Discovery Setup

import com.amazonaws.endpointdiscovery.DefaultEndpointDiscoveryProviderChain;
import com.amazonaws.services.timestreamwrite.AmazonTimestreamWrite;
import com.amazonaws.services.timestreamwrite.AmazonTimestreamWriteClientBuilder;

public class EndpointDiscoveryExample {
    
    public static void main(String[] args) {
        // Create client with endpoint discovery enabled
        AmazonTimestreamWrite timestreamClient = AmazonTimestreamWriteClientBuilder.standard()
            .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
            .withRegion(Regions.US_EAST_1)
            .withEndpointDiscoveryEnabled(true)
            .build();
        
        try {
            // Use the client - endpoints will be discovered automatically
            timestreamClient.listDatabases();
            
        } finally {
            // Clean up
            timestreamClient.shutdown();
        }
    }
}

Custom Endpoint Discovery Provider

import com.amazonaws.endpointdiscovery.BaseEndpointDiscoveryProvider;

public class CustomEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final String configSource;
    private volatile Boolean endpointDiscoveryEnabled;
    
    public CustomEndpointDiscoveryProvider(String configSource) {
        this.configSource = configSource;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        if (endpointDiscoveryEnabled == null) {
            // Load configuration from custom source
            endpointDiscoveryEnabled = loadConfigurationFromSource();
        }
        return endpointDiscoveryEnabled;
    }
    
    @Override
    public void refresh() {
        // Force reload from configuration source
        endpointDiscoveryEnabled = null;
    }
    
    private boolean loadConfigurationFromSource() {
        // Custom logic to load endpoint discovery configuration
        // For example, from database, external service, etc.
        try {
            // Your custom configuration loading logic here
            return fetchEndpointDiscoverySettingFromSource(configSource);
        } catch (Exception e) {
            // Default to disabled on error
            return false;
        }
    }
    
    private boolean fetchEndpointDiscoverySettingFromSource(String source) {
        // Implement your custom configuration fetching logic
        return true; // Placeholder
    }
}

Provider Chain Configuration

import com.amazonaws.endpointdiscovery.EndpointDiscoveryProviderChain;
import com.amazonaws.endpointdiscovery.EnvironmentVariableEndpointDiscoveryProvider;
import com.amazonaws.endpointdiscovery.AwsProfileEndpointDiscoveryProvider;
import com.amazonaws.endpointdiscovery.StaticEndpointDiscoveryProvider;

// Create custom provider chain
EndpointDiscoveryProvider customChain = new EndpointDiscoveryProviderChain(
    new EnvironmentVariableEndpointDiscoveryProvider(),
    new CustomEndpointDiscoveryProvider("my-config-source"),
    new AwsProfileEndpointDiscoveryProvider(),
    new StaticEndpointDiscoveryProvider(false) // Default fallback
);

// Use custom chain in client
AmazonTimestreamWrite client = AmazonTimestreamWriteClientBuilder.standard()
    .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
    .withRegion(Regions.US_EAST_1)
    .withEndpointDiscoveryProvider(customChain)
    .build();

Advanced Endpoint Discovery Patterns

Conditional Endpoint Discovery

public class ConditionalEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final String environment;
    private final Map<String, Boolean> environmentSettings;
    
    public ConditionalEndpointDiscoveryProvider(String environment) {
        this.environment = environment;
        this.environmentSettings = Map.of(
            "production", true,
            "staging", true,
            "development", false,
            "test", false
        );
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        return environmentSettings.getOrDefault(environment, false);
    }
}

// Usage
EndpointDiscoveryProvider conditionalProvider = 
    new ConditionalEndpointDiscoveryProvider(System.getProperty("environment", "development"));

Service-Specific Endpoint Discovery

public class ServiceSpecificEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final String serviceName;
    private final Map<String, Boolean> serviceSettings;
    
    public ServiceSpecificEndpointDiscoveryProvider(String serviceName) {
        this.serviceName = serviceName;
        this.serviceSettings = loadServiceSettings();
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        return serviceSettings.getOrDefault(serviceName, false);
    }
    
    private Map<String, Boolean> loadServiceSettings() {
        // Configure endpoint discovery per service
        return Map.of(
            "timestream-write", true,
            "timestream-query", true,
            "dax", true,
            "s3", false,
            "dynamodb", false
        );
    }
}

Caching Endpoint Discovery Provider

public class CachingEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final EndpointDiscoveryProvider delegate;
    private final long cacheTimeoutMs;
    private volatile Boolean cachedResult;
    private volatile long lastCacheTime;
    
    public CachingEndpointDiscoveryProvider(EndpointDiscoveryProvider delegate, long cacheTimeoutMs) {
        this.delegate = delegate;
        this.cacheTimeoutMs = cacheTimeoutMs;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        long currentTime = System.currentTimeMillis();
        
        if (cachedResult == null || (currentTime - lastCacheTime) > cacheTimeoutMs) {
            cachedResult = delegate.isEndpointDiscoveryEnabled();
            lastCacheTime = currentTime;
        }
        
        return cachedResult;
    }
    
    @Override
    public void refresh() {
        cachedResult = null;
        delegate.refresh();
    }
}

Error Handling and Fallbacks

Resilient Endpoint Discovery

public class ResilientEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final List<EndpointDiscoveryProvider> providers;
    private final boolean defaultOnError;
    
    public ResilientEndpointDiscoveryProvider(List<EndpointDiscoveryProvider> providers, boolean defaultOnError) {
        this.providers = providers;
        this.defaultOnError = defaultOnError;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        for (EndpointDiscoveryProvider provider : providers) {
            try {
                return provider.isEndpointDiscoveryEnabled();
            } catch (Exception e) {
                // Log error and try next provider
                System.err.println("Endpoint discovery provider failed: " + e.getMessage());
            }
        }
        
        // All providers failed, return default
        return defaultOnError;
    }
    
    @Override
    public void refresh() {
        for (EndpointDiscoveryProvider provider : providers) {
            try {
                provider.refresh();
            } catch (Exception e) {
                // Log error but continue with other providers
                System.err.println("Failed to refresh endpoint discovery provider: " + e.getMessage());
            }
        }
    }
}

Endpoint Discovery with Retry

public class RetryableEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final EndpointDiscoveryProvider delegate;
    private final int maxRetries;
    private final long retryDelayMs;
    
    public RetryableEndpointDiscoveryProvider(EndpointDiscoveryProvider delegate, int maxRetries, long retryDelayMs) {
        this.delegate = delegate;
        this.maxRetries = maxRetries;
        this.retryDelayMs = retryDelayMs;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        Exception lastException = null;
        
        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                return delegate.isEndpointDiscoveryEnabled();
                
            } catch (Exception e) {
                lastException = e;
                
                if (attempt < maxRetries) {
                    try {
                        Thread.sleep(retryDelayMs * (attempt + 1)); // Linear backoff
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("Interrupted during retry", ie);
                    }
                }
            }
        }
        
        throw new RuntimeException("Endpoint discovery failed after " + maxRetries + " retries", lastException);
    }
}

Monitoring and Observability

Endpoint Discovery Metrics

public class MetricsEnabledEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private final EndpointDiscoveryProvider delegate;
    private final AtomicLong enabledCount = new AtomicLong();
    private final AtomicLong disabledCount = new AtomicLong();
    private final AtomicLong errorCount = new AtomicLong();
    
    public MetricsEnabledEndpointDiscoveryProvider(EndpointDiscoveryProvider delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        try {
            boolean enabled = delegate.isEndpointDiscoveryEnabled();
            
            if (enabled) {
                enabledCount.incrementAndGet();
            } else {
                disabledCount.incrementAndGet();
            }
            
            return enabled;
            
        } catch (Exception e) {
            errorCount.incrementAndGet();
            throw e;
        }
    }
    
    // Expose metrics
    public long getEnabledCount() { return enabledCount.get(); }
    public long getDisabledCount() { return disabledCount.get(); }
    public long getErrorCount() { return errorCount.get(); }
    
    public void resetMetrics() {
        enabledCount.set(0);
        disabledCount.set(0);
        errorCount.set(0);
    }
}

Logging Endpoint Discovery Activity

public class LoggingEndpointDiscoveryProvider extends BaseEndpointDiscoveryProvider {
    private static final Logger logger = LoggerFactory.getLogger(LoggingEndpointDiscoveryProvider.class);
    private final EndpointDiscoveryProvider delegate;
    private final String providerName;
    
    public LoggingEndpointDiscoveryProvider(EndpointDiscoveryProvider delegate, String providerName) {
        this.delegate = delegate;
        this.providerName = providerName;
    }
    
    @Override
    public boolean isEndpointDiscoveryEnabled() {
        logger.debug("Checking endpoint discovery status with provider: {}", providerName);
        
        try {
            boolean enabled = delegate.isEndpointDiscoveryEnabled();
            logger.info("Endpoint discovery {} via provider: {}", 
                       enabled ? "ENABLED" : "DISABLED", providerName);
            return enabled;
            
        } catch (Exception e) {
            logger.error("Endpoint discovery check failed for provider: {}", providerName, e);
            throw e;
        }
    }
    
    @Override
    public void refresh() {
        logger.debug("Refreshing endpoint discovery provider: {}", providerName);
        try {
            delegate.refresh();
            logger.debug("Successfully refreshed endpoint discovery provider: {}", providerName);
        } catch (Exception e) {
            logger.error("Failed to refresh endpoint discovery provider: {}", providerName, e);
            throw e;
        }
    }
}

Best Practices

Configuration Best Practices

  1. Use environment-specific settings - Different configurations for dev/staging/production
  2. Implement proper fallbacks - Always provide a default configuration
  3. Cache results appropriately - Avoid excessive configuration lookups
  4. Monitor endpoint discovery usage - Track when discovery is enabled/disabled

Performance Considerations

  1. Cache endpoint discovery results to avoid repeated configuration lookups
  2. Use reasonable timeouts for external configuration sources
  3. Implement circuit breakers for unreliable configuration sources
  4. Consider the impact on cold start times in serverless environments

Security Considerations

  1. Validate configuration sources to prevent configuration injection
  2. Use secure channels for external configuration retrieval
  3. Implement proper access controls for configuration management
  4. Audit endpoint discovery configuration changes

Testing Strategies

  1. Test with discovery enabled and disabled in different environments
  2. Verify fallback behavior when providers fail
  3. Test configuration refresh scenarios
  4. Monitor endpoint discovery metrics in production

Endpoint discovery provides automatic service endpoint optimization, improving performance and reliability by directing traffic to the most appropriate service endpoints based on current network conditions and service topology.

Install with Tessl CLI

npx tessl i tessl/maven-com-amazonaws--aws-java-sdk-core

docs

arn-support.md

authentication.md

client-builders.md

endpoint-discovery.md

exception-handling.md

http-transport.md

index.md

metrics-monitoring.md

protocols.md

regions-endpoints.md

retry-policies.md

utilities.md

waiters.md

tile.json