Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposed Raw Javax Filter Support #75

Merged
merged 7 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,9 @@

import com.flipkart.gjex.core.filter.Filter;
import com.flipkart.gjex.core.filter.RequestParams;
import com.flipkart.gjex.core.filter.grpc.GrpcFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.flipkart.gjex.core.filter.http;

import lombok.Builder;
import lombok.Data;

import javax.servlet.Filter;

/**
*
* @author ajay.jalgaonkar
*/

@Data
@Builder
@Deprecated
public class JavaxFilterParams {

// The filter instance to be applied.
private final Filter filter;

// The URL pattern(s) the filter applies to.
private final String pathSpec;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@

import com.flipkart.gjex.core.filter.grpc.GrpcFilter;
import com.flipkart.gjex.core.filter.http.HttpFilterParams;
import com.flipkart.gjex.core.filter.http.JavaxFilterParams;
import com.flipkart.gjex.core.tracing.TracingSampler;
import com.flipkart.gjex.examples.helloworld.filter.AuthFilter;
import com.flipkart.gjex.examples.helloworld.filter.LoggingFilter;
import com.flipkart.gjex.examples.helloworld.service.GreeterService;
import com.flipkart.gjex.examples.helloworld.tracing.AllWhitelistTracingSampler;
import com.flipkart.gjex.examples.helloworld.web.HelloWorldResourceConfig;
import com.flipkart.gjex.examples.helloworld.web.httpfilter.ExampleHttpFilter;
import com.flipkart.gjex.examples.helloworld.web.javaxfilter.ExampleJavaxFilter;
import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
import io.grpc.BindableService;
Expand Down Expand Up @@ -55,5 +57,7 @@ protected void configure() {
bind(ResourceConfig.class).annotatedWith(Names.named("HelloWorldResourceConfig")).to(HelloWorldResourceConfig.class);
bind(HttpFilterParams.class).annotatedWith(Names.named("ExampleHttpFilterParams"))
.toInstance(HttpFilterParams.builder().filter(new ExampleHttpFilter()).pathSpec("/*").build());
bind(JavaxFilterParams.class).annotatedWith(Names.named("ExampleJavaxFilter"))
.toInstance(JavaxFilterParams.builder().filter(new ExampleJavaxFilter()).pathSpec("/*").build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.flipkart.gjex.examples.helloworld.web.javaxfilter;

import com.flipkart.gjex.core.logging.Logging;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Example filter extending {@link Filter}
* @author ajay.jalgaonkar
*/
public class ExampleJavaxFilter implements Logging, Filter {
public AtomicInteger number = new AtomicInteger();

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
info("printing from ExampleJavaxFilter: " + number.getAndIncrement());
chain.doFilter(request, response);
}

@Override
public void destroy() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.flipkart.gjex.core.filter.http.AccessLogHttpFilter;
import com.flipkart.gjex.core.filter.http.HttpFilterConfig;
import com.flipkart.gjex.core.filter.http.HttpFilterParams;
import com.flipkart.gjex.core.filter.http.JavaxFilterParams;
import com.flipkart.gjex.core.logging.Logging;
import com.flipkart.gjex.core.service.AbstractService;
import com.flipkart.gjex.core.service.Service;
Expand Down Expand Up @@ -67,10 +68,15 @@ public void registerResources(List<ResourceConfig> resourceConfigs) {
this.resourceConfigs.addAll(resourceConfigs);
}

public void registerFilters(List<HttpFilterParams> httpFilterParamsList, HttpFilterConfig httpFilterConfig){
public void registerFilters(List<HttpFilterParams> httpFilterParamsList,
List<JavaxFilterParams> javaxFilterParamsList,
HttpFilterConfig httpFilterConfig){
configureAccessLog(httpFilterParamsList, httpFilterConfig);
httpFilterInterceptor.registerFilters(httpFilterParamsList);
context.addFilter(new FilterHolder(httpFilterInterceptor), "/*", EnumSet.of(DispatcherType.REQUEST));
for (JavaxFilterParams javaxFilterParams: javaxFilterParamsList){
context.addFilter(new FilterHolder(javaxFilterParams.getFilter()), javaxFilterParams.getPathSpec(), EnumSet.of(DispatcherType.REQUEST));
}
}

private void configureAccessLog(List<HttpFilterParams> httpFilterParamsList, HttpFilterConfig httpFilterConfig){
Expand Down
6 changes: 5 additions & 1 deletion guice/src/main/java/com/flipkart/gjex/guice/GuiceBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.flipkart.gjex.core.GJEXConfiguration;
import com.flipkart.gjex.core.filter.grpc.GrpcFilter;
import com.flipkart.gjex.core.filter.http.HttpFilterParams;
import com.flipkart.gjex.core.filter.http.JavaxFilterParams;
import com.flipkart.gjex.core.job.ScheduledJob;
import com.flipkart.gjex.core.logging.Logging;
import com.flipkart.gjex.core.service.Service;
Expand Down Expand Up @@ -73,6 +74,7 @@ public class GuiceBundle<T extends GJEXConfiguration, U extends Map> implements
private List<ScheduledJob> scheduledJobs;
private List<ResourceConfig> resourceConfigs;
private List<HttpFilterParams> httpFilterParamsList;
private List<JavaxFilterParams> javaxFilterParamsList;
private Optional<Class<T>> configurationClass;
private GJEXEnvironmentModule gjexEnvironmentModule;

Expand Down Expand Up @@ -176,7 +178,9 @@ public void run(T configuration, U configMap, Environment environment) {

// Add all custom http filters
httpFilterParamsList = getInstances(baseInjector, HttpFilterParams.class);
apiServer.registerFilters(httpFilterParamsList, configuration.getApiService().getHttpFilterConfig());
javaxFilterParamsList = getInstances(baseInjector, JavaxFilterParams.class);
apiServer.registerFilters(httpFilterParamsList,
javaxFilterParamsList, configuration.getApiService().getHttpFilterConfig());
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -30,38 +28,27 @@ public class HttpFilterInterceptor implements javax.servlet.Filter {

private static class ServletPathFiltersHolder {
ServletPathSpec spec;
List<HttpFilter> filters;
HttpFilter filter;

public ServletPathFiltersHolder(ServletPathSpec spec, List<HttpFilter> filters) {
public ServletPathFiltersHolder(ServletPathSpec spec, HttpFilter filter) {
this.spec = spec;
this.filters = filters;
this.filter = filter;
}
}

/**
* Map of Filter instances mapped to Service and its method
*/
@SuppressWarnings("rawtypes")
private Map<String, ServletPathFiltersHolder> filtersMap = new HashMap<>();
private Map<ServletPathSpec, List<HttpFilter>> pathSpecToFilterMap = new HashMap<>();
private final List<ServletPathFiltersHolder> pathFiltersHolders = new ArrayList<>();

public void registerFilters(List<HttpFilterParams> httpFilterParamsList) {
for (HttpFilterParams httpFilterParams: httpFilterParamsList){
if (!filtersMap.containsKey(httpFilterParams.getPathSpec())){
ServletPathSpec spec = new ServletPathSpec(httpFilterParams.getPathSpec());
filtersMap.put(httpFilterParams.getPathSpec(), new ServletPathFiltersHolder(spec,
new ArrayList<>()));
}
filtersMap.get(httpFilterParams.getPathSpec()).filters.add(httpFilterParams.getFilter());
for(HttpFilterParams p : httpFilterParamsList){
ServletPathSpec spec = new ServletPathSpec(p.getPathSpec());
pathFiltersHolders.add(new ServletPathFiltersHolder(spec, p.getFilter()));
}
}

public void init(FilterConfig filterConfig) throws ServletException {
for (ServletPathFiltersHolder servletPathFiltersHolder : filtersMap.values()){
pathSpecToFilterMap.computeIfAbsent(servletPathFiltersHolder.spec,
k-> new ArrayList<>()).addAll(servletPathFiltersHolder.filters);
}
}
public void init(FilterConfig filterConfig) throws ServletException {}

/**
* The core method that processes incoming requests and responses. It captures the request and response objects,
Expand Down Expand Up @@ -109,7 +96,7 @@ public final void doFilter(ServletRequest request, ServletResponse response,
* @param request The ServletRequest object containing the client's request
* @return The real IP address of the client
*/
private String getClientIp(ServletRequest request) {
protected String getClientIp(ServletRequest request) {
String remoteAddr = request.getRemoteAddr();
String xForwardedFor = ((HttpServletRequest) request).getHeader("X-Forwarded-For");
if (xForwardedFor != null) {
Expand All @@ -118,10 +105,10 @@ private String getClientIp(ServletRequest request) {
return remoteAddr;
}

private List<HttpFilter> getMatchingFilters(String path) {
return pathSpecToFilterMap.keySet().stream().filter(key -> key.matches(path))
.map(k-> pathSpecToFilterMap.get(k)).flatMap(List::stream)
.map(filter -> filter.getInstance()).collect(Collectors.toList());
protected List<HttpFilter> getMatchingFilters(String path) {
return pathFiltersHolders.stream().filter(t -> t.spec.matches(path))
.map(t-> t.filter)
.map(HttpFilter::getInstance).collect(Collectors.toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;


public class HttpFilterInterceptorTest {

private HttpFilterInterceptor interceptor;
String pathSpec = "/test/*";

@Before
public void setUp() {
Expand All @@ -27,19 +29,27 @@ public void setUp() {

@Test
public void registerFiltersAddsFiltersToMap() {
String pathSpec = "/test/*";
List<HttpFilter> filters = new ArrayList<>();
filters.add(new AccessLogHttpFilter());
assertEquals(1, filters.size());
List<HttpFilterParams> httpFilterParamsList = new ArrayList<>();
httpFilterParamsList.add(HttpFilterParams.builder().pathSpec(pathSpec).filter(new AccessLogHttpFilter()).build());
interceptor.registerFilters(httpFilterParamsList);
assertEquals(1, interceptor.getMatchingFilters("/test/path").size());
}

@Test
public void testRegexSpec(){
ServletPathSpec spec = new ServletPathSpec("/test/*");
assertEquals(true, spec.matches("/test/path"));
assertTrue(spec.matches("/test/path"));
}


@Test
public void registerFiltersAddsFiltersToMap2() {
List<HttpFilterParams> httpFilterParamsList = new ArrayList<>();
httpFilterParamsList.add(HttpFilterParams.builder().pathSpec(pathSpec).filter(new AccessLogHttpFilter()).build());
httpFilterParamsList.add(HttpFilterParams.builder().pathSpec(pathSpec).filter(new AccessLogHttpFilter()).build());
interceptor.registerFilters(httpFilterParamsList);
assertEquals(2, interceptor.getMatchingFilters("/test/path").size());
}


}
Loading