下面列出了org.apache.http.concurrent.BasicFuture#com.amazonaws.AmazonWebServiceRequest 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public <RequestT extends AmazonWebServiceRequest, ResultT extends AmazonWebServiceResult<ResponseMetadata>>
ResultT
injectCredentialsAndInvoke(final RequestT request, final Function<RequestT, ResultT> requestFunction) {
request.setRequestCredentialsProvider(v1CredentialsProvider);
try {
ResultT respose = requestFunction.apply(request);
logRequestMetadata(request, respose);
return respose;
} catch (final Throwable e) {
loggerProxy.log(String.format("Failed to execute remote function: {%s}", e.getMessage()));
throw e;
} finally {
request.setRequestCredentialsProvider(null);
}
}
@Test
public void asyncActionCompletable() throws Exception {
AmazonWebServiceRequest someRequest = AmazonWebServiceRequest.NOOP;
final MockAsyncClient<AmazonWebServiceRequest, String> client = new MockAsyncClient<>(someRequest, "some response");
final Completable completable = AwsObservableExt.asyncActionCompletable(factory -> client.someAsyncOperation(factory.handler(
(req, resp) -> {
assertEquals(someRequest, req);
assertEquals("some response", resp);
},
(t) -> {
throw new IllegalStateException("Should never be here");
}
)));
TestScheduler testScheduler = Schedulers.test();
final AssertableSubscriber<Void> subscriber = completable.subscribeOn(testScheduler).test();
testScheduler.triggerActions();
subscriber.assertNotCompleted();
client.run();
testScheduler.triggerActions();
subscriber.assertCompleted();
}
@Test
public void asyncActionSingle() throws Exception {
AmazonWebServiceRequest someRequest = AmazonWebServiceRequest.NOOP;
final MockAsyncClient<AmazonWebServiceRequest, String> client = new MockAsyncClient<>(someRequest, "some response");
Single<String> single = AwsObservableExt.asyncActionSingle(supplier -> client.someAsyncOperation(supplier.handler()));
TestScheduler testScheduler = Schedulers.test();
final AssertableSubscriber<String> subscriber = single.subscribeOn(testScheduler).test();
testScheduler.triggerActions();
subscriber.assertNoValues();
subscriber.assertNotCompleted();
client.run();
testScheduler.triggerActions();
subscriber.assertValueCount(1);
subscriber.assertValue("some response");
subscriber.assertCompleted();
}
void waitAndPrintChangeSetEvents(String stack, String changeSet, Waiter<DescribeChangeSetRequest> waiter, PollConfiguration pollConfiguration) throws ExecutionException {
final BasicFuture<AmazonWebServiceRequest> waitResult = new BasicFuture<>(null);
waiter.runAsync(new WaiterParameters<>(new DescribeChangeSetRequest().withStackName(stack).withChangeSetName(changeSet)).withPollingStrategy(this.pollingStrategy(pollConfiguration)), new WaiterHandler() {
@Override
public void onWaitSuccess(AmazonWebServiceRequest request) {
waitResult.completed(request);
}
@Override
public void onWaitFailure(Exception e) {
waitResult.failed(e);
}
});
this.waitAndPrintEvents(stack, pollConfiguration, waitResult);
}
void waitAndPrintStackEvents(String stack, Waiter<DescribeStacksRequest> waiter, PollConfiguration pollConfiguration) throws ExecutionException {
final BasicFuture<AmazonWebServiceRequest> waitResult = new BasicFuture<>(null);
waiter.runAsync(new WaiterParameters<>(new DescribeStacksRequest().withStackName(stack)).withPollingStrategy(this.pollingStrategy(pollConfiguration)), new WaiterHandler() {
@Override
public void onWaitSuccess(AmazonWebServiceRequest request) {
waitResult.completed(request);
}
@Override
public void onWaitFailure(Exception e) {
waitResult.failed(e);
}
});
this.waitAndPrintEvents(stack, pollConfiguration, waitResult);
}
/**
* Creates a DynamoDB write request based on the DynamoDB Stream record.
*
* @param record
* The DynamoDB Stream record containing information about the update to a DynamoDB table
* @return A DynamoDB request based on the DynamoDB Stream record
*/
private AmazonWebServiceRequest createRequest(final Record record) {
final String eventName = record.getEventName();
final AmazonWebServiceRequest request;
if (eventName.equalsIgnoreCase(OperationType.INSERT.toString()) || eventName.equalsIgnoreCase(OperationType.MODIFY.toString())) {
// For INSERT or MODIFY: Put the new image in the DynamoDB table
PutItemRequest putItemRequest = new PutItemRequest();
putItemRequest.setItem(record.getDynamodb().getNewImage());
putItemRequest.setTableName(getTableName());
request = putItemRequest;
} else if (eventName.equalsIgnoreCase(OperationType.REMOVE.toString())) {
// For REMOVE: Delete the item from the DynamoDB table
DeleteItemRequest deleteItemRequest = new DeleteItemRequest();
deleteItemRequest.setKey(record.getDynamodb().getKeys());
deleteItemRequest.setTableName(getTableName());
request = deleteItemRequest;
} else {
// This should only happen if DynamoDB Streams adds/changes its operation types
log.warn("Unsupported operation type detected: " + eventName + ". Record: " + record);
request = null;
}
if (null != request) {
request.getRequestClientOptions().appendUserAgent(USER_AGENT);
}
return request;
}
private <Y> Request<Y> prepareRequest(Request<Y> request, ExecutionContext executionContext, boolean signRequest) {
request.setEndpoint(endpoint);
request.setTimeOffset(timeOffset);
AWSCredentials credentials = awsCredentialsProvider.getCredentials();
AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
if (originalRequest != null && originalRequest.getRequestCredentials() != null) {
credentials = originalRequest.getRequestCredentials();
}
if (signRequest) {
// expiration date is not currently supported on service side, but presignRequest method requires
// this argument so one with default value is provided.
Date expirationDate = DateTime.now(DateTimeZone.UTC)
.plusMinutes(DEFAULT_GET_REQUEST_EXPIRATION_MINUTES).toDate();
signer.presignRequest(request, credentials, expirationDate);
} else {
executionContext.setSigner(signer);
executionContext.setCredentials(credentials);
}
return request;
}
private static Method tryFindClientMethod(Object client, String name) {
// TODO: Cache me.
for (Method method : client.getClass().getMethods()) {
if (!method.getName().equals(name)) {
continue;
}
Class<?>[] parameters = method.getParameterTypes();
if (parameters.length != 1) {
continue;
}
// This is the inverse of the normal approach of findMethod() -
// we're looking for a method which will accept a specific subtype
// of AmazonWebServiceRequest, without worrying overmuch about
// what subtype it is. We'll create an object of the appropriate
// type and fill it in.
if (AmazonWebServiceRequest.class.isAssignableFrom(parameters[0])) {
return method;
}
}
return null;
}
/**
* Performs the given action on this resource. This always involves a
* request to the service. It may mark the cached attributes of this
* resource object dirty.
*
* @param name the name of the action to perform
* @param request the client-specified request object
* @param extractor an optional result extractor object
* @return the result of executing the action
*/
public ActionResult performAction(
String name,
AmazonWebServiceRequest request,
ResultCapture<?> extractor) {
ActionModel action = resourceModel.getAction(name);
if (action == null) {
throw new UnsupportedOperationException(
"Resource does not support the action " + name);
}
// The facade generator will ensure we only ever pass in an
// appropriately-typed extractor object.
@SuppressWarnings("unchecked")
ResultCapture<Object> erasedExtractor =
(ResultCapture<Object>) extractor;
return ActionUtils.perform(this, action, request, erasedExtractor);
}
public ActionResult performAction(
String name,
AmazonWebServiceRequest request,
ResultCapture<?> extractor) {
ActionModel action = model.getAction(name);
if (action == null) {
throw new UnsupportedOperationException(
"Service does not support the action " + name);
}
// The facade generator will ensure we only ever pass in an
// appropriately-typed extractor object.
@SuppressWarnings("unchecked")
ResultCapture<Object> erasedExtractor =
(ResultCapture<Object>) extractor;
return ActionUtils.perform(this, action, request, erasedExtractor);
}
private <RequestT extends AmazonWebServiceRequest, ResultT extends AmazonWebServiceResult<ResponseMetadata>>
void
logRequestMetadata(final RequestT request, final ResultT response) {
try {
String requestName = request.getClass().getSimpleName();
String requestId = (response == null || response.getSdkResponseMetadata() == null)
? ""
: response.getSdkResponseMetadata().getRequestId();
loggerProxy
.log(String.format("{\"apiRequest\": {\"requestId\": \"%s\", \"requestName\": \"%s\"}}", requestId, requestName));
} catch (final Exception e) {
loggerProxy.log(e.getMessage());
}
}
/**
* This is a hack to work around the problems that were introduced when the appender was compiled with AWS SDK
* version 1.9 or 1.10 but the user was running with version 1.11.
*
* The problem was that the createLogStream() method added a return object somewhere between 1.10 and 1.11 which
* broke backwards compatibility and the applications would throw NoSuchMethodError. Using reflection causes the
* linkage to be weaker and seems to work.
*/
private void callLogClientMethod(String methodName, AmazonWebServiceRequest arg) {
try {
Method method = awsLogsClient.getClass().getMethod(methodName, arg.getClass());
method.invoke(awsLogsClient, arg);
logInfo("Created: " + arg);
} catch (Exception e) {
logError("Problems creating: " + arg, e);
}
}
@Override
public boolean shouldRetry(
AmazonWebServiceRequest originalRequest,
AmazonClientException exception,
int retriesAttempted) {
LOG.debug("Exception caught during upload, retries attempted = {} out of {}", retriesAttempted, maxErrorRetry,
exception);
return retriesAttempted <= maxErrorRetry;
}
@Override
public long delayBeforeNextRetry(
AmazonWebServiceRequest originalRequest,
AmazonClientException exception,
int retriesAttempted) {
long backoffDelay = retriesAttempted * errorRetryDelay;
LOG.debug("Exception caught during upload, retries attempted = {}, will retry in {} ms", retriesAttempted,
backoffDelay, exception);
return backoffDelay;
}
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
// This is a somewhat hacky way of having ObjectMapper only serialize the fields in our
// model classes instead of the base class that comes from the SDK. In the future, we will
// remove the SDK dependency itself and the base classes and this hack will go away.
if (m.getDeclaringClass() == AmazonWebServiceRequest.class ||
m.getDeclaringClass() == AmazonWebServiceResult.class) {
return true;
}
return super.hasIgnoreMarker(m);
}
@Override
public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request) {
lazyLoadRecorder();
request.addHandlerContext(ENTITY_KEY, recorder.getTraceEntity());
request.addHandlerContext(EXECUTING_THREAD_KEY, Thread.currentThread().getId());
return request;
}
private <REQUEST extends AmazonWebServiceRequest, RESPONSE> Observable<RESPONSE> toObservable(
REQUEST request,
BiFunction<REQUEST, AsyncHandler<REQUEST, RESPONSE>, Future<RESPONSE>> callFun
) {
Supplier<REQUEST> supplier = () -> request;
return toObservable(supplier, callFun);
}
public <REQ extends AmazonWebServiceRequest, RES> AsyncHandler<REQ, RES> handler(Action2<REQ, RES> onSuccessAction, Action1<Exception> onErrorAction) {
return new AsyncHandler<REQ, RES>() {
@Override
public void onError(Exception exception) {
onErrorAction.call(exception);
subscriber.onError(exception);
}
@Override
public void onSuccess(REQ request, RES result) {
onSuccessAction.call(request, result);
subscriber.onCompleted();
}
};
}
public <REQ extends AmazonWebServiceRequest> AsyncHandler<REQ, RES> handler() {
return new AsyncHandler<REQ, RES>() {
@Override
public void onError(Exception exception) {
subscriber.onError(exception);
}
@Override
public void onSuccess(REQ request, RES result) {
subscriber.onSuccess(result);
}
};
}
public static <REQUEST extends AmazonWebServiceRequest, RESPONSE> Mono<RESPONSE> toMono(
REQUEST request,
BiFunction<REQUEST, AsyncHandler<REQUEST, RESPONSE>, Future<RESPONSE>> callFun
) {
Supplier<REQUEST> supplier = () -> request;
return toMono(supplier, callFun);
}
@Test
public void asyncActionCompletableErrors() {
AmazonWebServiceRequest someRequest = AmazonWebServiceRequest.NOOP;
final MockAsyncClient<AmazonWebServiceRequest, String> client = new MockAsyncClient<>(someRequest, "some response");
RuntimeException exception = new RuntimeException("error when initiating an async operation");
final Completable completable = AwsObservableExt.asyncActionCompletable(factory -> client.throwException(exception));
TestScheduler testScheduler = Schedulers.test();
final AssertableSubscriber<Void> subscriber = completable.subscribeOn(testScheduler).test();
testScheduler.triggerActions();
subscriber.assertError(exception);
}
@Test
public void asyncActionSingleErrors() {
AmazonWebServiceRequest someRequest = AmazonWebServiceRequest.NOOP;
final MockAsyncClient<AmazonWebServiceRequest, String> client = new MockAsyncClient<>(someRequest, "some response");
RuntimeException exception = new RuntimeException("error when initiating an async operation");
final Single<String> completable = AwsObservableExt.asyncActionSingle(supplier -> client.throwException(exception));
TestScheduler testScheduler = Schedulers.test();
final AssertableSubscriber<String> subscriber = completable.subscribeOn(testScheduler).test();
testScheduler.triggerActions();
subscriber.assertError(exception);
}
protected AmazonApiGateway getApiGatewayClient() {
if (apiGatewayClient != null) {
return apiGatewayClient;
}
RetryPolicy.RetryCondition retryCondition = new RetryPolicy.RetryCondition() {
@Override
public boolean shouldRetry(AmazonWebServiceRequest amazonWebServiceRequest, AmazonClientException amazonClientException, int i) {
if (amazonClientException instanceof TooManyRequestsException) {
return true;
}
return PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION.shouldRetry(amazonWebServiceRequest,
amazonClientException, i);
}
};
RetryPolicy retryPolicy = new RetryPolicy(retryCondition,
PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY,
10, true);
ClientConfiguration clientConfig = new ClientConfiguration()
.withRetryPolicy(retryPolicy);
apiGatewayClient = new AmazonApiGatewayClient(getAWSCredentialsProvideChain(), clientConfig).withRegion(Region.getRegion(Regions.fromName(deployment.getRegion())));
return apiGatewayClient;
}
@Test
public void retriesLessThanMaxTime() throws InterruptedException {
TimeOutRetryStrategy retryStrategy = new TimeOutRetryStrategy(Duration.ofSeconds(1));
AmazonWebServiceRequest request = Mockito.mock(AmazonWebServiceRequest.class);
Assertions.assertThat(retryStrategy.shouldRetry(pollingStrategyContext(request, 5))).isTrue();
Thread.sleep(1100);
Assertions.assertThat(retryStrategy.shouldRetry(pollingStrategyContext(request, 1))).isFalse();
}
/**
* the aws-sdk-java (currently as of 7/12/2018) does not have a publicly available constructor to create a PollingStrategyContext.
*/
private PollingStrategyContext pollingStrategyContext(AmazonWebServiceRequest request, int retriesAttempted) {
try {
Constructor<PollingStrategyContext> constructor = PollingStrategyContext.class.getDeclaredConstructor(AmazonWebServiceRequest.class, int.class);
constructor.setAccessible(true);
return constructor.newInstance(request, retriesAttempted);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new IllegalStateException("Could not create a PollingStrategyContext", e);
}
}
@Override
public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request) {
if (request instanceof SendMessageRequest) {
handleSendMessageRequest((SendMessageRequest) request);
} else if (request instanceof SendMessageBatchRequest) {
handleSendMessageBatchRequest((SendMessageBatchRequest) request);
}
return request;
}
@Override public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request) {
Span applicationSpan = tracer.nextSpan();
// new root span, but we don't yet know if we should sample it
if (applicationSpan.context().parentIdAsLong() == 0) {
request.addHandlerContext(DEFERRED_ROOT_CONTEXT, applicationSpan.context());
} else {
request.addHandlerContext(APPLICATION_SPAN, applicationSpan.start());
}
return request;
}
@Override
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest, AmazonClientException exception, int retriesAttempted)
{
long delay = (long) Math.pow(2, retriesAttempted) * SECOND_IN_MS;
LOGGER.warn("delayBeforeNextRetryInMilliseconds={} retriesAttempted={}", delay, retriesAttempted, exception);
return delay;
}
@Override
public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) {
Map<String, String> metadata = new HashMap<String, String>();
ResponseMetadata responseMetadata = new ResponseMetadata(metadata);
return responseMetadata;
}
@Override
public boolean shouldRetry(
AmazonWebServiceRequest originalRequest,
AmazonClientException exception,
int retriesAttempted) {
final boolean result = delegate.shouldRetry(originalRequest, exception, retriesAttempted);
if (result) {
registry
.counter("AWS_retries", AwsMetricsSupport.buildExceptionTags(originalRequest, exception))
.increment();
}
return result;
}