package rocks.inspectit.agent.java.tracing.core.adapter.http.data.impl;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import rocks.inspectit.agent.java.tracing.core.adapter.http.data.HttpRequest;
import rocks.inspectit.agent.java.util.ReflectionCache;
/**
* Our implementation of the {@link HttpServerRequest} that works with
* {@link javax.servlet.HttpServletRequest}. We only need to extract data from the original
* javax.servlet.HttpServletRequest.
*
* @author Ivan Senic
*
*/
public class JavaHttpServerRequest implements HttpRequest {
/**
* FQN constant of the javax.servlet.HttpServletRequest.
*/
private static final String JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS = "javax.servlet.HttpServletRequest";
/**
* Reflection cache to use for method invocation.
*/
private final ReflectionCache cache;
/**
* Object representing http servlet request.
*/
private final Object httpServletRequest;
/**
* @param httpServletRequest
* request object
* @param cache
* reflection cache to use
*/
public JavaHttpServerRequest(Object httpServletRequest, ReflectionCache cache) {
this.httpServletRequest = httpServletRequest;
this.cache = cache;
}
/**
* {@inheritDoc}
*/
@Override
public boolean startClientSpan() {
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String getUrl() {
Object url = cache.invokeMethod(httpServletRequest.getClass(), "getRequestURL", new Class<?>[] {}, httpServletRequest, new Object[] {}, null, JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS);
if (null != url) {
return url.toString();
} else {
// fail back to URI
return (String) cache.invokeMethod(httpServletRequest.getClass(), "getRequestURI", new Class<?>[] {}, httpServletRequest, new Object[] {}, null, JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS);
}
}
/**
* {@inheritDoc}
*/
@Override
public String getHttpMethod() {
return (String) cache.invokeMethod(httpServletRequest.getClass(), "getMethod", new Class<?>[] {}, httpServletRequest, new Object[] {}, null, JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS);
}
/**
* {@inheritDoc}
*/
@Override
public Iterator<Entry<String, String>> iterator() {
Object headerNames = cache.invokeMethod(httpServletRequest.getClass(), "getHeaderNames", new Class<?>[] {}, httpServletRequest, new Object[] {}, null,
JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS);
if (headerNames instanceof Enumeration<?>) {
Enumeration<?> enumeration = (Enumeration<?>) headerNames;
Map<String, String> baggage = new HashMap<String, String>();
while (enumeration.hasMoreElements()) {
String headerName = enumeration.nextElement().toString();
String headerValue = (String) cache.invokeMethod(httpServletRequest.getClass(), "getHeader", new Class<?>[] { String.class }, httpServletRequest, new Object[] { headerName }, null,
JAVAX_SERVLET_HTTP_SERVLET_REQUEST_CLASS);
if (null != headerValue) {
baggage.put(headerName, headerValue);
}
}
return baggage.entrySet().iterator();
} else {
return Collections.<String, String> emptyMap().entrySet().iterator();
}
}
/**
* {@inheritDoc}
*/
@Override
public void put(String key, String value) {
throw new UnsupportedOperationException("Server request does not provide option to put baggage.");
}
}