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