public static void service()

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;
        }
    }