diff --git a/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpAccessLogFilter.java b/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpAccessLogFilter.java
new file mode 100644
index 00000000..22ca58cf
--- /dev/null
+++ b/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpAccessLogFilter.java
@@ -0,0 +1,55 @@
+package com.flipkart.gjex.core.web.filter;
+
+import com.flipkart.gjex.core.logging.Logging;
+import com.flipkart.gjex.core.service.Api;
+import com.google.inject.AbstractModule;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Filter for logging http access log requests
+ * @author ajay.jalgaonkar
+ *
+ */
+
+@Singleton
+@Named("HttpAccessLogFilter")
+public class HttpAccessLogFilter implements Filter, Logging {
+ private long startTime;
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {}
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ startTime = System.currentTimeMillis();
+ chain.doFilter(request, response);
+ StringBuilder sb = new StringBuilder();
+ sb.append(request.getRemoteAddr()).append(" ");
+ if (request instanceof HttpServletRequest && response instanceof HttpServletResponse){
+ HttpServletRequest httpServletRequest= (HttpServletRequest) request;
+ HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+ sb.append(httpServletRequest.getRequestURI()).append(" ")
+ .append(httpServletResponse.getStatus()).append(" ")
+ .append(httpServletResponse.getHeader("Content-Length")).append(" ");
+ } else {
+ sb.append("Did not get HTTP request").append(" ");
+ }
+ sb.append(System.currentTimeMillis()-startTime);
+ error(sb.toString());
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+}
diff --git a/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpFilterParams.java b/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpFilterParams.java
new file mode 100644
index 00000000..9869bc64
--- /dev/null
+++ b/core/src/main/java/com/flipkart/gjex/core/web/filter/HttpFilterParams.java
@@ -0,0 +1,21 @@
+package com.flipkart.gjex.core.web.filter;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+
+import javax.servlet.Filter;
+
+/**
+ * Parameters for creating http filters
+ * @author ajay.jalgaonkar
+ *
+ */
+
+@AllArgsConstructor
+@Getter
+@Builder
+public class HttpFilterParams {
+ private final Filter filter;
+ private final String pathSpec;
+}
diff --git a/examples/build.gradle b/examples/build.gradle
index 756a8712..390d083a 100644
--- a/examples/build.gradle
+++ b/examples/build.gradle
@@ -88,7 +88,7 @@ task runHelloWorldServer(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = 'com.flipkart.gjex.examples.helloworld.HelloWorldApplication'
args "server", "./src/main/resources/hello_world_config.yml"
- jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
+// jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
}
diff --git a/guice/src/main/java/com/flipkart/gjex/grpc/service/ApiServer.java b/guice/src/main/java/com/flipkart/gjex/grpc/service/ApiServer.java
index 61d05163..5ca35123 100644
--- a/guice/src/main/java/com/flipkart/gjex/grpc/service/ApiServer.java
+++ b/guice/src/main/java/com/flipkart/gjex/grpc/service/ApiServer.java
@@ -15,20 +15,24 @@
*/
package com.flipkart.gjex.grpc.service;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import org.eclipse.jetty.server.Server;
-import org.glassfish.jersey.server.ResourceConfig;
-
import com.flipkart.gjex.core.logging.Logging;
import com.flipkart.gjex.core.service.AbstractService;
import com.flipkart.gjex.core.service.Service;
+import com.flipkart.gjex.core.web.filter.HttpFilterParams;
import com.flipkart.gjex.web.ResourceRegistrar;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.glassfish.jersey.server.ResourceConfig;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
/**
* ApiServer
is a {@link Service} implementation that manages the GJEX API Jetty Server instance lifecycle
@@ -40,19 +44,35 @@
@Named("APIServer")
public class ApiServer extends AbstractService implements Logging {
- private final Server apiServer;
- private final ResourceRegistrar resourceRegistrar;
- private List resourceConfigs = new LinkedList();
+ private final Server apiServer;
+ private final ResourceRegistrar resourceRegistrar;
+ private final ServletContextHandler context;
+ private final Filter accessLogFilter;
+ private List resourceConfigs = new LinkedList<>();
@Inject
- public ApiServer(@Named("APIJettyServer") Server apiServer, ResourceRegistrar resourceRegistrar) {
+ public ApiServer(@Named("APIJettyServer") Server apiServer,
+ @Named("ApiServletContext")ServletContextHandler context,
+ @Named("HttpAccessLogFilter")Filter accessLogFilter,
+ ResourceRegistrar resourceRegistrar) {
this.apiServer = apiServer;
+ this.context = context;
+ this.accessLogFilter = accessLogFilter;
this.resourceRegistrar = resourceRegistrar;
}
public void registerResources(List resourceConfigs) {
this.resourceConfigs.addAll(resourceConfigs);
}
+
+ public void registerHttpFilters(List httpFilterParamsList){
+ context.addFilter(new FilterHolder(accessLogFilter), "/*" , EnumSet.of(DispatcherType.REQUEST));
+ for (HttpFilterParams httpFilterParams : httpFilterParamsList){
+ context.addFilter(new FilterHolder(httpFilterParams.getFilter()),
+ httpFilterParams.getPathSpec(),
+ EnumSet.of(DispatcherType.REQUEST));
+ }
+ }
@Override
public void doStart() throws Exception {
diff --git a/guice/src/main/java/com/flipkart/gjex/guice/GuiceBundle.java b/guice/src/main/java/com/flipkart/gjex/guice/GuiceBundle.java
index 6fbb23c3..bd7a5a0c 100644
--- a/guice/src/main/java/com/flipkart/gjex/guice/GuiceBundle.java
+++ b/guice/src/main/java/com/flipkart/gjex/guice/GuiceBundle.java
@@ -15,27 +15,19 @@
*/
package com.flipkart.gjex.guice;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import com.flipkart.gjex.core.job.ScheduledJob;
-import com.flipkart.gjex.grpc.service.ScheduledJobManager;
-import io.grpc.health.v1.HealthGrpc;
-import org.glassfish.jersey.server.ResourceConfig;
-
-import io.dropwizard.metrics5.health.HealthCheck;
import com.flipkart.gjex.core.Bundle;
import com.flipkart.gjex.core.GJEXConfiguration;
import com.flipkart.gjex.core.filter.Filter;
+import com.flipkart.gjex.core.job.ScheduledJob;
import com.flipkart.gjex.core.logging.Logging;
import com.flipkart.gjex.core.service.Service;
import com.flipkart.gjex.core.setup.Bootstrap;
import com.flipkart.gjex.core.setup.Environment;
import com.flipkart.gjex.core.tracing.TracingSampler;
+import com.flipkart.gjex.core.web.filter.HttpFilterParams;
import com.flipkart.gjex.grpc.service.ApiServer;
import com.flipkart.gjex.grpc.service.GrpcServer;
+import com.flipkart.gjex.grpc.service.ScheduledJobManager;
import com.flipkart.gjex.guice.module.ApiModule;
import com.flipkart.gjex.guice.module.ConfigModule;
import com.flipkart.gjex.guice.module.DashboardModule;
@@ -52,10 +44,17 @@
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.palominolabs.metrics.guice.MetricsInstrumentationModule;
-
+import io.dropwizard.metrics5.health.HealthCheck;
import io.grpc.BindableService;
+import io.grpc.health.v1.HealthGrpc;
+import org.glassfish.jersey.server.ResourceConfig;
import ru.vyarus.guice.validator.ImplicitValidationModule;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
/**
* A Guice GJEX Bundle implementation. Multiple Guice Modules may be added to this Bundle.
*
@@ -73,6 +72,7 @@ public class GuiceBundle implements
private List tracingSamplers;
private List scheduledJobs;
private List resourceConfigs;
+ private List httpFilterParamsList;
private Optional> configurationClass;
private GJEXEnvironmentModule gjexEnvironmentModule;
@@ -172,7 +172,11 @@ public void run(T configuration, U configMap, Environment environment) {
ApiServer apiServer = baseInjector.getInstance(ApiServer.class);
// Add all custom web resources
resourceConfigs = getInstances(baseInjector, ResourceConfig.class);
- apiServer.registerResources(resourceConfigs);
+ apiServer.registerResources(resourceConfigs);
+
+ // Add all custom http filters
+ httpFilterParamsList = getInstances(baseInjector, HttpFilterParams.class);
+ apiServer.registerHttpFilters(httpFilterParamsList);
}
@SuppressWarnings("unchecked")
diff --git a/guice/src/main/java/com/flipkart/gjex/guice/module/ApiModule.java b/guice/src/main/java/com/flipkart/gjex/guice/module/ApiModule.java
index aea2a36a..4ff7b63d 100644
--- a/guice/src/main/java/com/flipkart/gjex/guice/module/ApiModule.java
+++ b/guice/src/main/java/com/flipkart/gjex/guice/module/ApiModule.java
@@ -19,10 +19,12 @@
import com.flipkart.gjex.core.healthcheck.RotationManagementBasedHealthCheck;
import com.flipkart.gjex.core.logging.Logging;
import com.flipkart.gjex.core.service.Api;
+import com.flipkart.gjex.core.web.filter.HttpAccessLogFilter;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matchers;
+import com.google.inject.name.Names;
import io.dropwizard.metrics5.health.HealthCheck;
import io.grpc.BindableService;
import io.grpc.Context;
@@ -34,6 +36,7 @@
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
+import javax.servlet.Filter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.Executors;
@@ -53,6 +56,7 @@ protected void configure() {
requestInjection(methodInterceptor);
bindInterceptor(Matchers.any(), new ApiMethodMatcher(), methodInterceptor);
bind(HealthCheck.class).to(RotationManagementBasedHealthCheck.class);
+ bind(Filter.class).annotatedWith(Names.named("HttpAccessLogFilter")).to(HttpAccessLogFilter.class);
}
@Named("ApiScheduledExecutor")