@EnableZuulProxy initial implementation

This commit is contained in:
Spencer Gibb
2014-08-06 01:47:47 -06:00
parent a2e8245e93
commit 8fbba2b093
24 changed files with 1465 additions and 27 deletions

View File

@@ -81,6 +81,16 @@
<artifactId>ribbon-eureka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -66,7 +66,7 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
private int leaseExpirationDurationInSeconds = 90;
@Value("${spring.application.name:unknown}.mydomain.net")
@Value("${spring.application.name:unknown}") //TODO: why is .mydomain.net here?
private String virtualHostName;
private String secureVirtualHostName;

View File

@@ -50,11 +50,11 @@ public class FeignConfigurer {
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
String name = URI.create(schemeName).getHost();
setServiceListClass(name);
setServiceListClassAndVIP(name);
return builder.target(LoadBalancingTarget.create(type, schemeName));
}
public static void setServiceListClass(String serviceId) {
public static void setServiceListClassAndVIP(String serviceId) {
setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
}

View File

@@ -0,0 +1,15 @@
package org.springframework.platform.netflix.zuul;
import java.lang.annotation.*;
import org.springframework.context.annotation.Import;
/**
* @author Spencer Gibb
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ZuulProxyConfiguration.class)
public @interface EnableZuulProxy {
}

View File

@@ -0,0 +1,72 @@
package org.springframework.platform.netflix.zuul;
import com.netflix.zuul.FilterFileManager;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.groovy.GroovyCompiler;
import com.netflix.zuul.groovy.GroovyFileFilter;
import com.netflix.zuul.monitoring.MonitoringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.List;
import java.util.Map;
/**
* User: spencergibb
* Date: 4/24/14
* Time: 9:23 PM
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
*/
public class FilterIntializer implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(FilterIntializer.class);
@Autowired
private Map<String, ZuulFilter> filters;
@Override
public void contextInitialized(ServletContextEvent sce) {
LOGGER.info("Starting filter initialzer context listener");
//FIXME: mocks monitoring infrastructure as we don't need it for this simple app
MonitoringHelper.initMocks();
FilterRegistry registry = FilterRegistry.instance();
for (Map.Entry<String, ZuulFilter> entry : filters.entrySet()) {
registry.put(entry.getKey(), entry.getValue());
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
LOGGER.info("Stopping filter initializer context listener");
}
/*private void initGroovyFilterManager() {
//TODO: support groovy filters loaded from filesystem in proxy
FilterLoader.getInstance().setCompiler(new GroovyCompiler());
final String scriptRoot = props.getFilterRoot();
LOGGER.info("Using file system script: " + scriptRoot);
try {
FilterFileManager.setFilenameFilter(new GroovyFileFilter());
FilterFileManager.init(5,
scriptRoot + "/pre",
scriptRoot + "/route",
scriptRoot + "/post"
);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}*/
}

View File

@@ -1,4 +1,4 @@
package io.spring.platform.netflix.zuul;
package org.springframework.platform.netflix.zuul;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;

View File

@@ -1,4 +1,4 @@
package io.spring.platform.netflix.zuul;
package org.springframework.platform.netflix.zuul;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,9 +22,20 @@ public class Routes {
@Autowired
ConfigurableEnvironment env;
private final Field propertySourcesField;
private Field propertySourcesField;
private String keyPrefix;
public Routes() {
keyPrefix = "zuul.route.";
initField();
}
public Routes(String keyPrefix) {
this.keyPrefix = keyPrefix;
initField();
}
private void initField() {
propertySourcesField = ReflectionUtils.findField(CompositePropertySource.class, "propertySources");
propertySourcesField.setAccessible(true);
}
@@ -63,7 +74,7 @@ public class Routes {
//EnumerablePropertySource enumerable = (EnumerablePropertySource) propertySource;
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(propertySource);
Map<String, Object> routeEntries = PropertySourceUtils.getSubProperties(propertySources, "zuul.route.");
Map<String, Object> routeEntries = PropertySourceUtils.getSubProperties(propertySources, keyPrefix);
for (Map.Entry<String, Object> entry : routeEntries.entrySet()) {
String serviceId = entry.getKey();
String route = entry.getValue().toString();

View File

@@ -1,4 +1,4 @@
package io.spring.platform.netflix.zuul;
package org.springframework.platform.netflix.zuul;
import com.netflix.zuul.ZuulFilter;
import org.springframework.web.context.WebApplicationContext;

View File

@@ -0,0 +1,94 @@
package org.springframework.platform.netflix.zuul;
import com.netflix.zuul.context.ContextLifecycleFilter;
import com.netflix.zuul.http.ZuulServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.platform.netflix.zuul.filters.post.SendResponseFilter;
import org.springframework.platform.netflix.zuul.filters.post.StatsFilter;
import org.springframework.platform.netflix.zuul.filters.pre.DebugFilter;
import org.springframework.platform.netflix.zuul.filters.pre.DebugRequestFilter;
import org.springframework.platform.netflix.zuul.filters.pre.PreDecorationFilter;
import org.springframework.platform.netflix.zuul.filters.route.RibbonRoutingFilter;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author Spencer Gibb
*/
@Configuration
@EnableConfigurationProperties(ZuulProxyProperties.class)
@ConditionalOnClass(ZuulServlet.class)
@ConditionalOnExpression("${zuul.proxy.enabled:true}")
public class ZuulProxyConfiguration {
@Autowired
private ZuulProxyProperties props;
@Bean
public FilterRegistrationBean contextLifecycleFilter() {
Collection<String> urlPatterns = new ArrayList<>();
urlPatterns.add(props.getMapping()+"/*");
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new ContextLifecycleFilter());
filterRegistrationBean.setUrlPatterns(urlPatterns);
return filterRegistrationBean;
}
@Bean
public ServletRegistrationBean zuulServlet() {
return new ServletRegistrationBean(new ZuulServlet(), props.getMapping()+"/*");
}
@Bean
Routes routes() {
return new Routes("zuul.proxy.route.");
}
@Bean
FilterIntializer filterIntializer() {
return new FilterIntializer();
}
// pre filters
@Bean
public DebugFilter debugFilter() {
return new DebugFilter();
}
@Bean
public DebugRequestFilter debugRequestFilter() {
return new DebugRequestFilter();
}
@Bean
public PreDecorationFilter preDecorationFilter() {
return new PreDecorationFilter();
}
// route filters
@Bean
public RibbonRoutingFilter ribbonRoutingFilter() {
return new RibbonRoutingFilter();
}
// post filters
@Bean
public SendResponseFilter sendResponseFilter() {
return new SendResponseFilter();
}
@Bean
public StatsFilter statsFilter() {
return new StatsFilter();
}
}

View File

@@ -0,0 +1,13 @@
package org.springframework.platform.netflix.zuul;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Created by sgibb on 8/5/14.
*/
@Data
@ConfigurationProperties("zuul.proxy")
public class ZuulProxyProperties {
private String mapping = "/proxy";
}

View File

@@ -0,0 +1,181 @@
package org.springframework.platform.netflix.zuul.filters.post;
import com.google.common.base.Throwables;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.util.Pair;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.constants.ZuulHeaders;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;
public class SendResponseFilter extends ZuulFilter {
static DynamicBooleanProperty INCLUDE_DEBUG_HEADER =
DynamicPropertyFactory.getInstance().getBooleanProperty(ZuulConstants.ZUUL_INCLUDE_DEBUG_HEADER, false);
static DynamicIntProperty INITIAL_STREAM_BUFFER_SIZE =
DynamicPropertyFactory.getInstance().getIntProperty(ZuulConstants.ZUUL_INITIAL_STREAM_BUFFER_SIZE, 1024);
static DynamicBooleanProperty SET_CONTENT_LENGTH = DynamicPropertyFactory.getInstance().getBooleanProperty(ZuulConstants.ZUUL_SET_CONTENT_LENGTH, false);
@Override
public String filterType() {
return "post";
}
@Override
public int filterOrder() {
return 1000;
}
public boolean shouldFilter() {
return !RequestContext.getCurrentContext().getZuulResponseHeaders().isEmpty() ||
RequestContext.getCurrentContext().getResponseDataStream() != null ||
RequestContext.getCurrentContext().getResponseBody() != null;
}
public Object run() {
try {
addResponseHeaders();
writeResponse();
} catch (Exception e) {
Throwables.propagate(e);
}
return null;
}
void writeResponse() throws Exception {
RequestContext context = RequestContext.getCurrentContext();
// there is no body to send
if (context.getResponseBody() == null && context.getResponseDataStream() == null) return;
HttpServletResponse servletResponse = context.getResponse();
servletResponse.setCharacterEncoding("UTF-8");
OutputStream outStream = servletResponse.getOutputStream();
InputStream is = null;
try {
if (RequestContext.getCurrentContext().getResponseBody() != null) {
String body = RequestContext.getCurrentContext().getResponseBody();
writeResponse(new ByteArrayInputStream(body.getBytes()), outStream);
return;
}
boolean isGzipRequested = false;
final String requestEncoding = context.getRequest().getHeader(ZuulHeaders.ACCEPT_ENCODING);
if (requestEncoding != null && requestEncoding.equals("gzip"))
isGzipRequested = true;
is = context.getResponseDataStream();
InputStream inputStream = is;
if (is != null) {
if (context.sendZuulResponse()) {
// if origin response is gzipped, and client has not requested gzip, decompress stream
// before sending to client
// else, stream gzip directly to client
if (context.getResponseGZipped() && !isGzipRequested)
try {
inputStream = new GZIPInputStream(is);
} catch (java.util.zip.ZipException e) {
System.out.println("gzip expected but not received assuming unencoded response" +
RequestContext.getCurrentContext().getRequest().getRequestURL().toString());
inputStream = is;
}
else if (context.getResponseGZipped() && isGzipRequested)
servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, "gzip");
writeResponse(inputStream, outStream);
}
}
} finally {
try {
if (is != null)
is.close();
outStream.flush();
outStream.close();
} catch (IOException e) {
}
}
}
private void writeResponse(InputStream zin, OutputStream out) throws Exception {
byte[] bytes = new byte[INITIAL_STREAM_BUFFER_SIZE.get()];
int bytesRead = -1;
while ((bytesRead = zin.read(bytes)) != -1) {
// if (Debug.debugRequest() && !Debug.debugRequestHeadersOnly()) {
// Debug.addRequestDebug("OUTBOUND: < " + new String(bytes, 0, bytesRead));
// }
try {
out.write(bytes, 0, bytesRead);
out.flush();
} catch (IOException e) {
//ignore
e.printStackTrace();
}
// doubles buffer size if previous read filled it
if (bytesRead == bytes.length) {
bytes = new byte[bytes.length * 2];
}
}
}
private void addResponseHeaders() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletResponse servletResponse = context.getResponse();
List<Pair<String, String>> zuulResponseHeaders = context.getZuulResponseHeaders();
String debugHeader = "";
List<String> rd = (List<String>) RequestContext.getCurrentContext().get("routingDebug");
for (String it : rd) {
debugHeader += "[[["+it+"]]]";
}
/*
rd = (List<String>) RequestContext.getCurrentContext().get("requestDebug");
rd?.each {
debugHeader += "[[[REQUEST_DEBUG::${it}]]]";
}
*/
if (INCLUDE_DEBUG_HEADER.get()) servletResponse.addHeader("X-Zuul-Debug-Header", debugHeader);
if (Debug.debugRequest() && zuulResponseHeaders != null) {
for (Pair<String, String> it : zuulResponseHeaders) {
servletResponse.addHeader(it.first(), it.second());
Debug.addRequestDebug("OUTBOUND: < " + it.first() + ":" + it.second());
}
} else if (zuulResponseHeaders != null) {
for (Pair<String, String> it : zuulResponseHeaders) {
servletResponse.addHeader(it.first(), it.second());
}
}
RequestContext ctx = RequestContext.getCurrentContext();
Integer contentLength = ctx.getOriginContentLength();
// only inserts Content-Length if origin provides it and origin response is not gzipped
if (SET_CONTENT_LENGTH.get()) {
if (contentLength != null && !ctx.getResponseGZipped())
servletResponse.setContentLength(contentLength);
}
}
}

View File

@@ -0,0 +1,50 @@
package org.springframework.platform.netflix.zuul.filters.post;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import java.util.List;
public class StatsFilter extends ZuulFilter {
@Override
public String filterType() {
return "post";
}
@Override
public int filterOrder() {
return 2000;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
dumpRoutingDebug();
dumpRequestDebug();
return null;
}
public void dumpRequestDebug() {
List<String> rd = (List<String>) RequestContext.getCurrentContext().get("requestDebug");
if (rd != null) {
for (String it : rd) {
System.out.println("REQUEST_DEBUG::" + it);
}
}
}
public void dumpRoutingDebug() {
List<String> rd = (List<String>) RequestContext.getCurrentContext().get("routingDebug");
if (rd != null) {
for (String it : rd) {
System.out.println("ZUUL_DEBUG::"+it);
}
}
}
}

View File

@@ -0,0 +1,48 @@
package org.springframework.platform.netflix.zuul.filters.pre;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
public class DebugFilter extends ZuulFilter {
static final DynamicBooleanProperty routingDebug = DynamicPropertyFactory.getInstance()
.getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, true);
static final DynamicStringProperty debugParameter = DynamicPropertyFactory.getInstance()
.getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "d");
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
if ("true".equals(request.getParameter(debugParameter.get())))
return true;
return routingDebug.get();
}
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.setDebugRouting(true);
ctx.setDebugRequest(true);
return null;
}
}

