Skip to content

Fix javadocs, add more tests, remove unnecessary methods #2070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,21 @@ public static String waiterInterfaceJavadoc() {

public static CodeBlock waiterOperationJavadoc(ClassName className, Map.Entry<String, WaiterDefinition> waiterDefinition,
OperationModel operationModel) {
String returnStatement = "WaiterResponse containing either a response or an exception that has matched with the waiter "
+ "success condition";

String asyncReturnStatement = "CompletableFuture containing the WaiterResponse. It completes successfully when the "
+ "resource enters into a desired state or exceptionally when it is determined that the "
+ "resource will never enter into the desired state.";
String javadocs = new DocumentationBuilder().description("Polls {@link $T#$N} API until the desired condition "
+ "{@code $N} is met, "
+ "or until it is determined that the resource will never "
+ "enter into the desired state")
.param(operationModel.getInput().getVariableName(), "the request to be used"
+ " for polling")
.returns(className.simpleName().contains("Async") ?
"CompletableFuture of the WaiterResponse containing either a "
+ "response or an exception that has matched with the waiter "
+ "success condition"
: "WaiterResponse containing either a response or an exception that"
+ " has matched with the waiter success condition")
asyncReturnStatement :
returnStatement)
.build();
return CodeBlock.builder()
.add(javadocs, className, operationModel.getMethodName(), waiterDefinition.getKey())
Expand All @@ -65,7 +68,7 @@ public static CodeBlock waiterOperationConsumerBuilderJavadoc(ClassName clientCl
+ "enter into the desired state. \n "
+ "<p>This is a convenience method to create an instance of "
+ "the request builder without the need "
+ "to create one manually using {@link $T.builder()} ")
+ "to create one manually using {@link $T#builder()} ")
.param(operationModel.getInput().getVariableName(), "The consumer that will"
+ " configure the "
+ "request to be used"
Expand Down Expand Up @@ -94,14 +97,18 @@ public static CodeBlock waiterBuilderMethodJavadoc(ClassName className) {
.build();
}

public static CodeBlock waiterCreateMethodJavadoc(ClassName className) {
public static CodeBlock waiterCreateMethodJavadoc(ClassName waiterClassName, ClassName clientClassName) {
String javadocs = new DocumentationBuilder()
.description("Create an instance of {@link $T} with the default configuration")
.description("Create an instance of {@link $T} with the default configuration. \n"
+ "<p><b>A default {@link $T} will be created to poll resources. It is recommended "
+ "to share a single instance of the waiter created via this method. If it is not desirable "
+ "to share a waiter instance, invoke {@link #close()} to release the resources once the waiter"
+ " is not needed.</b>")
.returns("an instance of {@link $T}")
.build();

return CodeBlock.builder()
.add(javadocs, className, className)
.add(javadocs, waiterClassName, clientClassName, waiterClassName)
.build();
}

Expand All @@ -121,7 +128,7 @@ public static CodeBlock waiterBuilderPollingStrategy() {
public static CodeBlock waiterBuilderPollingStrategyConsumerBuilder() {
String javadocs = new DocumentationBuilder()
.description("This is a convenient method to pass the override configuration without the need to "
+ "create an instance manually via {@link $T.builder()}")
+ "create an instance manually via {@link $T#builder()}")
.param("overrideConfiguration", "The consumer that will configure the overrideConfiguration")
.see("#overrideConfiguration(WaiterOverrideConfiguration)")
.returns("a reference to this object so that method calls can be chained together.")
Expand Down Expand Up @@ -149,7 +156,7 @@ public static CodeBlock waiterBuilderScheduledExecutorServiceJavadoc() {
public static CodeBlock waiterBuilderClientJavadoc(ClassName className) {
String javadocs = new DocumentationBuilder()
.description("Defines the {@link $T} to use when polling a resource")
.description("Sets a custom {@link $T} that will be used to pool the resource \n "
.description("Sets a custom {@link $T} that will be used to poll the resource \n "
+ "<p> This SDK client must be closed by the caller when it is ready to be disposed. The"
+ " SDK will not close the client when the waiter is closed")
.param("client", "the client to send the request")
Expand Down Expand Up @@ -216,4 +223,18 @@ public static CodeBlock waiterOperationWithOverrideConfig(ClassName clientClassN
.add(javadocs, clientClassName, opModel.getMethodName(), waiterDefinition.getKey())
.build();
}

public static CodeBlock waiterMethodInClient(ClassName waiterClassName) {
String javadocs = new DocumentationBuilder()
.description("Create an instance of {@link $T} using this client. \n"
+ "<p>Waiters created via this method are managed by the SDK and resources will be released "
+ "when the service client is closed.")
.returns("an instance of {@link $T}")
.build();

return CodeBlock.builder()
.add(javadocs, waiterClassName, waiterClassName)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import software.amazon.awssdk.codegen.docs.ClientType;
import software.amazon.awssdk.codegen.docs.DocConfiguration;
import software.amazon.awssdk.codegen.docs.SimpleMethodOverload;
import software.amazon.awssdk.codegen.docs.WaiterDocs;
import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod;
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
Expand Down Expand Up @@ -452,7 +453,7 @@ private MethodSpec waiterMethod() {
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.returns(poetExtensions.getAsyncWaiterInterface())
.addStatement("throw new $T()", UnsupportedOperationException.class)
.addJavadoc("Creates an instance of {@link $T} object", poetExtensions.getAsyncWaiterInterface())
.addJavadoc(WaiterDocs.waiterMethodInClient(poetExtensions.getAsyncWaiterInterface()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import software.amazon.awssdk.codegen.docs.ClientType;
import software.amazon.awssdk.codegen.docs.DocConfiguration;
import software.amazon.awssdk.codegen.docs.SimpleMethodOverload;
import software.amazon.awssdk.codegen.docs.WaiterDocs;
import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod;
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
Expand Down Expand Up @@ -465,7 +466,7 @@ private MethodSpec waiterMethod() {
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addStatement("throw new $T()", UnsupportedOperationException.class)
.returns(poetExtensions.getSyncWaiterInterface())
.addJavadoc("Creates an instance of {@link $T} object", poetExtensions.getSyncWaiterInterface())
.addJavadoc(WaiterDocs.waiterMethodInClient(poetExtensions.getSyncWaiterInterface()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public TypeSpec poetSpec() {
.build());
result.addMethod(MethodSpec.methodBuilder("create")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc(WaiterDocs.waiterCreateMethodJavadoc(className()))
.addJavadoc(WaiterDocs.waiterCreateMethodJavadoc(className(),
clientClassName()))
.returns(className())
.addStatement("return $T.builder().build()", waiterImplName())
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ public interface QueryAsyncWaiter extends SdkAutoCloseable {
*
* @param aPostOperationRequest
* the request to be used for polling
* @return CompletableFuture of the WaiterResponse containing either a response or an exception that has matched
* with the waiter success condition
* @return CompletableFuture containing the WaiterResponse. It completes successfully when the resource enters into
* a desired state or exceptionally when it is determined that the resource will never enter into the
* desired state.
*/
default CompletableFuture<WaiterResponse<APostOperationResponse>> waitUntilPostOperationSuccess(
APostOperationRequest aPostOperationRequest) {
Expand All @@ -38,7 +39,7 @@ default CompletableFuture<WaiterResponse<APostOperationResponse>> waitUntilPostO
* met, or until it is determined that the resource will never enter into the desired state.
* <p>
* This is a convenience method to create an instance of the request builder without the need to create one manually
* using {@link APostOperationRequest.builder()}
* using {@link APostOperationRequest#builder()}
*
* @param aPostOperationRequest
* The consumer that will configure the request to be used for polling
Expand Down Expand Up @@ -97,7 +98,11 @@ static Builder builder() {
}

/**
* Create an instance of {@link QueryAsyncWaiter} with the default configuration
* Create an instance of {@link QueryAsyncWaiter} with the default configuration.
* <p>
* <b>A default {@link QueryAsyncClient} will be created to poll resources. It is recommended to share a single
* instance of the waiter created via this method. If it is not desirable to share a waiter instance, invoke
* {@link #close()} to release the resources once the waiter is not needed.</b>
*
* @return an instance of {@link QueryAsyncWaiter}
*/
Expand Down Expand Up @@ -130,7 +135,7 @@ interface Builder {

/**
* This is a convenient method to pass the override configuration without the need to create an instance
* manually via {@link WaiterOverrideConfiguration.builder()}
* manually via {@link WaiterOverrideConfiguration#builder()}
*
* @param overrideConfiguration
* The consumer that will configure the overrideConfiguration
Expand All @@ -144,7 +149,7 @@ default Builder overrideConfiguration(Consumer<WaiterOverrideConfiguration.Build
}

/**
* Sets a custom {@link QueryAsyncClient} that will be used to pool the resource
* Sets a custom {@link QueryAsyncClient} that will be used to poll the resource
* <p>
* This SDK client must be closed by the caller when it is ready to be disposed. The SDK will not close the
* client when the waiter is closed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ default WaiterResponse<APostOperationResponse> waitUntilPostOperationSuccess(APo
* until it is determined that the resource will never enter into the desired state.
* <p>
* This is a convenience method to create an instance of the request builder without the need to create one manually
* using {@link APostOperationRequest.builder()}
* using {@link APostOperationRequest#builder()}
*
* @param aPostOperationRequest
* The consumer that will configure the request to be used for polling
Expand Down Expand Up @@ -94,7 +94,11 @@ static Builder builder() {
}

/**
* Create an instance of {@link QueryWaiter} with the default configuration
* Create an instance of {@link QueryWaiter} with the default configuration.
* <p>
* <b>A default {@link QueryClient} will be created to poll resources. It is recommended to share a single instance
* of the waiter created via this method. If it is not desirable to share a waiter instance, invoke {@link #close()}
* to release the resources once the waiter is not needed.</b>
*
* @return an instance of {@link QueryWaiter}
*/
Expand All @@ -115,7 +119,7 @@ interface Builder {

/**
* This is a convenient method to pass the override configuration without the need to create an instance
* manually via {@link WaiterOverrideConfiguration.builder()}
* manually via {@link WaiterOverrideConfiguration#builder()}
*
* @param overrideConfiguration
* The consumer that will configure the overrideConfiguration
Expand All @@ -129,7 +133,7 @@ default Builder overrideConfiguration(Consumer<WaiterOverrideConfiguration.Build
}

/**
* Sets a custom {@link QueryClient} that will be used to pool the resource
* Sets a custom {@link QueryClient} that will be used to poll the resource
* <p>
* This SDK client must be closed by the caller when it is ready to be disposed. The SDK will not close the
* client when the waiter is closed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public final class DefaultWaiterResponse<T> implements WaiterResponse<T> {
private final T result;
private final Throwable exception;
private final int attemptsExecuted;
private final ResponseOrException<T> matched;

private DefaultWaiterResponse(Builder<T> builder) {
mutuallyExclusive("response and exception are mutually exclusive, set only one on the Builder",
Expand All @@ -39,16 +40,18 @@ private DefaultWaiterResponse(Builder<T> builder) {
this.exception = builder.exception;
this.attemptsExecuted = Validate.paramNotNull(builder.attemptsExecuted, "attemptsExecuted");
Validate.isPositive(builder.attemptsExecuted, "attemptsExecuted");
matched = result != null ?
ResponseOrException.response(result) :
ResponseOrException.exception(exception);
}


public static <T> Builder<T> builder() {
return new Builder<>();
}

@Override
public ResponseOrException<T> matched() {
return result != null ? ResponseOrException.response(result) : ResponseOrException.exception(exception);
return matched;
}

@Override
Expand Down Expand Up @@ -89,7 +92,9 @@ public String toString() {
ToString toString = ToString.builder("DefaultWaiterResponse")
.add("attemptsExecuted", attemptsExecuted);

matched().apply(r -> toString.add("response", r), e -> toString.add("exception", e.getMessage()));
matched.response().ifPresent(r -> toString.add("response", result));
matched.exception().ifPresent(r -> toString.add("exception", exception));

return toString.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,74 +16,53 @@
package software.amazon.awssdk.core.internal.waiters;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.annotations.SdkPublicApi;

/**
* Represents a value that can be either a response or a Throwable
*
* @param <R> response type
*/
@SdkProtectedApi
@SdkPublicApi
public final class ResponseOrException<R> {

private final Optional<R> response;
private final Optional<Throwable> exception;

private ResponseOrException(Optional<R> l, Optional<Throwable> r) {
response = l;
exception = r;
private ResponseOrException(Optional<R> response, Optional<Throwable> exception) {
this.response = response;
this.exception = exception;
}

/**
* Maps the Either to a type and returns the resolved value (which may be from the left or the right value).
*
* @param lFunc Function that maps the left value if present.
* @param rFunc Function that maps the right value if present.
* @param <T> Type that both the left and right should be mapped to.
* @return Mapped value from either lFunc or rFunc depending on which value is present.
* @return the optional response that has matched with the waiter success condition
*/
public <T> T map(
Function<? super R, ? extends T> lFunc,
Function<? super Throwable, ? extends T> rFunc) {
return response.<T>map(lFunc).orElseGet(() -> exception.map(rFunc).get());
}

public Optional<R> response() {
return response;
}

public Optional<Throwable> exception() {
return exception;
}

/**
* Apply the consumers to the left or the right value depending on which is present.
*
* @param lFunc Consumer of left value, invoked if left value is present.
* @param rFunc Consumer of right value, invoked if right value is present.
* @return the optional exception that has matched with the waiter success condition
*/
public void apply(Consumer<? super R> lFunc, Consumer<? super Throwable> rFunc) {
response.ifPresent(lFunc);
exception.ifPresent(rFunc);
public Optional<Throwable> exception() {
return exception;
}

/**
* Create a new Either with the left type.
* Create a new ResponseOrException with the response
*
* @param value Left value
* @param <R> Left type
* @param value response
* @param <R> Response type
*/
public static <R> ResponseOrException<R> response(R value) {
return new ResponseOrException<>(Optional.of(value), Optional.empty());
}

/**
* Create a new Either with the right type.
* Create a new ResponseOrException with the exception
*
* @param value Right value
* @param <R> Left type
* @param value exception
* @param <R> Response type
*/
public static <R> ResponseOrException<R> exception(Throwable value) {
return new ResponseOrException<>(Optional.empty(), Optional.of(value));
Expand Down
Loading