diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..dc85cd5 --- /dev/null +++ b/config.yml @@ -0,0 +1,8 @@ +maxmind: + databaseFilePath: /path/to/maxmind/database/file.mmdb + remoteIpHeader: "CLIENT-IP" #default is X-FORWARDED-FOR (when used behind a loadbalancer) + cacheTTL: 120 #In seconds, Default is 300 seconds + cacheMaxEntries: 102400 #Default is 10240 + enterprise: true #default: false. Enable maxmind enterprise database mode + type: anonymous #If it is not a enterprise database; set the type of database that is being used. Supported: country, city, anonymous + maxMindContext: false #If you need MaxMindInfo injection into resource methods; set it to true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8140dbd..cb9865a 100644 --- a/pom.xml +++ b/pom.xml @@ -44,10 +44,10 @@ UTF-8 - 1.3.13 + 2.0.16 2.12.0 1.18.8 - 4.12 + 5.7.0 1.8 1.8 @@ -83,11 +83,13 @@ ${lombok.version} provided + - junit - junit + org.junit.jupiter + junit-jupiter-api ${junit.version} test + diff --git a/src/main/java/io/dropwizard/maxmind/geoip2/MaxMindBundle.java b/src/main/java/io/dropwizard/maxmind/geoip2/MaxMindBundle.java index 8cf5cf6..f118b92 100644 --- a/src/main/java/io/dropwizard/maxmind/geoip2/MaxMindBundle.java +++ b/src/main/java/io/dropwizard/maxmind/geoip2/MaxMindBundle.java @@ -18,21 +18,17 @@ import io.dropwizard.Configuration; import io.dropwizard.ConfiguredBundle; import io.dropwizard.maxmind.geoip2.config.MaxMindConfig; +import io.dropwizard.maxmind.geoip2.feature.MaxMindContextFeature; import io.dropwizard.maxmind.geoip2.filter.MaxMindGeoIpRequestFilter; -import io.dropwizard.maxmind.geoip2.provider.MaxMindContext; -import io.dropwizard.maxmind.geoip2.provider.MaxMindInfoProvider; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; -import org.glassfish.hk2.api.InjectionResolver; -import org.glassfish.hk2.api.TypeLiteral; -import org.glassfish.hk2.utilities.binding.AbstractBinder; -import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider; +import lombok.extern.slf4j.Slf4j; -import javax.inject.Singleton; /** * @author phaneesh */ +@Slf4j public abstract class MaxMindBundle implements ConfiguredBundle { public abstract MaxMindConfig getMaxMindConfig(final T configuration); @@ -47,14 +43,7 @@ public void run(final T configuration, final Environment environment) { MaxMindConfig maxMindConfig = getMaxMindConfig(configuration); environment.jersey().register(new MaxMindGeoIpRequestFilter(maxMindConfig)); if(maxMindConfig.isMaxMindContext()) { - environment.jersey().register(new AbstractBinder() { - @Override - protected void configure() { - bind(MaxMindInfoProvider.class).to(ValueFactoryProvider.class).in(Singleton.class); - bind(MaxMindInfoProvider.InjectResolver.class).to( - new TypeLiteral>() {}).in(Singleton.class); - } - }); + environment.jersey().register(MaxMindContextFeature.class); } } } diff --git a/src/main/java/io/dropwizard/maxmind/geoip2/feature/MaxMindContextFeature.java b/src/main/java/io/dropwizard/maxmind/geoip2/feature/MaxMindContextFeature.java new file mode 100644 index 0000000..85b5016 --- /dev/null +++ b/src/main/java/io/dropwizard/maxmind/geoip2/feature/MaxMindContextFeature.java @@ -0,0 +1,22 @@ +package io.dropwizard.maxmind.geoip2.feature; + +import io.dropwizard.maxmind.geoip2.provider.MaxMindContextValueParamProvider; +import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.server.spi.internal.ValueParamProvider; +import javax.ws.rs.core.Feature; +import javax.ws.rs.core.FeatureContext; + +public class MaxMindContextFeature implements Feature { + @Override + public boolean configure(FeatureContext context) { + context.register(new AbstractBinder() { + @Override + protected void configure() { + bind(MaxMindContextValueParamProvider.class) + .to(ValueParamProvider.class); + } + }); + + return true; + } +} diff --git a/src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindInfoProvider.java b/src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindContextValueParamProvider.java similarity index 51% rename from src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindInfoProvider.java rename to src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindContextValueParamProvider.java index 2cdf877..0ba9554 100644 --- a/src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindInfoProvider.java +++ b/src/main/java/io/dropwizard/maxmind/geoip2/provider/MaxMindContextValueParamProvider.java @@ -21,19 +21,19 @@ import io.dropwizard.maxmind.geoip2.core.MaxMindHeaders; import io.dropwizard.maxmind.geoip2.core.MaxMindInfo; import lombok.extern.slf4j.Slf4j; -import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory; -import org.glassfish.jersey.server.internal.inject.AbstractValueFactoryProvider; -import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider; -import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver; +import org.glassfish.jersey.server.ContainerRequest; import org.glassfish.jersey.server.model.Parameter; +import org.glassfish.jersey.server.spi.internal.ValueParamProvider; + -import javax.inject.Inject; import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; /** * @author phaneesh @@ -41,38 +41,35 @@ @Slf4j @Singleton @Provider -public class MaxMindInfoProvider extends AbstractValueFactoryProvider { - - - public static final class InjectResolver extends ParamInjectionResolver { +public class MaxMindContextValueParamProvider implements ValueParamProvider { - public InjectResolver() { - super(MaxMindInfoProvider.class); + @Override + public Function getValueProvider(Parameter parameter) { + if (parameter.getRawType().equals(MaxMindInfo.class) + && parameter.isAnnotationPresent(MaxMindContext.class)) { + return new MaxMindInfoParamProvider(); } + return null; } + public static final class MaxMindInfoParamProvider implements Function { - private static final class MaxMinfInfoParamValueFactory extends AbstractContainerRequestValueFactory { - - @Context - private ResourceContext context; - - public MaxMindInfo provide() { - final HttpServletRequest request = context.getResource(HttpServletRequest.class); - final String anonymousIp = request.getHeader(MaxMindHeaders.X_ANONYMOUS_IP); - final String anonymousVpn = request.getHeader(MaxMindHeaders.X_ANONYMOUS_VPN); - final String tor = request.getHeader(MaxMindHeaders.X_TOR); - final String city = request.getHeader(MaxMindHeaders.X_CITY); - final String state = request.getHeader(MaxMindHeaders.X_STATE); - final String stateIso = request.getHeader(MaxMindHeaders.X_STATE_ISO); - final String postal = request.getHeader(MaxMindHeaders.X_POSTAL); - final String connectionType = request.getHeader(MaxMindHeaders.X_CONNECTION_TYPE); - final String userType = request.getHeader(MaxMindHeaders.X_USER_TYPE); - final String country = request.getHeader(MaxMindHeaders.X_COUNTRY); - final String countryIso = request.getHeader(MaxMindHeaders.X_COUNTRY_ISO); - final String isp = request.getHeader(MaxMindHeaders.X_ISP); - final String latitude = request.getHeader(MaxMindHeaders.X_LATITUDE); - final String longitude = request.getHeader(MaxMindHeaders.X_LONGITUDE); - final String accuracy = request.getHeader(MaxMindHeaders.X_LOCATION_ACCURACY); + @Override + public MaxMindInfo apply(@Context ContainerRequest request) { + final String anonymousIp = getHeader(request,MaxMindHeaders.X_ANONYMOUS_IP); + final String anonymousVpn = getHeader(request,MaxMindHeaders.X_ANONYMOUS_VPN); + final String tor = getHeader(request,MaxMindHeaders.X_TOR); + final String city = getHeader(request,MaxMindHeaders.X_CITY); + final String state = getHeader(request,MaxMindHeaders.X_STATE); + final String stateIso = getHeader(request,MaxMindHeaders.X_STATE_ISO); + final String postal = getHeader(request,MaxMindHeaders.X_POSTAL); + final String connectionType = getHeader(request,MaxMindHeaders.X_CONNECTION_TYPE); + final String userType = getHeader(request,MaxMindHeaders.X_USER_TYPE); + final String country = getHeader(request,MaxMindHeaders.X_COUNTRY); + final String countryIso = getHeader(request,MaxMindHeaders.X_COUNTRY_ISO); + final String isp = getHeader(request,MaxMindHeaders.X_ISP); + final String latitude = getHeader(request,MaxMindHeaders.X_LATITUDE); + final String longitude = getHeader(request,MaxMindHeaders.X_LONGITUDE); + final String accuracy = getHeader(request,MaxMindHeaders.X_LOCATION_ACCURACY); return MaxMindInfo.builder() .anonymousIp(Strings.isNullOrEmpty(anonymousIp) ? false : Boolean.valueOf(anonymousIp)) .anonymousVpn(Strings.isNullOrEmpty(anonymousVpn) ? false : Boolean.valueOf(anonymousVpn)) @@ -91,21 +88,17 @@ public MaxMindInfo provide() { .accuracy(Strings.isNullOrEmpty(accuracy) ? 0 : Integer.valueOf(accuracy)) .build(); } + private String getHeader(ContainerRequest request,String name) { + List headerList = request.getRequestHeader(name); + return Optional.ofNullable(headerList) + .map(Collection::stream) + .orElseGet(Stream::empty) + .findFirst() + .orElse(null); + } } - - @Inject - public MaxMindInfoProvider(MultivaluedParameterExtractorProvider extractorProvider, ServiceLocator locator) { - super(extractorProvider, locator, Parameter.Source.UNKNOWN); - } - @Override - protected AbstractContainerRequestValueFactory createValueFactory(Parameter parameter) { - Class classType = parameter.getRawType(); - - if (classType == null || (!classType.equals(MaxMindInfo.class))) { - log.warn("MaxMindContext annotation was not placed on correct object type; Injection might not work correctly!"); - return null; - } - return new MaxMinfInfoParamValueFactory(); + public PriorityType getPriority() { + return Priority.HIGH; } }