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; 006 007import javax.servlet.http.HttpServletRequest; 008import javax.servlet.http.HttpServletResponse; 009import java.io.IOException; 010import java.io.OutputStream; 011import java.util.Enumeration; 012 013/** 014 * This class is an adapter for HTTP exchanges, implementing the PrometheusHttpExchange interface. 015 * It wraps HttpServletRequest and HttpServletResponse objects into Request and Response inner 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 /** 069 * This inner class adapts a HttpServletRequest to a PrometheusHttpRequest. 070 */ 071 public static class Request implements PrometheusHttpRequest { 072 073 private final HttpServletRequest request; 074 075 /** 076 * Constructs a new Request with the given HttpServletRequest. 077 * 078 * @param request the HttpServletRequest to be adapted 079 */ 080 public Request(HttpServletRequest request) { 081 this.request = request; 082 } 083 084 @Override 085 public String getQueryString() { 086 return request.getQueryString(); 087 } 088 089 090 @Override 091 public Enumeration<String> getHeaders(String name) { 092 return request.getHeaders(name); 093 } 094 095 096 @Override 097 public String getMethod() { 098 return request.getMethod(); 099 } 100 101 102 @Override 103 public String getRequestPath() { 104 StringBuilder uri = new StringBuilder(); 105 String contextPath = request.getContextPath(); 106 if (contextPath.startsWith("/")) { 107 uri.append(contextPath); 108 } 109 String servletPath = request.getServletPath(); 110 if (servletPath.startsWith("/")) { 111 uri.append(servletPath); 112 } 113 String pathInfo = request.getPathInfo(); 114 if (pathInfo != null) { 115 uri.append(pathInfo); 116 } 117 return uri.toString(); 118 } 119 } 120 121 /** 122 * This inner class adapts a HttpServletResponse to a PrometheusHttpResponse. 123 */ 124 public static class Response implements PrometheusHttpResponse { 125 126 private final HttpServletResponse response; 127 128 /** 129 * Constructs a new Response with the given HttpServletResponse. 130 * 131 * @param response the HttpServletResponse to be adapted 132 */ 133 public Response(HttpServletResponse response) { 134 this.response = response; 135 } 136 137 138 @Override 139 public void setHeader(String name, String value) { 140 response.setHeader(name, value); 141 } 142 143 144 @Override 145 public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException { 146 if (response.getHeader("Content-Length") == null && contentLength > 0) { 147 response.setContentLength(contentLength); 148 } 149 response.setStatus(statusCode); 150 return response.getOutputStream(); 151 } 152 } 153}