package com.narhari import org.eclipse.jetty.io.Content import org.eclipse.jetty.server.Handler import org.eclipse.jetty.server.Request import org.eclipse.jetty.server.Response import org.eclipse.jetty.util.Callback import org.slf4j.LoggerFactory import org.slf4j.MDC import java.nio.ByteBuffer import java.util.concurrent.TimeUnit class ZipHandler : Handler.Abstract() { companion object { val log = LoggerFactory.getLogger(ZipHandler::class.java) } override fun handle(request: Request?, response: Response?, callback: Callback?): Boolean { MDC.put(UUID, java.util.UUID.randomUUID().toString()) val mdcMap = MDC.getCopyOfContextMap().apply { this.put(MDC_TS_REQUEST_DISPATCHED, System.currentTimeMillis().toString()) MDC.clear() } forward(response, callback, mdcMap) log.debug("***** Asynchronous Request.send(listener) done *****") return true; } } fun forward(response: Response?, callback: Callback?, mdc: MutableMap) { httpClient .newRequest("HTTP CALL TO SERVICE B") .idleTimeout(10, TimeUnit.MINUTES) .send(run { RapidResponseListener(response, callback, mdc) }) } class RapidResponseListener( val response: Response?, val callback: Callback?, val mdc: MutableMap ) : org.eclipse.jetty.client.Response.Listener { companion object { val log = LoggerFactory.getLogger(RapidResponseListener::class.java) } var aborted = false override fun onContent(clientResponse: org.eclipse.jetty.client.Response?, content: ByteBuffer?) { try { content?.let { c -> val array = ByteArray(c.remaining()).apply { c.get(this) } Content.Sink.asOutputStream(response).write(array) } } catch (e: Exception) { aborted = true } } override fun onComplete(result: org.eclipse.jetty.client.Result?) { if (!aborted) { log.debug("${result?.response}") try { log.debug("Data written") } finally { MDC.setContextMap(mdc) MDC.put(MDC_TS_RESPONSE_COMPLETE, System.currentTimeMillis().toString()) log.debug("Succeed") callback?.succeeded() } } else { MDC.setContextMap(mdc) MDC.put(ABORTED, "true") log.debug("aborted") } } }