View File

@@ -0,0 +1,62 @@
package org.springframework.platform.netflix.zuul.filters.pre;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.io.IOUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
public class DebugRequestFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 10000;
}
@Override
public boolean shouldFilter() {
return Debug.debugRequest();
}
@Override
public Object run() {
HttpServletRequest req = RequestContext.getCurrentContext().getRequest();
Debug.addRequestDebug("REQUEST:: " + req.getScheme() + " " + req.getRemoteAddr() + ":" + req.getRemotePort());
Debug.addRequestDebug("REQUEST:: > " + req.getMethod() + " " + req.getRequestURI() + " " + req.getProtocol());
Enumeration<String> headerIt = req.getHeaderNames();
while (headerIt.hasMoreElements()) {
String name = headerIt.nextElement();
String value = req.getHeader(name);
Debug.addRequestDebug("REQUEST:: > " + name + ":" + value);
}
final RequestContext ctx = RequestContext.getCurrentContext();
if (!ctx.isChunkedRequestBody()) {
try {
InputStream inp = ctx.getRequest().getInputStream();
if (inp != null) {
String body = IOUtils.toString(inp);
Debug.addRequestDebug("REQUEST:: > " + body);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
}

View File

@@ -0,0 +1,76 @@
package org.springframework.platform.netflix.zuul.filters.pre;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.platform.netflix.zuul.Routes;
import org.springframework.platform.netflix.zuul.ZuulProxyProperties;
import javax.annotation.Nullable;
import java.util.LinkedHashMap;
public class PreDecorationFilter extends ZuulFilter {
private static Logger LOG = LoggerFactory.getLogger(PreDecorationFilter.class);
@Autowired
private Routes routes;
@Autowired
private ZuulProxyProperties properties;
@Override
public int filterOrder() {
return 5;
}
@Override
public String filterType() {
return "pre";
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
String requestURI = ctx.getRequest().getRequestURI();
//remove proxy prefix TODO: only if embedded proxy
String proxyMapping = properties.getMapping();
final String uriPart = requestURI.replace(proxyMapping, ""); //TODO: better strategy?
ctx.put("requestURI", uriPart);
LinkedHashMap<String, String> routesMap = routes.getRoutes();
Optional<String> route = Iterables.tryFind(routesMap.keySet(), new Predicate<String>() {
@Override
public boolean apply(@Nullable String path) {
return uriPart.startsWith(path);
}
});
if (route.isPresent()) {
String serviceId = routesMap.get(route.get());
if (serviceId != null) {
// set serviceId for use in filters.route.RibbonRequest
ctx.set("serviceId", serviceId);
ctx.setRouteHost(null);
ctx.addOriginResponseHeader("X-Zuul-ServiceId", serviceId);
}
} else {
LOG.warn("No route found for uri: "+requestURI);
//TODO: 404
}
return null;
}
}

View File

@@ -0,0 +1,302 @@
package org.springframework.platform.netflix.zuul.filters.route;
import com.netflix.client.ClientException;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpResponse;
import com.netflix.hystrix.exception.HystrixRuntimeException;
import com.netflix.niws.client.http.RestClient;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.util.HTTPRequestUtils;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.platform.netflix.zuul.RibbonCommand;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MultivaluedMap;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import static com.netflix.client.http.HttpRequest.Verb;
import static org.springframework.platform.netflix.feign.FeignConfigurer.setServiceListClassAndVIP;
public class RibbonRoutingFilter extends ZuulFilter {
private static final Logger LOG = LoggerFactory.getLogger(RibbonRoutingFilter.class);
public static final String CONTENT_ENCODING = "Content-Encoding";
@Override
public String filterType() {
return "route";
}
@Override
public int filterOrder() {
return 10;
}
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return (ctx.getRouteHost() == null && ctx.get("serviceId") != null && ctx.sendZuulResponse());
}
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
MultivaluedMap<String, String> headers = buildZuulRequestHeaders(request);
MultivaluedMap<String, String> params = buildZuulRequestQueryParams(request);
Verb verb = getVerb(request);
InputStream requestEntity = getRequestBody(request);
String serviceId = (String) context.get("serviceId");
//TODO: can this be set be default? or an implementation of an interface?
setServiceListClassAndVIP(serviceId);
RestClient restClient = (RestClient) ClientFactory.getNamedClient(serviceId);
String uri = request.getRequestURI();
if (context.get("requestURI") != null) {
uri = (String) context.get("requestURI");
}
//remove double slashes
uri = uri.replace("//", "/");
try {
HttpResponse response = forward(restClient, verb, uri, headers, params, requestEntity);
setResponse(response);
return response;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void debug(RestClient restClient, Verb verb, String uri, MultivaluedMap<String, String> headers,
MultivaluedMap<String, String> params, InputStream requestEntity) throws IOException {
if (Debug.debugRequest()) {
for (String header: headers.keySet()) {
Debug.addRequestDebug(String.format("ZUUL:: > %s %s", header, headers.getFirst(header)));
}
StringBuilder query = new StringBuilder();
for (String param : params.keySet()) {
for (String value : params.get(param)) {
query.append(param);
query.append("=");
query.append(value);
query.append("&");
}
}
Debug.addRequestDebug(String.format("ZUUL:: > %s %s?%s HTTP/1.1", verb.verb(), uri, query.toString()));
RequestContext ctx = RequestContext.getCurrentContext();
if (!ctx.isChunkedRequestBody()) {
if (requestEntity != null) {
debugRequestEntity(ctx.getRequest().getInputStream());
}
}
}
}
private void debugRequestEntity(InputStream inputStream) throws IOException {
if (!Debug.debugRequestHeadersOnly()) {
String entity = IOUtils.toString(inputStream);
Debug.addRequestDebug("ZUUL:: > "+entity);
}
}
private HttpResponse forward(RestClient restClient, Verb verb, String uri, MultivaluedMap<String, String> headers,
MultivaluedMap<String, String> params, InputStream requestEntity) throws Exception {
debug(restClient, verb, uri, headers, params, requestEntity);
RibbonCommand command = new RibbonCommand(restClient, verb, uri, headers, params, requestEntity);
try {
HttpResponse response = command.execute();
return response;
} catch (HystrixRuntimeException e) {
if (e.getFallbackException() != null &&
e.getFallbackException().getCause() != null &&
e.getFallbackException().getCause() instanceof ClientException) {
ClientException ex = (ClientException) e.getFallbackException().getCause();
throw new ZuulException(ex, "Forwarding error", 500, ex.getErrorType().toString());
}
throw new ZuulException(e, "Forwarding error", 500, e.getFailureType().toString());
}
}
private InputStream getRequestBody(HttpServletRequest request) {
InputStream requestEntity = null;
try {
requestEntity = (InputStream) RequestContext.getCurrentContext().get("requestEntity");
if (requestEntity == null) {
requestEntity = request.getInputStream();
}
} catch (IOException e) {
LOG.error("Error during getRequestBody", e);
}
return requestEntity;
}
private MultivaluedMap<String, String> buildZuulRequestQueryParams(HttpServletRequest request) {
Map<String, List<String>> map = HTTPRequestUtils.getInstance().getQueryParams();
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
if (map == null) return params;
for (String key : params.keySet()) {
for (String value : params.get(key)) {
params.add(key, value);
}
}
return params;
}
private MultivaluedMap<String, String> buildZuulRequestHeaders(HttpServletRequest request) {
RequestContext context = RequestContext.getCurrentContext();
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
Enumeration headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = (String) headerNames.nextElement();
String value = request.getHeader(name);
if (!name.toLowerCase().contains("content-length")) headers.putSingle(name, value);
}
}
Map<String, String> zuulRequestHeaders = context.getZuulRequestHeaders();
for (String header : zuulRequestHeaders.keySet()) {
headers.putSingle(header, zuulRequestHeaders.get(header));
}
headers.putSingle("accept-encoding", "deflate, gzip");
if (headers.containsKey("transfer-encoding"))
headers.remove("transfer-encoding");
return headers;
}
Verb getVerb(HttpServletRequest request) {
String sMethod = request.getMethod();
return getVerb(sMethod);
}
Verb getVerb(String sMethod) {
if (sMethod == null) return Verb.GET;
sMethod = sMethod.toLowerCase();
if (sMethod.equals("post")) return Verb.POST;
if (sMethod.equals("put")) return Verb.PUT;
if (sMethod.equals("delete")) return Verb.DELETE;
if (sMethod.equals("options")) return Verb.OPTIONS;
if (sMethod.equals("head")) return Verb.HEAD;
return Verb.GET;
}
void setResponse(HttpResponse resp) throws ClientException, IOException {
RequestContext context = RequestContext.getCurrentContext();
context.setResponseStatusCode(resp.getStatus());
if (resp.hasEntity()) {
context.setResponseDataStream(resp.getInputStream());
}
String contentEncoding = null;
Collection<String> contentEncodingHeader = resp.getHeaders().get(CONTENT_ENCODING);
if (contentEncodingHeader != null && !contentEncodingHeader.isEmpty()) {
contentEncoding = contentEncodingHeader.iterator().next();
}
if (contentEncoding != null && HTTPRequestUtils.getInstance().isGzipped(contentEncoding)) {
context.setResponseGZipped(true);
} else {
context.setResponseGZipped(false);
}
if (Debug.debugRequest()) {
for (String key : resp.getHeaders().keySet()) {
boolean isValidHeader = isValidHeader(key);
Collection<String> list = resp.getHeaders().get(key);
for (String header : list) {
context.addOriginResponseHeader(key, header);
if (key.equalsIgnoreCase("content-length"))
context.setOriginContentLength(header);
if (isValidHeader) {
context.addZuulResponseHeader(key, header);
Debug.addRequestDebug(String.format("ORIGIN_RESPONSE:: < %s %s", key, header));
}
}
}
if (context.getResponseDataStream() != null) {
byte[] origBytes = IOUtils.toByteArray(context.getResponseDataStream());
InputStream inStream = new ByteArrayInputStream(origBytes);
if (context.getResponseGZipped())
inStream = new GZIPInputStream(inStream);
String responseEntity = IOUtils.toString(inStream);
Debug.addRequestDebug("ORIGIN_RESPONSE:: < "+responseEntity);
context.setResponseDataStream(new ByteArrayInputStream(origBytes));
}
} else {
for (String key : resp.getHeaders().keySet()) {
boolean isValidHeader = isValidHeader(key);
Collection<java.lang.String> list = resp.getHeaders().get(key);
for (String header : list) {
context.addOriginResponseHeader(key, header);
if (key.equalsIgnoreCase("content-length"))
context.setOriginContentLength(header);
if (isValidHeader) {
context.addZuulResponseHeader(key, header);
}
}
}
}
}
boolean isValidHeader(String headerName) {
switch (headerName.toLowerCase()) {
case "connection":
case "content-length":
case "content-encoding":
case "server":
case "transfer-encoding":
return false;
default:
return true;
}
}
}

View File

@@ -0,0 +1,456 @@
package org.springframework.platform.netflix.zuul.filters.route;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.util.HTTPRequestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.GZIPInputStream;
public class SimpleHostRoutingFilter extends ZuulFilter {
public static final String CONTENT_ENCODING = "Content-Encoding";
private static final Logger LOG = LoggerFactory.getLogger(SimpleHostRoutingFilter.class);
private static final Runnable CLIENTLOADER = new Runnable() {
@Override
public void run() {
loadClient();
}
};
private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().
getIntProperty(ZuulConstants.ZUUL_HOST_SOCKET_TIMEOUT_MILLIS, 10000);
private static final DynamicIntProperty CONNECTION_TIMEOUT = DynamicPropertyFactory.getInstance().
getIntProperty(ZuulConstants.ZUUL_HOST_CONNECT_TIMEOUT_MILLIS, 2000);
private static final AtomicReference<HttpClient> CLIENT = new AtomicReference<HttpClient>(newClient());
private static final Timer CONNECTION_MANAGER_TIMER = new Timer(true);
// cleans expired connections at an interval
static {
SOCKET_TIMEOUT.addCallback(CLIENTLOADER);
CONNECTION_TIMEOUT.addCallback(CLIENTLOADER);
CONNECTION_MANAGER_TIMER.schedule(new TimerTask() {
@Override
public void run() {
try {
final HttpClient hc = CLIENT.get();
if (hc == null) return;
hc.getConnectionManager().closeExpiredConnections();
} catch (Throwable t) {
LOG.error("error closing expired connections", t);
}
}
}, 30000, 5000);
}
public SimpleHostRoutingFilter() {}
private static final ClientConnectionManager newConnectionManager() throws Exception {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
registry.register(new Scheme("https", sf, 8443));
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(registry);
cm.setMaxTotal(Integer.parseInt(System.getProperty("zuul.max.host.connections", "200")));
cm.setDefaultMaxPerRoute(Integer.parseInt(System.getProperty("zuul.max.host.connections", "20")));
return cm;
}
@Override
public String filterType() {
return "route";
}
@Override
public int filterOrder() {
return 100;
}
public boolean shouldFilter() {
return RequestContext.getCurrentContext().getRouteHost() != null &&
RequestContext.getCurrentContext().sendZuulResponse();
}
private static final void loadClient() {
final HttpClient oldClient = CLIENT.get();
CLIENT.set(newClient());
if (oldClient != null) {
CONNECTION_MANAGER_TIMER.schedule(new TimerTask() {
@Override
public void run() {
try {
oldClient.getConnectionManager().shutdown();
} catch (Throwable t) {
LOG.error("error shutting down old connection manager", t);
}
}
}, 30000);
}
}
private static final HttpClient newClient() {
// I could statically cache the connection manager but we will probably want to make some of its properties
// dynamic in the near future also
try {
DefaultHttpClient httpclient = new DefaultHttpClient(newConnectionManager());
HttpParams httpParams = httpclient.getParams();
httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT.get());
httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT.get());
httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
httpParams.setParameter(ClientPNames.COOKIE_POLICY, org.apache.http.client.params.CookiePolicy.IGNORE_COOKIES);
httpclient.setRedirectStrategy(new org.apache.http.client.RedirectStrategy() {
@Override
public boolean isRedirected(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) {
return false;
}
@Override
public org.apache.http.client.methods.HttpUriRequest getRedirect(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) {
return null;
}
});
return httpclient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Object run() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
Header[] headers = buildZuulRequestHeaders(request);
String verb = getVerb(request);
InputStream requestEntity = getRequestBody(request);
HttpClient httpclient = CLIENT.get();
String uri = request.getRequestURI();
if (RequestContext.getCurrentContext().get("requestURI") != null) {
uri = (String) RequestContext.getCurrentContext().get("requestURI");
}
try {
HttpResponse response = forward(httpclient, verb, uri, request, headers, requestEntity);
setResponse(response);
}
catch (Exception e) {
if (Debug.debugRequest()) {
Debug.addRequestDebug("ZUUL:: ERROR " + e.getMessage());
}
throw new RuntimeException(e);
}
return null;
}
private InputStream debug(HttpClient httpclient, String verb, String uri, HttpServletRequest request, Header[] headers, InputStream requestEntity) throws Exception {
if (Debug.debugRequest()) {
Debug.addRequestDebug("ZUUL:: host="+RequestContext.getCurrentContext().getRouteHost());
for (Header header : headers) {
Debug.addRequestDebug(String.format("ZUUL::> %s %s", header.getName(), header.getValue()));
}
Debug.addRequestDebug(String.format("ZUUL:: > ${verb} ${uri}?${query} HTTP/1.1", verb, uri, request.getQueryString()));
if (requestEntity != null) {
requestEntity = debugRequestEntity(requestEntity);
}
}
return requestEntity;
}
private InputStream debugRequestEntity(InputStream inputStream) throws Exception {
if (Debug.debugRequestHeadersOnly()) return inputStream;
if (inputStream == null) return null;
String entity = IOUtils.toString(inputStream);
Debug.addRequestDebug("ZUUL::> "+entity);
return new ByteArrayInputStream(entity.getBytes());
}
private HttpResponse forward(HttpClient httpclient, String verb, String uri, HttpServletRequest request, Header[] headers, InputStream requestEntity) throws Exception {
requestEntity = debug(httpclient, verb, uri, request, headers, requestEntity);
HttpHost httpHost = getHttpHost();
HttpRequest httpRequest;
switch (verb) {
case "POST":
HttpPost httpPost = new HttpPost(uri + getQueryString());
httpRequest = httpPost;
InputStreamEntity entity = new InputStreamEntity(requestEntity, request.getContentLength());
httpPost.setEntity(entity);
break;
case "PUT":
HttpPut httpPut = new HttpPut(uri + getQueryString());
httpRequest = httpPut;
InputStreamEntity entity2 = new InputStreamEntity(requestEntity, request.getContentLength());
httpPut.setEntity(entity2);
break;
default:
httpRequest = new BasicHttpRequest(verb, uri + getQueryString());
LOG.debug(uri + getQueryString());
}
try {
httpRequest.setHeaders(headers);
LOG.debug(httpHost.getHostName() + " " + httpHost.getPort() + " " + httpHost.getSchemeName());
HttpResponse zuulResponse = forwardRequest(httpclient, httpHost, httpRequest);
return zuulResponse;
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
// httpclient.getConnectionManager().shutdown();
}
}
private HttpResponse forwardRequest(HttpClient httpclient, HttpHost httpHost, HttpRequest httpRequest) throws IOException {
return httpclient.execute(httpHost, httpRequest);
}
String getQueryString() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
String query = request.getQueryString();
return (query != null) ? "?"+query : "";
}
HttpHost getHttpHost() {
URL host = RequestContext.getCurrentContext().getRouteHost();
HttpHost httpHost = new HttpHost(host.getHost(), host.getPort(), host.getProtocol());
return httpHost;
}
private InputStream getRequestBody(HttpServletRequest request) {
InputStream requestEntity = null;
try {
requestEntity = request.getInputStream();
} catch (IOException e) {
//no requestBody is ok.
}
return requestEntity;
}
boolean isValidHeader(String name) {
if (name.toLowerCase().contains("content-length")) return false;
if (!RequestContext.getCurrentContext().getResponseGZipped()) {
if (name.toLowerCase().contains("accept-encoding")) return false;
}
return true;
}
private Header[] buildZuulRequestHeaders(HttpServletRequest request) {
ArrayList<Header> headers = new ArrayList<>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = (String) headerNames.nextElement();
String value = request.getHeader(name);
if (isValidHeader(name)) headers.add(new BasicHeader(name, value));
}
Map<String, String> zuulRequestHeaders = RequestContext.getCurrentContext().getZuulRequestHeaders();
for (String it : zuulRequestHeaders.keySet()) {
final String name = it.toLowerCase();
Optional<Header> h = Iterables.tryFind(headers, new Predicate<Header>() {
@Override
public boolean apply(@Nullable Header input) {
return input.getName().equals(name);
}
});
if (h.isPresent()) {
headers.remove(h);
}
headers.add(new BasicHeader(it, zuulRequestHeaders.get(it)));
}
if (RequestContext.getCurrentContext().getResponseGZipped()) {
headers.add(new BasicHeader("accept-encoding", "deflate, gzip"));
}
return headers.toArray(new Header[0]);
}
private String getVerb(HttpServletRequest request) {
String sMethod = request.getMethod();
return sMethod.toUpperCase();
}
private String getVerb(String sMethod) {
if (sMethod == null) return "GET";
sMethod = sMethod.toLowerCase();
if (sMethod.equalsIgnoreCase("post")) return "POST";
if (sMethod.equalsIgnoreCase("put")) return "PUT";
if (sMethod.equalsIgnoreCase("delete")) return "DELETE";
if (sMethod.equalsIgnoreCase("options")) return "OPTIONS";
if (sMethod.equalsIgnoreCase("head")) return "HEAD";
return "GET";
}
private void setResponse(HttpResponse response) throws IOException {
RequestContext context = RequestContext.getCurrentContext();
RequestContext.getCurrentContext().set("hostZuulResponse", response);
RequestContext.getCurrentContext().setResponseStatusCode(response.getStatusLine().getStatusCode());
if (response.getEntity() != null) {
RequestContext.getCurrentContext().setResponseDataStream(response.getEntity().getContent());
}
boolean isOriginResponseGzipped = false;
for (Header h : response.getHeaders(CONTENT_ENCODING)) {
if (HTTPRequestUtils.getInstance().isGzipped(h.getValue())) {
isOriginResponseGzipped = true;
break;
}
}
context.setResponseGZipped(isOriginResponseGzipped);
if (Debug.debugRequest()) {
for (Header header : response.getAllHeaders()) {
if (isValidHeader(header)) {
RequestContext.getCurrentContext().addZuulResponseHeader(header.getName(), header.getValue());
Debug.addRequestDebug("ORIGIN_RESPONSE:: < " + header.getName() +","+ header.getValue());
}
}
if (context.getResponseDataStream() != null) {
byte[] origBytes = IOUtils.toByteArray(context.getResponseDataStream());
ByteArrayInputStream byteStream = new ByteArrayInputStream(origBytes);
InputStream inputStream = byteStream;
if (RequestContext.getCurrentContext().getResponseGZipped()) {
inputStream = new GZIPInputStream(byteStream);
}
context.setResponseDataStream(new ByteArrayInputStream(origBytes));
}
} else {
for (Header header : response.getAllHeaders()) {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addOriginResponseHeader(header.getName(), header.getValue());
if (header.getName().equalsIgnoreCase("content-length"))
ctx.setOriginContentLength(header.getValue());
if (isValidHeader(header)) {
ctx.addZuulResponseHeader(header.getName(), header.getValue());
}
}
}
}
boolean isValidHeader(Header header) {
switch (header.getName().toLowerCase()) {
case "connection":
case "content-length":
case "content-encoding":
case "server":
case "transfer-encoding":
return false;
default:
return true;
}
}
public static class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
TrustManager[] tms = new TrustManager[1];
tms[0] = tm;
sslContext.init(null, tms, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}

