001package io.prometheus.metrics.exporter.servlet.javax; 002 003import io.prometheus.metrics.exporter.common.PrometheusHttpExchange; 004import io.prometheus.metrics.exporter.common.PrometheusHttpRequest; 005import io.prometheus.metrics.exporter.common.PrometheusHttpResponse; 006import java.io.IOException; 007import java.io.OutputStream; 008import java.util.Enumeration; 009import javax.servlet.http.HttpServletRequest; 010import javax.servlet.http.HttpServletResponse; 011 012/** 013 * This class is an adapter for HTTP exchanges, implementing the PrometheusHttpExchange interface. 014 * It wraps HttpServletRequest and HttpServletResponse objects into Request and Response inner 015 * classes. 016 */ 017public class HttpExchangeAdapter implements PrometheusHttpExchange { 018 019 private final Request request; 020 private final Response response; 021 022 /** 023 * Constructs a new HttpExchangeAdapter with the given HttpServletRequest and HttpServletResponse. 024 * 025 * @param request the HttpServletRequest to be adapted 026 * @param response the HttpServletResponse to be adapted 027 */ 028 public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { 029 this.request = new Request(request); 030 this.response = new Response(response); 031 } 032 033 /** 034 * Returns the adapted HttpServletRequest. 035 * 036 * @return the adapted HttpServletRequest 037 */ 038 @Override 039 public PrometheusHttpRequest getRequest() { 040 return request; 041 } 042 043 /** 044 * Returns the adapted HttpServletResponse. 045 * 046 * @return the adapted HttpServletResponse 047 */ 048 @Override 049 public PrometheusHttpResponse getResponse() { 050 return response; 051 } 052 053 @Override 054 public void handleException(IOException e) throws IOException { 055 throw e; // leave exception handling to the servlet container 056 } 057 058 @Override 059 public void handleException(RuntimeException e) { 060 throw e; // leave exception handling to the servlet container 061 } 062 063 @Override 064 public void close() { 065 // nothing to do for Servlets. 066 } 067 068 /** This inner class adapts a HttpServletRequest to a PrometheusHttpRequest. */ 069 public static class Request implements PrometheusHttpRequest { 070 071 private final HttpServletRequest request; 072 073 /** 074 * Constructs a new Request with the given HttpServletRequest. 075 * 076 * @param request the HttpServletRequest to be adapted 077 */ 078 public Request(HttpServletRequest request) { 079 this.request = request; 080 } 081 082 @Override 083 public String getQueryString() { 084 return request.getQueryString(); 085 } 086 087 @Override 088 public Enumeration<String> getHeaders(String name) { 089 return request.getHeaders(name); 090 } 091 092 @Override 093 public String getMethod() { 094 return request.getMethod(); 095 } 096 097 @Override 098 public String getRequestPath() { 099 StringBuilder uri = new StringBuilder(); 100 String contextPath = request.getContextPath(); 101 if (contextPath.startsWith("/")) { 102 uri.append(contextPath); 103 } 104 String servletPath = request.getServletPath(); 105 if (servletPath.startsWith("/")) { 106 uri.append(servletPath); 107 } 108 String pathInfo = request.getPathInfo(); 109 if (pathInfo != null) { 110 uri.append(pathInfo); 111 } 112 return uri.toString(); 113 } 114 } 115 116 /** This inner class adapts a HttpServletResponse to a PrometheusHttpResponse. */ 117 public static class Response implements PrometheusHttpResponse { 118 119 private final HttpServletResponse response; 120 121 /** 122 * Constructs a new Response with the given HttpServletResponse. 123 * 124 * @param response the HttpServletResponse to be adapted 125 */ 126 public Response(HttpServletResponse response) { 127 this.response = response; 128 } 129 130 @Override 131 public void setHeader(String name, String value) { 132 response.setHeader(name, value); 133 } 134 135 @Override 136 public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) 137 throws IOException { 138 if (response.getHeader("Content-Length") == null && contentLength > 0) { 139 response.setContentLength(contentLength); 140 } 141 response.setStatus(statusCode); 142 return response.getOutputStream(); 143 } 144 } 145}