001package io.prometheus.metrics.exporter.servlet.jakarta; 002 003import io.prometheus.metrics.exporter.common.PrometheusHttpExchange; 004import io.prometheus.metrics.exporter.common.PrometheusHttpRequest; 005import io.prometheus.metrics.exporter.common.PrometheusHttpResponse; 006import jakarta.servlet.http.HttpServletRequest; 007import jakarta.servlet.http.HttpServletResponse; 008 009import java.io.IOException; 010import java.io.OutputStream; 011import java.net.URI; 012import java.util.Enumeration; 013 014public class HttpExchangeAdapter implements PrometheusHttpExchange { 015 016 private final Request request; 017 private final Response response; 018 019 public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { 020 this.request = new Request(request); 021 this.response = new Response(response); 022 } 023 024 @Override 025 public PrometheusHttpRequest getRequest() { 026 return request; 027 } 028 029 @Override 030 public PrometheusHttpResponse getResponse() { 031 return response; 032 } 033 034 @Override 035 public void handleException(IOException e) throws IOException { 036 throw e; // leave exception handling to the servlet container 037 } 038 039 @Override 040 public void handleException(RuntimeException e) { 041 throw e; // leave exception handling to the servlet container 042 } 043 044 @Override 045 public void close() { 046 // nothing to do for Servlets. 047 } 048 049 public static class Request implements PrometheusHttpRequest { 050 051 private final HttpServletRequest request; 052 053 public Request(HttpServletRequest request) { 054 this.request = request; 055 } 056 057 @Override 058 public String getQueryString() { 059 return request.getQueryString(); 060 } 061 062 @Override 063 public Enumeration<String> getHeaders(String name) { 064 return request.getHeaders(name); 065 } 066 067 @Override 068 public String getMethod() { 069 return request.getMethod(); 070 } 071 072 @Override 073 public String getRequestPath() { 074 StringBuilder uri = new StringBuilder(); 075 String contextPath = request.getContextPath(); 076 if (contextPath.startsWith("/")) { 077 uri.append(contextPath); 078 } 079 String servletPath = request.getServletPath(); 080 if (servletPath.startsWith("/")) { 081 uri.append(servletPath); 082 } 083 String pathInfo = request.getPathInfo(); 084 if (pathInfo != null) { 085 uri.append(pathInfo); 086 } 087 return uri.toString(); 088 } 089 } 090 091 public static class Response implements PrometheusHttpResponse { 092 093 private final HttpServletResponse response; 094 095 public Response(HttpServletResponse response) { 096 this.response = response; 097 } 098 099 @Override 100 public void setHeader(String name, String value) { 101 response.setHeader(name, value); 102 } 103 104 @Override 105 public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException { 106 if (response.getHeader("Content-Length") == null && contentLength > 0) { 107 response.setContentLength(contentLength); 108 } 109 response.setStatus(statusCode); 110 return response.getOutputStream(); 111 } 112 } 113}