|
| 1 | +# BREAKING: Overhaul of Endpoint Discovery features |
| 2 | + |
| 3 | +An upcoming release of the **AWS SDK for Kotlin** will introduce improvements and fixes for |
| 4 | +[Endpoint Discovery](https://docs.aws.amazon.com/timestream/latest/developerguide/Using-API.endpoint-discovery.how-it-works.html), |
| 5 | +which is required when using [Amazon Timestream](https://aws.amazon.com/timestream/) and optional when using |
| 6 | +[Amazon DynamoDB](https://aws.amazon.com/dynamodb/). If you do not use either of these services, you are unaffected by |
| 7 | +these changes. |
| 8 | + |
| 9 | +## Release target |
| 10 | + |
| 11 | +This overhaul is targeted to be included in the **v1.5** release of the SDK. See |
| 12 | +[the **v1.5** announcment](TEMP-V1Dot5-Announcment.md) for more details and other important changes. |
| 13 | + |
| 14 | +## What's changing |
| 15 | + |
| 16 | +The goal of this overhaul is to make Endpoint Discovery easier to configure, customize, and disable. To accomplish this, |
| 17 | +Several aspects of Endpoint Discovery are changing: |
| 18 | + |
| 19 | +* The service-specific endpoint discoverer classes are changing to interfaces to allow fully custom discoverer |
| 20 | + implementations |
| 21 | +* Usages of the `ReadThroughCache` class are being relaxed to use the new `ExpiringKeyedCache` interface to allow fully |
| 22 | + custom cache implementations |
| 23 | + * The current implementation of `ReadThroughCache` is now provided in the new `PeriodicSweepCache` class, which |
| 24 | + implements the new `ExpiringKeyedCache` interface |
| 25 | +* The `endpointUrl` configuration parameter now takes precedence over endpoint discoverers. If you've configured both a |
| 26 | + custom `endpointUrl` and the service client has Endpoint Discovery enabled, the custom `endpointUrl` will be used and |
| 27 | + Endpoint Discovery will effectively be disabled. |
| 28 | +* Endpoint Discovery settings will now be resolved from |
| 29 | + [environmental configuration](https://docs.aws.amazon.com/sdkref/latest/guide/feature-endpoint-discovery.html) sources |
| 30 | + used by other AWS SDKs, including the following sources: |
| 31 | + * The `aws.endpointDiscoveryEnabled` system property (JVM only) |
| 32 | + * The `AWS_ENABLE_ENDPOINT_DISCOVERY` environment variable |
| 33 | + * The `endpoint_discovery_enabled` [profile key](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) |
| 34 | + |
| 35 | +## How to migrate |
| 36 | + |
| 37 | +Migrating existing code using Endpoint Discovery may require no modifications if you do not customize discovery or use |
| 38 | +custom endpoints. Your code may require modifications in the following scenarios: |
| 39 | + |
| 40 | +### Specifying a custom endpoint discoverer |
| 41 | + |
| 42 | +Previously, the Timestream and DynamoDB service clients provided an `endpointDiscoverer` configuration parameter. The |
| 43 | +type of this parameter was specific to the client. For instance, the Timestream Query client's `endpointDiscoverer` was |
| 44 | +of type `TimestreamQueryEndpointDiscoverer`. Unfortunately, this type was a non-`open` `class` meaning there was no easy |
| 45 | +way to provide a custom implementation. |
| 46 | + |
| 47 | +After this update, the client-specific parameter type is now an `interface` which may be fully implemented by users. The |
| 48 | +default implementation (e.g., `DefaultTimestreamQueryEndpointDiscoverer`) is recommended in most scenarios. If you wish |
| 49 | +to provide a custom implementation, you may do so by setting the `endpointDiscoverer` parameter: |
| 50 | + |
| 51 | +```kotlin |
| 52 | +val timestreamQuery = TimestreamQueryClient.fromEnvironment { |
| 53 | + endpointDiscoverer = MyCustomTimestreamQueryEndpointDiscoverer() |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +See the client-specific interfaces (e.g., `TimestreamQueryEndpointDiscoverer`) for more details about implementation. |
| 58 | + |
| 59 | +### Specifying custom caching behavior |
| 60 | + |
| 61 | +Previously, the default implementations of endpoint discoverers used an internal cache to avoid re-discovering endpoints |
| 62 | +for every new operation invocation, provided by the `ReadThroughCache` class. This meant there was no easy way to |
| 63 | +customize or replace caching behavior. |
| 64 | + |
| 65 | +After this update, the new `ExpiringKeyedCache` interface defines the semantics and requirements for caching while the |
| 66 | +new `PeriodicSweepCache` class provides the old `ReadThroughCache` implementation. The default caching behavior included |
| 67 | +in the default endpoint discoverers (e.g., `DefaultTimestreamQueryEndpointDiscoverer`) is recommended in most scenarios. |
| 68 | +If you wish to use custom caching behavior, you may do so by passing an `ExpiringKeyedCache` implementation to the |
| 69 | +default discoverer constructor: |
| 70 | + |
| 71 | +```kotlin |
| 72 | +val myCache = PeriodicSweepCache<DiscoveryParams, Host>(minimumSweepPeriod = 15.minutes) |
| 73 | +val timestreamQuery = TimestreamQueryClient.fromEnvironment { |
| 74 | + endpointDiscoverer = DefaultTimestreamQueryEndpointDiscoverer(cache = myCache) |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +### Overriding endpoint discovery with `endpointUrl` |
| 79 | + |
| 80 | +Previously, the `endpointUrl` configuration parameter was effectively ignored when Endpoint Discovery was in use. This |
| 81 | +made it difficult to use custom endpoints as might be desirable when using mock implementations, non-AWS services, etc. |
| 82 | + |
| 83 | +After this update, the `endpointUrl` configuration parameter, if set, now takes precedence over any `endpointDiscoverer` |
| 84 | +set on the same client. The default discoverer _without_ a custom endpoint URL is recommended in most scenarios. If you |
| 85 | +wish to use a custom endpoint, you may do so by setting `endpointUrl`: |
| 86 | + |
| 87 | +```kotlin |
| 88 | +TimestreamQueryClient.fromEnvironment { |
| 89 | + endpointUrl = Url.parse("http://localhost:2345") |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +In the above example, the **localhost** address specified in `endpointUrl` will _always_ be used and no additional calls |
| 94 | +will be made to support Endpoint Discovery. This behavior is implementation specific in the default discoverer. If you |
| 95 | +implement your own endpoint discoverer, you will need to handle situations where the `endpointUrl` is set: |
| 96 | + |
| 97 | +```kotlin |
| 98 | +class MyCustomTimestreamQueryEndpointDiscoverer : TimestreamQueryEndpointDiscoverer { |
| 99 | + override fun asEndpointResolver(client: TimestreamQueryClient, delegate: EndpointResolver) = EndpointResolver { |
| 100 | + if (client.config.endpointUrl == null) { |
| 101 | + // No custom endpoint set, do normal Endpoint Discovery logic |
| 102 | + TODO("implementation omitted") |
| 103 | + } else { |
| 104 | + // Custom endpoint set, bypass Endpoint Discovery logic |
| 105 | + Endpoint(client.config.endpointUrl) |
| 106 | + } |
| 107 | + } |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +### Customizing Endpoint Discovery with environmental configuration |
| 112 | + |
| 113 | +Previously, the settings for Endpoint Discovery were controlled through explicitly-set parameters in client |
| 114 | +configuration because the **AWS SDK for Kotlin** did not support the |
| 115 | +[standard environmental configuration](https://docs.aws.amazon.com/sdkref/latest/guide/feature-endpoint-discovery.html) |
| 116 | +sources used by other AWS SDKs. This made it difficult to universally configure Endpoint Discovery at a host level, |
| 117 | +file level, or in a multi-tenant environment. |
| 118 | + |
| 119 | +After this update, Endpoint Discovery settings will be resolved from the following sources in descending priority: |
| 120 | +1. Any explicit configuration provided in the client configuration parameter `endpointDiscoverer` (including |
| 121 | + [via `withConfig`](https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/override-client-config.html)) |
| 122 | +2. The `aws.endpointDiscoveryEnabled` system property (Kotlin/JVM only) |
| 123 | +3. The `AWS_ENABLE_ENDPOINT_DISCOVERY ` environment variable |
| 124 | +4. The `endpoint_discovery_enabled` profile key |
| 125 | + |
| 126 | +A source will only be used if the higher-priority source(s) above it are not configured. For instance, the |
| 127 | +`aws.endpointDiscoveryEnabled` system property will be ignored if `endpointDiscoverer` is explicitly configured. |
| 128 | + |
| 129 | +## Additional info |
| 130 | + |
| 131 | +For more information about Endpoint Discovery, see the following resources: |
| 132 | + |
| 133 | +* [AWS SDKs and Tools Reference Guide](https://docs.aws.amazon.com/sdkref/latest/guide/feature-endpoint-discovery.html) |
| 134 | +* [How the endpoint discovery pattern works](https://docs.aws.amazon.com/timestream/latest/developerguide/Using-API.endpoint-discovery.how-it-works.html) |
| 135 | +* [Implementing the endpoint discovery pattern](https://docs.aws.amazon.com/timestream/latest/developerguide/Using-API.endpoint-discovery.describe-endpoints.implementation.html) |
| 136 | +* Amazon DynamoDB's [`DescribeEndpoints` operation](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeEndpoints.html) |
| 137 | +* Timestream Query's [`DescribeEndpoints` operation](https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_DescribeEndpoints.html) |
| 138 | +* Timestream Write's [`DescribeEndpoints` operation](https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeEndpoints.html) |
| 139 | + |
| 140 | +## Feedback |
| 141 | + |
| 142 | +If you have any questions concerning this change, please feel free to engage with us in this discussion. If you |
| 143 | +encounter a bug with this change, please |
| 144 | +[file an issue](https://github.com/awslabs/aws-sdk-kotlin/issues/new?template=bug_report.yml). |
0 commit comments