in disco-java-agent-web/src/main/java/software/amazon/disco/agent/web/servlet/HttpServletServiceInterceptor.java [80:153]
public static void service(@AllArguments Object[] args,
@This Object invoker,
@Origin String origin,
@SuperCall Callable<Object> zuper) throws Throwable {
HttpServletNetworkRequestEvent requestEvent = null;
HttpServletNetworkResponseEvent responseEvent = null;
Throwable throwable = null;
if (LogManager.isDebugEnabled()) {
log.debug("DiSCo(Web) interception of " + origin);
}
if (TransactionContext.isWithinCreatedContext() && TransactionContext.getMetadata(TX_NAMESPACE) != null) {
//since service() calls in subclasses may call their parents, this interceptor can stack up
//only perform event publication it if we were the first call to take place
zuper.call();
return;
}
TransactionContext.create();
TransactionContext.putMetadata(TX_NAMESPACE, true);
try {
// To reduce the # of dependencies, we use reflection to obtain the basic methods.
Object request = args[0];
HttpServletRequestAccessor reqAccessor = (HttpServletRequestAccessor) request;
// Obtain the metadata information from the host.
// If they are null, they are't stored, so retrieval would be null as well.
int srcPort = reqAccessor.getRemotePort();
int dstPort = reqAccessor.getLocalPort();
String srcIP = reqAccessor.getRemoteAddr();
String dstIP = reqAccessor.getLocalAddr();
requestEvent = new HttpServletNetworkRequestEvent(EVENT_ORIGIN, srcPort, dstPort, srcIP, dstIP)
.withHeaderMap(reqAccessor.retrieveHeaderMap())
.withDate(reqAccessor.getHeader(DATE_HEADER))
.withHost(reqAccessor.getHeader(HOST_HEADER))
.withHTTPOrigin(reqAccessor.getHeader(ORIGIN_HEADER))
.withReferer(reqAccessor.getHeader(REFERER_HEADER))
.withUserAgent(reqAccessor.getHeader(USER_AGENT_HEADER))
.withMethod(reqAccessor.getMethod())
.withRequest(request)
.withURL(reqAccessor.getRequestUrl());
EventBus.publish(requestEvent);
} catch (Throwable e) {
log.error("DiSCo(Web) Failed to retrieve request data from servlet service.");
}
// call the original, catching anything it throws
try {
zuper.call();
} catch (Throwable t) {
throwable = t;
}
try {
Object response = args[1];
HttpServletResponseAccessor respAccessor = (HttpServletResponseAccessor)response;
int statusCode = respAccessor.getStatus();
responseEvent = new HttpServletNetworkResponseEvent(EVENT_ORIGIN, requestEvent)
.withHeaderMap(respAccessor.retrieveHeaderMap())
.withStatusCode(statusCode)
.withResponse(response);
EventBus.publish(responseEvent);
} catch (Throwable t) {
log.error("DiSCo(Web) Failed to retrieve response data from service.");
}
//match the create() call with a destroy() in all cases
TransactionContext.destroy();
//rethrow anything
if (throwable != null) {
throw throwable;
}
}