private void populateAndEndSubsegment(Subsegment currentSubsegment, Request<?> request, Response<?> response) { if (null != response) { String requestId = null; if (response.getAwsResponse() instanceof AmazonWebServiceResult<?>) { // Not all services return responses extending AmazonWebServiceResult (e.g. S3) ResponseMetadata metadata = ((AmazonWebServiceResult<?>) response.getAwsResponse()).getSdkResponseMetadata(); if (null != metadata) { requestId = metadata.getRequestId(); if (null != requestId) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, requestId); } } } else if (null != response.getHttpResponse()) { // S3 does not follow request id header convention if (null != response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)); } if (null != response.getHttpResponse().getHeader(S3_EXTENDED_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(EXTENDED_REQUEST_ID_SUBSEGMENT_KEY, response.getHttpResponse().getHeader(S3_EXTENDED_REQUEST_ID_HEADER_KEY)); } } currentSubsegment.putAllAws(extractResponseParameters(request, response.getAwsResponse())); currentSubsegment.putAllHttp(extractHttpResponseInformation(response.getHttpResponse())); } finalizeSubsegment(request); }
@Override public synchronized ResponseMetadata get(Object obj) { // System.identityHashCode isn't guaranteed to be unique // on all platforms, but should be reasonable enough to use // for a few requests at a time. We can always easily move // to our own unique IDs if needed. return internalCache.get(System.identityHashCode(obj)); }
/** Tests that the cache correctly evicts the oldest entries. */ @Test public void testEviction() { ResponseMetadataCache cache = new ResponseMetadataCache(3); AmazonWebServiceRequest key1 = new TestRequest(); AmazonWebServiceRequest key2 = new TestRequest(); AmazonWebServiceRequest key3 = new TestRequest(); AmazonWebServiceRequest key4 = new TestRequest(); ResponseMetadata metadata1 = newResponseMetadata(); ResponseMetadata metadata2 = newResponseMetadata(); ResponseMetadata metadata3 = newResponseMetadata(); ResponseMetadata metadata4 = newResponseMetadata(); // Fill the cache cache.add(key1, metadata1); cache.add(key2, metadata2); cache.add(key3, metadata3); // Verify all entries are still there assertEquals(metadata1, cache.get(key1)); assertEquals(metadata2, cache.get(key2)); assertEquals(metadata3, cache.get(key3)); // Add another and make sure the oldest is evicted cache.add(key4, metadata4); assertNull(cache.get(key1)); assertEquals(metadata2, cache.get(key2)); assertEquals(metadata3, cache.get(key3)); assertEquals(metadata4, cache.get(key4)); }
/** Tests that the cache works correctly with size=0 */ @Test public void TestEmpty() { ResponseMetadataCache cache = new ResponseMetadataCache(0); AmazonWebServiceRequest key = new TestRequest(); ResponseMetadata metadata = newResponseMetadata(); // Add item to the cache, it should be immediately evicted. cache.add(key, metadata); // get should return null assertNull(cache.get(key)); }
/** * Parses the S3 response metadata (ex: AWS request ID) from the specified * response, and returns a AmazonWebServiceResponse<T> object ready for the * result to be plugged in. * * @param response * The response containing the response metadata to pull out. * * @return A new, populated AmazonWebServiceResponse<T> object, ready for * the result to be plugged in. */ protected AmazonWebServiceResponse<T> parseResponseMetadata(HttpResponse response) { AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>(); String awsRequestId = response.getHeaders().get(Headers.REQUEST_ID); String hostId = response.getHeaders().get(Headers.EXTENDED_REQUEST_ID); String cloudFrontId = response.getHeaders().get(Headers.CLOUD_FRONT_ID); Map<String, String> metadataMap = new HashMap<String, String>(); metadataMap.put(ResponseMetadata.AWS_REQUEST_ID, awsRequestId); metadataMap.put(S3ResponseMetadata.HOST_ID, hostId); metadataMap.put(S3ResponseMetadata.CLOUD_FRONT_ID, cloudFrontId); awsResponse.setResponseMetadata(new S3ResponseMetadata(metadataMap)); return awsResponse; }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { Map<String, String> metadata = new HashMap<String, String>(); ResponseMetadata responseMetadata = new ResponseMetadata(metadata); return responseMetadata; }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { throw new UnsupportedOperationException("Not supported in mock"); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest amazonWebServiceRequest) { return null; }
/** * @see HttpResponseHandler#handle(HttpResponse) */ public AmazonWebServiceResponse<T> handle(HttpResponse response) throws Exception { log.trace("Parsing service response JSON"); String CRC32Checksum = response.getHeaders().get("x-amz-crc32"); JsonParser jsonParser = null; if (shouldParsePayloadAsJson()) { jsonParser = jsonFactory.createParser(response.getContent()); } try { AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>(); JsonUnmarshallerContext unmarshallerContext = new JsonUnmarshallerContextImpl( jsonParser, simpleTypeUnmarshallers, customTypeMarshallers, response); registerAdditionalMetadataExpressions(unmarshallerContext); T result = responseUnmarshaller.unmarshall(unmarshallerContext); // Make sure we read all the data to get an accurate CRC32 calculation. // See https://github.com/aws/aws-sdk-java/issues/1018 if (shouldParsePayloadAsJson() && response.getContent() != null) { IOUtils.drainInputStream(response.getContent()); } if (CRC32Checksum != null) { long serverSideCRC = Long.parseLong(CRC32Checksum); long clientSideCRC = response.getCRC32Checksum(); if (clientSideCRC != serverSideCRC) { throw new CRC32MismatchException( "Client calculated crc32 checksum didn't match that calculated by server side"); } } awsResponse.setResult(result); Map<String, String> metadata = unmarshallerContext.getMetadata(); metadata.put(ResponseMetadata.AWS_REQUEST_ID, response.getHeaders().get(X_AMZN_REQUEST_ID_HEADER)); awsResponse.setResponseMetadata(new ResponseMetadata(metadata)); log.trace("Done parsing service response"); return awsResponse; } finally { if (shouldParsePayloadAsJson()) { try { jsonParser.close(); } catch (IOException e) { log.warn("Error closing json parser", e); } } } }
@Override public void add(Object obj, ResponseMetadata metadata) { // deliberately left blank }
@Override public ResponseMetadata get(Object obj) { throw new SdkClientException("Response metadata caching is not enabled"); }
@Override public synchronized void add(Object obj, ResponseMetadata metadata) { if (obj == null) return; internalCache.put(System.identityHashCode(obj), metadata); }
@Override protected boolean removeEldestEntry(Entry<Integer,ResponseMetadata> eldest) { return size() > maxSize; }
private ResponseMetadata newResponseMetadata() { HashMap<String, String> metadata = new HashMap<String, String>(); metadata.put("foo", "bar-" + new Random().nextLong()); return new ResponseMetadata(metadata); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest arg0) { throw new java.lang.UnsupportedOperationException(); }
@Override @SuppressWarnings("unchecked") public Promise<ResponseMetadata> getCachedResponseMetadata(AmazonWebServiceRequest request) { return Blocking.get(() -> sns().getCachedResponseMetadata(request)) .transform(breaker); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { throw new RuntimeException("Not implemented"); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { throw new UnsupportedOperationException(); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { throw new UnsupportedOperationException(NOT_IMPLEMENTED); }
@Override public ResponseMetadata getCachedResponseMetadata(final AmazonWebServiceRequest arg0) { throw new UnsupportedOperationException(); }
@Test public void test_getCachedResponseMetadata() throws Exception { ResponseMetadata result = dynamoDb.getCachedResponseMetadata(null); assertThat(result, notNullValue()); }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { return null; }
@Override public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { return client.getResponseMetadataForRequest(request); }
/** * Returns additional response metadata for an executed request. Response metadata isn't * considered part of the standard results returned by an operation, so it's accessed instead * through this diagnostic interface. Response metadata is typically used for troubleshooting * issues with AWS support staff when services aren't acting as expected. * * @param request A previously executed AmazonWebServiceRequest object, whose response metadata * is desired. * @return The response metadata for the specified request, otherwise null if there is no * response metadata available for the request. */ public ResponseMetadata getResponseMetadataForRequest(AmazonWebServiceRequest request) { return responseMetadataCache.get(request); }
/** * Create the default {@link ResponseMetadata}. Subclasses may override this to create a * subclass of {@link ResponseMetadata}. Currently only SimpleDB does this. */ protected ResponseMetadata getResponseMetadata(Map<String, String> metadata) { return new ResponseMetadata(metadata); }
/** * Adds a new entry to this cache, possibly evicting the oldest entry if the * cache is at its size limit. * * @param obj * The key by which to store the metadata. * @param metadata * The metadata for this entry. */ void add(Object obj, ResponseMetadata metadata);
/** * Returns the response metadata associated with the specified object, or * null if no metadata is associated with that object. * * @param obj * The key by which the desired metadata is stored. * * @return The response metadata associated with the given object key, * otherwise null if no metadata is associated with that object. */ ResponseMetadata get(Object obj);
/** * Creates a new S3ResponseMetadata object from an existing ResponseMetadata * object. * * @param originalResponseMetadata * The ResponseMetadata object from which to create the new * object. */ public S3ResponseMetadata(ResponseMetadata originalResponseMetadata) { super(originalResponseMetadata); }
/** * Returns additional metadata for a previously executed successful, * request, typically used for debugging issues where a service isn't acting * as expected. This data isn't considered part of the result data returned * by an operation, so it's available through this separate, diagnostic * interface. * <p> * Response metadata is only cached for a limited period of time, so if you * need to access this extra diagnostic information for an executed request, * you should use this method to retrieve it as soon as possible after * executing the request. * * @param request * The originally executed request * * @return The response metadata for the specified request, or null if none * is available. */ public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { return amazonSqsToBeExtended.getCachedResponseMetadata(request); }
/** * Method that gets the response metadata included with a response from AWS associated with the request. * * @param request * AWS request * @return ResponseMetadata */ public ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request);