diff --git a/README.md b/README.md
index d799936..dc73fae 100644
--- a/README.md
+++ b/README.md
@@ -11,15 +11,17 @@ i. Declare the dependency in your _pom.xml_ file.
cloud.cirrusup
aws-latency-request-log-handler
- 1.0.0
+ 1.1.0
```
-
ii. Create a _request handler_ object.
-
```java
AwsLatencyRequestLogHandler handler = new AwsLatencyRequestLogHandler();
```
+If you want to publish call details in JSON format, then declare the handler in the following manner:
+```java
+AwsLatencyRequestLogHandler handler = new AwsLatencyRequestLogHandler(new JSONPublisher());
+```
iii. Enhance the _AWS client_ with the request handler created above.
diff --git a/pom.xml b/pom.xml
index fba470a..faa312c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
cloud.cirrusup
aws-latency-request-log-handler
- 1.0.0-SNAPSHOT
+ 1.1.0-SNAPSHOT
jar
@@ -124,13 +124,26 @@
-
+
com.amazonaws
aws-java-sdk-core
1.11.397
+
+ com.amazonaws
+ aws-java-sdk-s3
+ 1.11.397
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.9.7
+
+
org.slf4j
diff --git a/src/main/java/cloud/cirrusup/AwsLatencyRequestLogHandler.java b/src/main/java/cloud/cirrusup/AwsLatencyRequestLogHandler.java
index 20a495f..12ed4dc 100644
--- a/src/main/java/cloud/cirrusup/AwsLatencyRequestLogHandler.java
+++ b/src/main/java/cloud/cirrusup/AwsLatencyRequestLogHandler.java
@@ -1,12 +1,15 @@
package cloud.cirrusup;
+import cloud.cirrusup.publisher.Publisher;
+import cloud.cirrusup.publisher.PlainLogPublisher;
+import cloud.cirrusup.publisher.model.PublishedInfo;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.Request;
import com.amazonaws.Response;
import com.amazonaws.handlers.RequestHandler2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.amazonaws.services.s3.model.AmazonS3Exception;
+import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -14,17 +17,25 @@
*/
public class AwsLatencyRequestLogHandler extends RequestHandler2 {
- private static final String LOG_NAME = "aws-latency-log";
private static final String REQUEST_ID = "requestId";
- private static final Logger LOG = LoggerFactory.getLogger(LOG_NAME);
-
+ private final Publisher publisher;
private final ConcurrentHashMap REQUEST_MAP = new ConcurrentHashMap<>();
/**
* Constructor.
*/
public AwsLatencyRequestLogHandler() {
+
+ this(new PlainLogPublisher());
+ }
+
+ /**
+ * Constructor.
+ */
+ public AwsLatencyRequestLogHandler(Publisher publisher) {
+
+ this.publisher = publisher;
}
/**
@@ -34,9 +45,6 @@ public AwsLatencyRequestLogHandler() {
public void beforeRequest(Request> request) {
final String id = RandomGenerator.getUUIDRandomString();
-
- LOG.info("ID [{}] - Request done to the service [{}] with the method [{}]", id, request.getServiceName(), request.getHttpMethod());
-
request.getHeaders().put(REQUEST_ID, id);
REQUEST_MAP.put(id, System.currentTimeMillis());
}
@@ -48,14 +56,20 @@ public void beforeRequest(Request> request) {
public void afterResponse(Request> request, Response> response) {
final String id = request.getHeaders().get(REQUEST_ID);
-
+ PublishedInfo info = new PublishedInfo();
try {
- LOG.info("Request ID [{}] took [{}] milliseconds and returned the RESPONSE_CODE [{}]",
- id, getTime(id), getStatusCode(response, null));
+ info.addInfo(PublishedInfo.SERVICE_NAME, request.getServiceName());
+ info.addInfo(PublishedInfo.HTTP_METHOD, request.getHttpMethod().name());
+ info.addInfo(PublishedInfo.API_METHOD, getApiMethod(request));
+ info.addInfo(PublishedInfo.REQUEST_ID, getRequestId(request, response));
+ info.addLatency(getTime(id));
+ info.setStatusCode(getStatusCode(response, null));
} catch (Exception ex) {
- LOG.error("ID [{}] for the request to [{}] was not found.", id, request.getServiceName());
+ } finally {
+
+ publisher.publish(info);
}
}
@@ -66,15 +80,71 @@ public void afterResponse(Request> request, Response> response) {
public void afterError(Request> request, Response> response, Exception e) {
final String id = request.getHeaders().get(REQUEST_ID);
-
+ PublishedInfo info = new PublishedInfo();
try {
- LOG.error("Request ID [{}] took [{}] milliseconds and returned the RESPONSE_CODE [{}] and ERROR_MESSAGE [{}]",
- id, getTime(id), getStatusCode(response, e), e.getMessage());
+ info.addInfo(PublishedInfo.SERVICE_NAME, request.getServiceName());
+ info.addInfo(PublishedInfo.HTTP_METHOD, request.getHttpMethod().name());
+ info.addInfo(PublishedInfo.REQUEST_ID, getRequestId(e));
+ info.addInfo(PublishedInfo.API_METHOD, getApiMethod(request));
+ info.addInfo(PublishedInfo.ERROR_SUMMARY, e.getMessage());
+ info.addLatency(getTime(id));
+ info.setStatusCode(getStatusCode(response, e));
} catch (Exception ex) {
- LOG.error("ID [{}] for the request to [{}] was not found.", id, request.getServiceName());
+ } finally {
+
+ publisher.publish(info);
+ }
+ }
+
+ private String getApiMethod(Request> request) {
+
+ if (request != null && request.getHeaders() != null && request.getHeaders().containsKey("X-Amz-Target")) {
+
+ return request.getHeaders().get("X-Amz-Target");
}
+
+ if (request != null && request.getParameters() != null && request.getParameters().containsKey("Action")) {
+
+ List action = request.getParameters().get("Action");
+ if (!action.isEmpty()) {
+
+ return action.get(0);
+ }
+ }
+
+ return null;
+ }
+
+ private String getRequestId(Exception e) {
+
+ if (e != null && e instanceof AmazonServiceException) {
+
+ AmazonServiceException awsException = (AmazonServiceException) e;
+ if (awsException.getServiceName().equals("Amazon S3") && (awsException instanceof AmazonS3Exception)) {
+
+ return awsException.getRequestId() + " " + ((AmazonS3Exception) e).getExtendedRequestId();
+ }
+ return awsException.getRequestId();
+ }
+
+ return null;
+ }
+
+
+ private String getRequestId(Request> request, Response> response) {
+
+ if (response != null && response.getHttpResponse() != null && response.getHttpResponse().getHeaders() != null) {
+
+ if (request.getServiceName().equals("Amazon S3")) {
+
+ return response.getHttpResponse().getHeaders().get("x-amz-request-id") + " " + response.getHttpResponse().getHeaders().get("x-amz-id-2");
+ }
+ return response.getHttpResponse().getHeaders().get("x-amzn-RequestId");
+ }
+
+ return null;
}
private int getStatusCode(Response> response, Exception e) {
diff --git a/src/main/java/cloud/cirrusup/publisher/JSONPublisher.java b/src/main/java/cloud/cirrusup/publisher/JSONPublisher.java
new file mode 100644
index 0000000..ed3b8c9
--- /dev/null
+++ b/src/main/java/cloud/cirrusup/publisher/JSONPublisher.java
@@ -0,0 +1,50 @@
+package cloud.cirrusup.publisher;
+
+import cloud.cirrusup.publisher.Publisher;
+import cloud.cirrusup.publisher.model.PublishedInfo;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static cloud.cirrusup.publisher.model.PublishedInfo.API_METHOD;
+import static cloud.cirrusup.publisher.model.PublishedInfo.ERROR_SUMMARY;
+import static cloud.cirrusup.publisher.model.PublishedInfo.HTTP_METHOD;
+import static cloud.cirrusup.publisher.model.PublishedInfo.REQUEST_ID;
+import static cloud.cirrusup.publisher.model.PublishedInfo.SERVICE_NAME;
+
+/**
+ * Publisher that exports entries in JSON format.
+ */
+public class JSONPublisher implements Publisher {
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+ private static final Logger LOG = LoggerFactory.getLogger(LOG_NAME);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void publish(PublishedInfo info) {
+
+ ObjectNode node = mapper.createObjectNode();
+ node.put("requestId", info.getInfo(REQUEST_ID));
+ node.put("serviceName", info.getInfo(SERVICE_NAME));
+ node.put("httpMethod", info.getInfo(HTTP_METHOD));
+ node.put("latency", info.getLatency());
+ node.put("statusCode", info.getStatusCode());
+ if (info.hasInfo(ERROR_SUMMARY)) {
+ node.put("errorMessage", info.getInfo(ERROR_SUMMARY));
+ }
+ if (info.hasInfo(API_METHOD)) {
+ node.put("apiMethod", info.getInfo(API_METHOD));
+ }
+
+ try {
+
+ LOG.info(mapper.writeValueAsString(node));
+ } catch (JsonProcessingException e) {
+ }
+ }
+}
diff --git a/src/main/java/cloud/cirrusup/publisher/PlainLogPublisher.java b/src/main/java/cloud/cirrusup/publisher/PlainLogPublisher.java
new file mode 100644
index 0000000..5f92d4d
--- /dev/null
+++ b/src/main/java/cloud/cirrusup/publisher/PlainLogPublisher.java
@@ -0,0 +1,38 @@
+package cloud.cirrusup.publisher;
+
+import cloud.cirrusup.publisher.Publisher;
+import cloud.cirrusup.publisher.model.PublishedInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static cloud.cirrusup.publisher.model.PublishedInfo.API_METHOD;
+import static cloud.cirrusup.publisher.model.PublishedInfo.ERROR_SUMMARY;
+import static cloud.cirrusup.publisher.model.PublishedInfo.HTTP_METHOD;
+import static cloud.cirrusup.publisher.model.PublishedInfo.REQUEST_ID;
+import static cloud.cirrusup.publisher.model.PublishedInfo.SERVICE_NAME;
+
+/**
+ * Publisher that uses a text log file to add plain info.
+ */
+public class PlainLogPublisher implements Publisher {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LOG_NAME);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void publish(PublishedInfo info) {
+
+ LOG.info("Request ID [{}] to [{}/{}] took [{}] milliseconds and returned the RESPONSE_CODE [{}]",
+ info.getInfo(REQUEST_ID), info.getInfo(SERVICE_NAME), info.getInfo(HTTP_METHOD), info.getLatency(), info.getStatusCode());
+
+ if (info.hasInfo(ERROR_SUMMARY)) {
+ LOG.warn("Request ID [{}], RESPONSE_CODE [{}], MESSAGE [{}]", info.getInfo(REQUEST_ID), info.getStatusCode(), info.getInfo(ERROR_SUMMARY));
+ }
+
+ if(info.hasInfo(API_METHOD)){
+ LOG.info("Request ID [{}], API method [{}]", info.getInfo(REQUEST_ID), info.getInfo(API_METHOD));
+ }
+ }
+}
diff --git a/src/main/java/cloud/cirrusup/publisher/Publisher.java b/src/main/java/cloud/cirrusup/publisher/Publisher.java
new file mode 100644
index 0000000..e4532a5
--- /dev/null
+++ b/src/main/java/cloud/cirrusup/publisher/Publisher.java
@@ -0,0 +1,18 @@
+package cloud.cirrusup.publisher;
+
+import cloud.cirrusup.publisher.model.PublishedInfo;
+
+/**
+ * Model for any publisher.
+ */
+public interface Publisher {
+
+ String LOG_NAME = "aws-latency-log";
+
+ /**
+ * Publish info in the underlying destination.
+ *
+ * @param info information to be published
+ */
+ void publish(PublishedInfo info);
+}
diff --git a/src/main/java/cloud/cirrusup/publisher/model/PublishedInfo.java b/src/main/java/cloud/cirrusup/publisher/model/PublishedInfo.java
new file mode 100644
index 0000000..20af318
--- /dev/null
+++ b/src/main/java/cloud/cirrusup/publisher/model/PublishedInfo.java
@@ -0,0 +1,57 @@
+package cloud.cirrusup.publisher.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * POJO class that holds all details about info published.
+ */
+public class PublishedInfo {
+
+ public static final String REQUEST_ID = "requestId";
+ public static final String SERVICE_NAME = "serviceName";
+ public static final String HTTP_METHOD = "httpMethod";
+ public static final String ERROR_SUMMARY = "errorInfo";
+ public static final String API_METHOD = "apiMethod";
+
+
+ private final Map info = new HashMap<>();
+ private long latency = -1;
+ private int statusCode = -1;
+
+
+ public void addLatency(long latency) {
+
+ this.latency = latency;
+ }
+
+ public void addInfo(String name, String value) {
+
+ this.info.put(name, value);
+ }
+
+ public long getLatency() {
+
+ return latency;
+ }
+
+ public String getInfo(String name) {
+
+ return info.get(name);
+ }
+
+ public boolean hasInfo(String name) {
+
+ return info.containsKey(name) && info.get(name) != null;
+ }
+
+ public void setStatusCode(int statusCode) {
+
+ this.statusCode = statusCode;
+ }
+
+ public int getStatusCode() {
+
+ return statusCode;
+ }
+}
diff --git a/src/test/java/cloud/cirrusup/AwsLatencyRequestLogHandlerTest.java b/src/test/java/cloud/cirrusup/AwsLatencyRequestLogHandlerTest.java
index 2a6c565..8a7927a 100644
--- a/src/test/java/cloud/cirrusup/AwsLatencyRequestLogHandlerTest.java
+++ b/src/test/java/cloud/cirrusup/AwsLatencyRequestLogHandlerTest.java
@@ -6,6 +6,7 @@
import com.amazonaws.Response;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.http.HttpResponse;
+import com.amazonaws.services.s3.model.AmazonS3Exception;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@@ -16,7 +17,6 @@
import java.util.Map;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -41,6 +41,56 @@ public class AwsLatencyRequestLogHandlerTest {
@Test
public void testWithGoodRequestId() throws InterruptedException {
+ //setup
+ Request request = mock(Request.class);
+ Response response = PowerMockito.mock(Response.class);
+ HttpResponse httpResponse = mock(HttpResponse.class);
+ Map mapMock = mock(Map.class);
+ mockStatic(RandomGenerator.class);
+
+ when(request.getServiceName()).thenReturn("AmazonSQS");
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.POST);
+ when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
+ when(request.getHeaders()).thenReturn(mapMock);
+ when(response.getHttpResponse()).thenReturn(httpResponse);
+ when(httpResponse.getStatusCode()).thenReturn(200);
+ when(httpResponse.getHeaders()).thenReturn(mapMock);
+ when(mapMock.get("x-amzn-RequestId")).thenReturn(REQUEST_VALUE);
+ when(mapMock.get("requestId")).thenReturn(REQUEST_VALUE);
+
+ //call
+ awsLatencyRequestHandler.beforeRequest(request);
+ Thread.sleep(150);
+ awsLatencyRequestHandler.afterResponse(request, response);
+
+ //verify
+ verify(request, times(4)).getHeaders();
+ verify(request, times(2)).getParameters();
+ verify(response, times(5)).getHttpResponse();
+ verify(request, times(1)).getHttpMethod();
+ verify(request, times(2)).getServiceName();
+ verify(httpResponse, times(1)).getStatusCode();
+ verify(httpResponse, times(2)).getHeaders();
+ verify(mapMock, times(1)).put(anyString(), anyString());
+ verify(mapMock, times(1)).get("requestId");
+ verify(mapMock, times(1)).get("x-amzn-RequestId");
+ verify(mapMock, times(1)).containsKey("X-Amz-Target");
+ verifyNoMoreInteractions(request);
+ verifyNoMoreInteractions(httpResponse);
+ verifyNoMoreInteractions(mapMock);
+
+ PowerMockito.verifyStatic(times(1));
+ RandomGenerator.getUUIDRandomString();
+ PowerMockito.verifyNoMoreInteractions(RandomGenerator.class);
+
+ assertEquals(SERVICE_NAME, request.getServiceName());
+ assertEquals(HttpMethodName.POST, request.getHttpMethod());
+ assertEquals(REQUEST_VALUE, request.getHeaders().get(REQUEST_ID));
+ assertEquals(200, httpResponse.getStatusCode());
+ }
+
+ @Test
+ public void testWithMethodName() throws InterruptedException {
//setup
Request request = mock(Request.class);
@@ -53,9 +103,13 @@ public void testWithGoodRequestId() throws InterruptedException {
when(request.getHttpMethod()).thenReturn(HttpMethodName.POST);
when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
when(request.getHeaders()).thenReturn(mapMock);
- when(mapMock.get(any())).thenReturn(REQUEST_VALUE);
when(response.getHttpResponse()).thenReturn(httpResponse);
when(httpResponse.getStatusCode()).thenReturn(200);
+ when(httpResponse.getHeaders()).thenReturn(mapMock);
+ when(mapMock.get("x-amzn-RequestId")).thenReturn(REQUEST_VALUE);
+ when(mapMock.get("requestId")).thenReturn(REQUEST_VALUE);
+ when(mapMock.containsKey("X-Amz-Target")).thenReturn(true);
+ when(mapMock.get("X-Amz-Target")).thenReturn("list queues");
//call
awsLatencyRequestHandler.beforeRequest(request);
@@ -63,13 +117,17 @@ public void testWithGoodRequestId() throws InterruptedException {
awsLatencyRequestHandler.afterResponse(request, response);
//verify
- verify(request, times(2)).getHeaders();
- verify(response, times(2)).getHttpResponse();
+ verify(request, times(5)).getHeaders();
+ verify(response, times(5)).getHttpResponse();
verify(request, times(1)).getHttpMethod();
- verify(request, times(1)).getServiceName();
+ verify(request, times(2)).getServiceName();
verify(httpResponse, times(1)).getStatusCode();
+ verify(httpResponse, times(2)).getHeaders();
verify(mapMock, times(1)).put(anyString(), anyString());
- verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).get("requestId");
+ verify(mapMock, times(1)).get("x-amzn-RequestId");
+ verify(mapMock, times(1)).get("X-Amz-Target");
+ verify(mapMock, times(1)).containsKey("X-Amz-Target");
verifyNoMoreInteractions(request);
verifyNoMoreInteractions(httpResponse);
verifyNoMoreInteractions(mapMock);
@@ -84,6 +142,59 @@ public void testWithGoodRequestId() throws InterruptedException {
assertEquals(200, httpResponse.getStatusCode());
}
+ @Test
+ public void testWithGoodRequestIdS3Service() throws InterruptedException {
+
+ //setup
+ Request request = mock(Request.class);
+ Response response = PowerMockito.mock(Response.class);
+ HttpResponse httpResponse = mock(HttpResponse.class);
+ Map mapMock = mock(Map.class);
+ mockStatic(RandomGenerator.class);
+
+ when(request.getServiceName()).thenReturn("Amazon S3");
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
+ when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
+ when(request.getHeaders()).thenReturn(mapMock);
+ when(response.getHttpResponse()).thenReturn(httpResponse);
+ when(httpResponse.getStatusCode()).thenReturn(200);
+ when(httpResponse.getHeaders()).thenReturn(mapMock);
+ when(mapMock.get("x-amz-request-id")).thenReturn(REQUEST_VALUE);
+ when(mapMock.get("x-amz-id-2")).thenReturn("value-2");
+ when(mapMock.get("requestId")).thenReturn(REQUEST_VALUE);
+
+ //call
+ awsLatencyRequestHandler.beforeRequest(request);
+ Thread.sleep(150);
+ awsLatencyRequestHandler.afterResponse(request, response);
+
+ //verify
+ verify(request, times(4)).getHeaders();
+ verify(response, times(6)).getHttpResponse();
+ verify(request, times(1)).getHttpMethod();
+ verify(request, times(2)).getServiceName();
+ verify(request, times(2)).getParameters();
+ verify(httpResponse, times(1)).getStatusCode();
+ verify(httpResponse, times(3)).getHeaders();
+ verify(mapMock, times(1)).put(anyString(), anyString());
+ verify(mapMock, times(1)).get("requestId");
+ verify(mapMock, times(1)).get("x-amz-request-id");
+ verify(mapMock, times(1)).get("x-amz-id-2");
+ verify(mapMock, times(1)).containsKey("X-Amz-Target");
+ verifyNoMoreInteractions(request);
+ verifyNoMoreInteractions(httpResponse);
+ verifyNoMoreInteractions(mapMock);
+
+ PowerMockito.verifyStatic(times(1));
+ RandomGenerator.getUUIDRandomString();
+ PowerMockito.verifyNoMoreInteractions(RandomGenerator.class);
+
+ assertEquals("Amazon S3", request.getServiceName());
+ assertEquals(HttpMethodName.GET, request.getHttpMethod());
+ assertEquals(REQUEST_VALUE, request.getHeaders().get(REQUEST_ID));
+ assertEquals(200, httpResponse.getStatusCode());
+ }
+
@Test
public void testRequestIdNotFound() {
@@ -93,18 +204,22 @@ public void testRequestIdNotFound() {
when(request.getServiceName()).thenReturn("AmazonSQS");
when(request.getHeaders()).thenReturn(mapMock);
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
when(mapMock.get(REQUEST_ID)).thenReturn(REQUEST_VALUE);
+ when(mapMock.get("x-amzn-RequestId")).thenReturn(REQUEST_VALUE);
//call
awsLatencyRequestHandler.beforeRequest(request);
awsLatencyRequestHandler.afterResponse(request, null);
//verify
- verify(request, times(2)).getHeaders();
+ verify(request, times(4)).getHeaders();
+ verify(request, times(2)).getParameters();
verify(request, times(1)).getHttpMethod();
- verify(request, times(2)).getServiceName();
+ verify(request, times(1)).getServiceName();
verify(mapMock, times(1)).put(anyString(), anyString());
verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).containsKey(anyString());
verifyNoMoreInteractions(request);
verifyNoMoreInteractions(mapMock);
@@ -122,18 +237,69 @@ public void testResponseNullAfterError() {
when(request.getHeaders()).thenReturn(mapMock);
when(mapMock.get(REQUEST_ID)).thenReturn(REQUEST_VALUE);
when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
+
+ AmazonServiceException exception = new AmazonServiceException("AmazonServiceException");
+ exception.setServiceName("AmazonSQS");
+ exception.setStatusCode(500);
+ exception.setRequestId(REQUEST_VALUE);
//call
awsLatencyRequestHandler.beforeRequest(request);
- awsLatencyRequestHandler.afterError(request, null, new AmazonServiceException("AmazonServiceException"));
+ awsLatencyRequestHandler.afterError(request, null, exception);
//verify
- verify(request, times(2)).getHeaders();
+ verify(request, times(4)).getHeaders();
+ verify(request, times(2)).getParameters();
verify(request, times(1)).getServiceName();
verify(request, times(1)).getHttpMethod();
verify(mapMock, times(1)).put(anyString(), anyString());
verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).containsKey(anyString());
+
+ verifyNoMoreInteractions(request);
+ verifyNoMoreInteractions(mapMock);
+
+ PowerMockito.verifyStatic(times(1));
+ RandomGenerator.getUUIDRandomString();
+ PowerMockito.verifyNoMoreInteractions(RandomGenerator.class);
+ }
+
+ @Test
+ public void testS3ExceptionAfterError() {
+
+ //setup
+ Request request = mock(Request.class);
+ Map mapMock = mock(Map.class);
+ mockStatic(RandomGenerator.class);
+
+ when(request.getServiceName()).thenReturn("Amazon S3");
+ when(request.getHeaders()).thenReturn(mapMock);
+ when(mapMock.get(REQUEST_ID)).thenReturn(REQUEST_VALUE);
+ when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
+
+ AmazonS3Exception exception = new AmazonS3Exception("AmazonS3Exception");
+ exception.setServiceName("Amazon S3");
+ exception.setRequestId(REQUEST_VALUE);
+ exception.setExtendedRequestId("extended value");
+ exception.setStatusCode(500);
+ exception.setRequestId(REQUEST_VALUE);
+
+ //call
+ awsLatencyRequestHandler.beforeRequest(request);
+ awsLatencyRequestHandler.afterError(request, null, exception);
+
+ //verify
+ verify(request, times(4)).getHeaders();
+ verify(request, times(1)).getServiceName();
+ verify(request, times(1)).getHttpMethod();
+ verify(request, times(2)).getParameters();
+
+ verify(mapMock, times(1)).put(anyString(), anyString());
+ verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).containsKey(anyString());
verifyNoMoreInteractions(request);
verifyNoMoreInteractions(mapMock);
@@ -155,25 +321,31 @@ public void testResponseNotNullAfterError() {
when(request.getServiceName()).thenReturn("AmazonSQS");
when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
when(request.getHeaders()).thenReturn(mapMock);
when(mapMock.get(REQUEST_ID)).thenReturn(REQUEST_VALUE);
when(response.getHttpResponse()).thenReturn(httpResponse);
- when(httpResponse.getStatusCode()).thenReturn(200);
+ when(httpResponse.getStatusCode()).thenReturn(403);
+ AmazonServiceException exception = new AmazonServiceException("AmazonServiceException");
+ exception.setServiceName("AmazonSQS");
+ exception.setStatusCode(403);
+ exception.setRequestId(REQUEST_VALUE);
+ exception.setErrorCode("403");
//call
awsLatencyRequestHandler.beforeRequest(request);
- AmazonServiceException exception = new AmazonServiceException("AmazonServiceException");
- exception.setErrorCode("403");
awsLatencyRequestHandler.afterError(request, response, exception);
//verify
- verify(request, times(2)).getHeaders();
+ verify(request, times(4)).getHeaders();
+ verify(request, times(2)).getParameters();
verify(request, times(1)).getHttpMethod();
verify(request, times(1)).getServiceName();
verify(response, times(2)).getHttpResponse();
verify(httpResponse, times(1)).getStatusCode();
verify(mapMock, times(1)).put(anyString(), anyString());
verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).containsKey(anyString());
verifyNoMoreInteractions(request);
verifyNoMoreInteractions(response);
@@ -197,19 +369,24 @@ public void testResponseWithClientException() {
when(request.getServiceName()).thenReturn("AmazonSQS");
when(RandomGenerator.getUUIDRandomString()).thenReturn(REQUEST_VALUE);
when(request.getHeaders()).thenReturn(mapMock);
+ when(request.getHttpMethod()).thenReturn(HttpMethodName.GET);
when(mapMock.get(REQUEST_ID)).thenReturn(REQUEST_VALUE);
when(response.getHttpResponse()).thenReturn(null);
+ AmazonClientException exception = new AmazonClientException("AmazonClientException");
//call
awsLatencyRequestHandler.beforeRequest(request);
- awsLatencyRequestHandler.afterError(request, null, new AmazonClientException("AmazonClientException"));
+
+ awsLatencyRequestHandler.afterError(request, null, exception);
//verify
- verify(request, times(2)).getHeaders();
+ verify(request, times(4)).getHeaders();
+ verify(request, times(2)).getParameters();
verify(request, times(1)).getHttpMethod();
verify(request, times(1)).getServiceName();
verify(mapMock, times(1)).put(anyString(), anyString());
verify(mapMock, times(1)).get(anyString());
+ verify(mapMock, times(1)).containsKey(anyString());
verifyNoMoreInteractions(request);
verifyNoMoreInteractions(response);