View File

@@ -0,0 +1,34 @@
package org.springframework.platform.netflix.zuul.sample;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.platform.netflix.eureka.EnableEurekaClient;
import org.springframework.platform.netflix.zuul.EnableZuulProxy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
@EnableZuulProxy
@EnableEurekaClient
public class Application {
@RequestMapping("/testing123")
public String testing123() {
return "testing123";
}
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}

View File

@@ -0,0 +1,18 @@
package org.springframework.platform.netflix.zuul.sample;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@@ -1,12 +1,14 @@
server:
port: 9000
port: 9999
spring:
application:
name: client
name: testclient
eureka:
server:
enabled: false
client:
serviceUrl:
defaultZone: http://localhost:8080/v2/
default.defaultZone: http://localhost:8080/v2/
zuul:
proxy:
route:
testclient: /testing123
stores: /stores

View File

@@ -8,6 +8,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.platform.netflix.endpoint.HystrixStreamEndpoint;
import org.springframework.platform.netflix.zuul.Routes;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.ArrayList;

View File

@@ -11,7 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//import javax.servlet.http.HttpSessionEvent;
/**
* User: spencergibb
@@ -19,7 +18,7 @@ import javax.servlet.ServletContextListener;
* Time: 9:23 PM
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
*/
public class FilterIntializer implements ServletContextListener/*, HttpSessionListener*/ {
public class FilterIntializer implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(FilterIntializer.class);
@@ -27,9 +26,6 @@ public class FilterIntializer implements ServletContextListener/*, HttpSessionLi
ZuulProperties props;
@Override
/*public void sessionCreated(HttpSessionEvent se) {
contextInitialized(null);
}*/
public void contextInitialized(ServletContextEvent sce) {
LOGGER.info("Starting filter initialzer context listener");
@@ -42,9 +38,6 @@ public class FilterIntializer implements ServletContextListener/*, HttpSessionLi
}
@Override
/*public void sessionDestroyed(HttpSessionEvent se) {
contextDestroyed(null);
}*/
public void contextDestroyed(ServletContextEvent sce) {
LOGGER.info("Stopping filter initializer context listener");
}

View File

@@ -3,8 +3,8 @@ package filters.pre
import com.netflix.zuul.context.RequestContext
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import io.spring.platform.netflix.zuul.Routes
import io.spring.platform.netflix.zuul.SpringFilter
import org.springframework.platform.netflix.zuul.Routes
import org.springframework.platform.netflix.zuul.SpringFilter
class PreDecorationFilter extends SpringFilter {
private static Logger LOG = LoggerFactory.getLogger(PreDecorationFilter.class);

View File

@@ -15,14 +15,14 @@ import com.netflix.zuul.util.HTTPRequestUtils
import com.sun.jersey.core.util.MultivaluedMapImpl
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import io.spring.platform.netflix.zuul.RibbonCommand
import org.springframework.platform.netflix.zuul.RibbonCommand
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import java.util.zip.GZIPInputStream
import static HttpRequest.Verb
import static org.springframework.platform.netflix.feign.FeignConfigurer.setServiceListClass
import static org.springframework.platform.netflix.feign.FeignConfigurer.setServiceListClassAndVIP
class RibbonRequest extends ZuulFilter {
@@ -57,7 +57,7 @@ class RibbonRequest extends ZuulFilter {
def serviceId = context.get("serviceId")
//TODO: can this be set be default? or an implementation of an interface?
setServiceListClass(serviceId)
setServiceListClassAndVIP(serviceId)
IClient restClient = ClientFactory.getNamedClient(serviceId);