+ * If not specified, defaults to {@link Executors#newScheduledThreadPool} with a default value of 3 thread in the + * pool. + * + * @param scheduledExecutorService the ScheduledExecutorService to use for retry attempt. + * @return a reference to this builder + */ + Builder scheduledExecutorService(ScheduledExecutorService scheduledExecutorService); + + /** + * Define the http client used by the Ec2 Metadata client. If provided, the Ec2MetadataClient will NOT manage the + * lifetime if the httpClient and must therefore be closed explicitly by calling the {@link SdkAsyncHttpClient#close()} + * method on it. + *
+ * If not specified, the IMDS client will look for a SdkAsyncHttpClient class included in the classpath of the
+ * application and creates a new instance of that class, managed by the IMDS Client, that will be closed when the IMDS
+ * Client is closed. If no such class can be found, will throw a {@link SdkClientException}.
+ *
+ * @param httpClient the http client
+ * @return a reference to this builder
+ */
+ Builder httpClient(SdkAsyncHttpClient httpClient);
+
+ /**
+ * An http client builder used to retrieve an instance of an {@link SdkAsyncHttpClient}. If specified, the Ec2
+ * Metadata Client will use the instance returned by the builder and manage its lifetime by closing the http client
+ * once the Ec2 Client itself is closed.
+ *
+ * @param builder the builder to used to retrieve an instance.
+ * @return a reference to this builder
+ */
+ Builder httpClient(SdkAsyncHttpClient.Builder> builder);
+ }
+}
diff --git a/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClient.java b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClient.java
new file mode 100644
index 000000000000..57a40d602e39
--- /dev/null
+++ b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClient.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.imds;
+
+import software.amazon.awssdk.annotations.SdkPublicApi;
+import software.amazon.awssdk.core.exception.SdkClientException;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
+import software.amazon.awssdk.imds.internal.DefaultEc2MetadataClient;
+import software.amazon.awssdk.utils.SdkAutoCloseable;
+
+
+/**
+ * Interface to represent the Ec2Metadata Client Class. Used to access instance metadata from a running instance.
+ */
+@SdkPublicApi
+public interface Ec2MetadataClient extends SdkAutoCloseable {
+
+ /**
+ * Gets the specified instance metadata value by the given path. For more information about instance metadata, check the
+ * Instance metadata documentation
+ *
+ * @param path Input path
+ * @return Instance metadata value as part of MetadataResponse Object
+ */
+ Ec2MetadataResponse get(String path);
+
+ /**
+ * Create an {@link Ec2MetadataClient} instance using the default values.
+ *
+ * @return the client instance.
+ */
+ static Ec2MetadataClient create() {
+ return builder().build();
+ }
+
+ /**
+ * Creates a default builder for {@link Ec2MetadataClient}.
+ */
+ static Builder builder() {
+ return DefaultEc2MetadataClient.builder();
+ }
+
+ /**
+ * The builder definition for a {@link Ec2MetadataClient}.
+ */
+ interface Builder extends Ec2MetadataClientBuilder
+ * If not specified, the IMDS client will look for a SdkHttpClient class included in the classpath of the
+ * application and creates a new instance of that class, managed by the IMDS Client, that will be closed when the IMDS
+ * Client is closed. If no such class can be found, will throw a {@link SdkClientException}.
+ *
+ * @param httpClient the http client
+ * @return a reference to this builder
+ */
+ Builder httpClient(SdkHttpClient httpClient);
+
+ /**
+ * A http client builder used to retrieve an instance of an {@link SdkHttpClient}. If specified, the Ec2 Metadata Client
+ * will use the instance returned by the builder and manage its lifetime by closing the http client once the Ec2 Client
+ * itself is closed.
+ *
+ * @param builder the builder to used to retrieve an instance.
+ * @return a reference to this builder
+ */
+ Builder httpClient(SdkHttpClient.Builder> builder);
+ }
+
+}
diff --git a/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClientBuilder.java b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClientBuilder.java
new file mode 100644
index 000000000000..5cb056f12c51
--- /dev/null
+++ b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataClientBuilder.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.imds;
+
+import java.net.URI;
+import java.time.Duration;
+import java.util.function.Consumer;
+import software.amazon.awssdk.annotations.SdkPublicApi;
+import software.amazon.awssdk.core.retry.RetryMode;
+import software.amazon.awssdk.core.retry.backoff.BackoffStrategy;
+import software.amazon.awssdk.imds.internal.Ec2MetadataEndpointProvider;
+import software.amazon.awssdk.utils.builder.SdkBuilder;
+
+/**
+ * Base shared builder interface for Ec2MetadataClients, sync and async.
+ * @param the Builder Type
+ * @param
+ * If not specified, defaults to 3 retry attempts and a {@link BackoffStrategy#defaultStrategy()} backoff strategy} that
+ * uses {@link RetryMode#STANDARD}. Can be also specified by using the
+ * {@link Ec2MetadataClientBuilder#retryPolicy(Consumer)} method. if any of the retryPolicy methods are called multiple times,
+ * only the last invocation will be considered.
+ *
+ * @param retryPolicy The retry policy which includes the number of retry attempts for any failed request.
+ * @return a reference to this builder
+ */
+ B retryPolicy(Ec2MetadataRetryPolicy retryPolicy);
+
+ /**
+ * Define the retry policy which includes the number of retry attempts for any failed request. Can be used instead of
+ * {@link Ec2MetadataClientBuilder#retryPolicy(Ec2MetadataRetryPolicy)} to use a "fluent consumer" syntax. User
+ * should not manually build the builder in the consumer.
+ *
+ * If not specified, defaults to 3 retry attempts and a {@link BackoffStrategy#defaultStrategy()} backoff strategy} that
+ * uses {@link RetryMode#STANDARD}. Can be also specified by using the
+ * {@link Ec2MetadataClientBuilder#retryPolicy(Ec2MetadataRetryPolicy)} method. if any of the retryPolicy methods are
+ * called multiple times, only the last invocation will be considered.
+ *
+ * @param builderConsumer the consumer
+ * @return a reference to this builder
+ */
+ B retryPolicy(Consumer
+ * If not specified, the IMDS client will attempt to automatically resolve the endpoint value
+ * based on the logic of {@link Ec2MetadataEndpointProvider}.
+ *
+ * @param endpoint The endpoint of IMDS.
+ * @return a reference to this builder
+ */
+ B endpoint(URI endpoint);
+
+ /**
+ * Define the Time to live (TTL) of the token. The token represents a logical session. The TTL specifies the length of time
+ * that the token is valid and, therefore, the duration of the session. Defaults to 21,600 seconds (6 hours) if not specified.
+ *
+ * @param tokenTtl The Time to live (TTL) of the token.
+ * @return a reference to this builder
+ */
+ B tokenTtl(Duration tokenTtl);
+
+ /**
+ * Define the endpoint mode of IMDS. Supported values include IPv4 and IPv6. Used to determine the endpoint of the IMDS
+ * Client only if {@link Ec2MetadataClientBuilder#endpoint(URI)} is not specified. Only one of both endpoint or endpoint mode
+ * but not both. If both are specified in the Builder, a {@link IllegalArgumentException} will be thrown.
+ *
+ * If not specified, the IMDS client will attempt to automatically resolve the endpoint mode value
+ * based on the logic of {@link Ec2MetadataEndpointProvider}.
+ *
+ * @param endpointMode The endpoint mode of IMDS. Supported values include IPv4 and IPv6.
+ * @return a reference to this builder
+ */
+ B endpointMode(EndpointMode endpointMode);
+
+}
diff --git a/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataResponse.java b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataResponse.java
new file mode 100644
index 000000000000..6cb27461aaed
--- /dev/null
+++ b/core/imds/src/main/java/software/amazon/awssdk/imds/Ec2MetadataResponse.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.imds;
+
+import java.io.UncheckedIOException;
+import java.util.Arrays;
+import java.util.List;
+import software.amazon.awssdk.annotations.SdkPublicApi;
+import software.amazon.awssdk.core.document.Document;
+import software.amazon.awssdk.imds.internal.unmarshall.document.DocumentUnmarshaller;
+import software.amazon.awssdk.protocols.jsoncore.JsonNode;
+import software.amazon.awssdk.protocols.jsoncore.JsonNodeParser;
+import software.amazon.awssdk.thirdparty.jackson.core.JsonParseException;
+import software.amazon.awssdk.utils.ToString;
+import software.amazon.awssdk.utils.Validate;
+
+/**
+ * This class is used for response handling and parsing the metadata fetched by the get call in the {@link Ec2MetadataClient}
+ * interface. It provides convenience methods to the users to parse the metadata as a String and List. Also provides
+ * ways to parse the metadata as Document type if it is in the json format.
+ */
+@SdkPublicApi
+public final class Ec2MetadataResponse {
+
+ private static final JsonNodeParser JSON_NODE_PARSER = JsonNode.parserBuilder().removeErrorLocations(true).build();
+
+ private final String body;
+
+ private Ec2MetadataResponse(String body) {
+ this.body = Validate.notNull(body, "Metadata is null");
+ }
+
+ /**
+ * Create a {@link Ec2MetadataResponse} with the given body as it's content.
+ * @param body the content of the response
+ * @return a {@link Ec2MetadataResponse} with the given body as it's content.
+ */
+ public static Ec2MetadataResponse create(String body) {
+ return new Ec2MetadataResponse(body);
+ }
+
+ /**
+ * @return String Representation of the Metadata Response Body.
+ */
+ public String asString() {
+ return body;
+ }
+
+ /**
+ * Splits the Metadata response body on new line character and returns it as a list.
+ * @return The Metadata response split on each line.
+ */
+ public List
+ * When using the {@link #builder()} the SDK will use default values for fields that are not provided.A custom BackoffStrategy
+ * can be used to construct a policy or a default {@link BackoffStrategy} is used.
+ *
+ * @see BackoffStrategy for a list of SDK provided backoff strategies
+ */
+@SdkPublicApi
+public final class Ec2MetadataRetryPolicy implements ToCopyableBuilderget
are made while the token is expired, all CompletableFuture returned
+ * will be completed once the single refresh process completes.
+ *
+ */
+@SdkInternalApi
+final class AsyncTokenCache implements Supplier
+ *
+ * (the default endpoint mode is IPV4).
+ * @param endpointMode Used only if an endpoint value is not specified. If so, this method will use the endpointMode to
+ * choose the default value to return.
+ * @return the String representing the endpoint to be used,
+ */
+ public String resolveEndpoint(EndpointMode endpointMode) {
+ Optional> responses = CompletableFuture
+ .allOf(requests.toArray(new CompletableFuture[0]))
+ .thenApply(unusedVoid -> requests.stream()
+ .map(CompletableFuture::join)
+ .collect(Collectors.toList()));
+
+ List