Skip to content

Commit

Permalink
Merge dropwizard-java8 addon into mainline
Browse files Browse the repository at this point in the history
dropwizard-java8 used to provide support for Java 8 classes like `Optional<T>` and
the Java Date and Time API (JSR-310) for Dropwizard. Given that the baseline for
Dropwizard is now Java 8, those additions can be maintained in the mainline repository.

The only backward-incompatible change is in the `io.dropwizard.auth.Authenticator` interface
which is now using `java.util.Optional` instead of the equivalent class from Google Guava.

Closes #962
  • Loading branch information
joschi committed Nov 29, 2015
1 parent e03c043 commit 3a05b91
Show file tree
Hide file tree
Showing 128 changed files with 4,657 additions and 209 deletions.
@@ -1,8 +1,7 @@
package io.dropwizard.auth; package io.dropwizard.auth;


import com.google.common.base.Optional;

import java.security.Principal; import java.security.Principal;
import java.util.Optional;


/** /**
* An interface for classes which authenticate user-provided credentials and return principal * An interface for classes which authenticate user-provided credentials and return principal
Expand All @@ -14,10 +13,10 @@
public interface Authenticator<C, P extends Principal> { public interface Authenticator<C, P extends Principal> {
/** /**
* Given a set of user-provided credentials, return an optional principal. * Given a set of user-provided credentials, return an optional principal.
* <p/> *
* If the credentials are valid and map to a principal, returns an {@code Optional.of(p)}. * If the credentials are valid and map to a principal, returns an {@link Optional#of(Object)}.
* <p/> *
* If the credentials are invalid, returns an {@code Optional.absent()}. * If the credentials are invalid, returns an {@link Optional#empty()}.
* *
* @param credentials a set of user-provided credentials * @param credentials a set of user-provided credentials
* @return either an authenticated principal or an absent optional * @return either an authenticated principal or an absent optional
Expand Down
Expand Up @@ -3,14 +3,15 @@
import com.codahale.metrics.Meter; import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer; import com.codahale.metrics.Timer;
import com.google.common.base.Optional;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheBuilderSpec; import com.google.common.cache.CacheBuilderSpec;
import com.google.common.cache.CacheStats; import com.google.common.cache.CacheStats;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.security.Principal; import java.security.Principal;
import java.util.Optional;

import static com.codahale.metrics.MetricRegistry.name; import static com.codahale.metrics.MetricRegistry.name;


/** /**
Expand Down
@@ -1,6 +1,5 @@
package io.dropwizard.auth.basic; package io.dropwizard.auth.basic;


import com.google.common.base.Optional;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import io.dropwizard.auth.AuthenticationException; import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.AuthFilter; import io.dropwizard.auth.AuthFilter;
Expand All @@ -17,6 +16,7 @@
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.Principal; import java.security.Principal;
import java.util.Optional;


@Priority(Priorities.AUTHENTICATION) @Priority(Priorities.AUTHENTICATION)
public class BasicCredentialAuthFilter<P extends Principal> extends AuthFilter<BasicCredentials, P> { public class BasicCredentialAuthFilter<P extends Principal> extends AuthFilter<BasicCredentials, P> {
Expand Down
@@ -1,6 +1,5 @@
package io.dropwizard.auth.oauth; package io.dropwizard.auth.oauth;


import com.google.common.base.Optional;
import io.dropwizard.auth.AuthenticationException; import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.AuthFilter; import io.dropwizard.auth.AuthFilter;
import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.Authenticator;
Expand All @@ -16,6 +15,7 @@
import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.SecurityContext;
import java.io.IOException; import java.io.IOException;
import java.security.Principal; import java.security.Principal;
import java.util.Optional;


@Priority(Priorities.AUTHENTICATION) @Priority(Priorities.AUTHENTICATION)
public class OAuthCredentialAuthFilter<P extends Principal> extends AuthFilter<String, P> { public class OAuthCredentialAuthFilter<P extends Principal> extends AuthFilter<String, P> {
Expand Down
@@ -1,15 +1,14 @@
package io.dropwizard.auth; package io.dropwizard.auth;


import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilderSpec; import com.google.common.cache.CacheBuilderSpec;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InOrder; import org.mockito.InOrder;


import java.security.Principal; import java.security.Principal;
import java.util.Optional;


import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.anyString;
Expand All @@ -23,7 +22,7 @@ public class CachingAuthenticatorTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private final Authenticator<String, Principal> underlying = mock(Authenticator.class); private final Authenticator<String, Principal> underlying = mock(Authenticator.class);
private final CachingAuthenticator<String, Principal> cached = private final CachingAuthenticator<String, Principal> cached =
new CachingAuthenticator<>(new MetricRegistry(), underlying, CacheBuilderSpec.parse("maximumSize=1")); new CachingAuthenticator<>(new MetricRegistry(), underlying, CacheBuilderSpec.parse("maximumSize=1"));


@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
Expand Down Expand Up @@ -70,15 +69,8 @@ public void invalidatesSetsOfCredentials() throws Exception {


@Test @Test
public void invalidatesCredentialsMatchingGivenPredicate() throws Exception { public void invalidatesCredentialsMatchingGivenPredicate() throws Exception {
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean apply(String c) {
return c.equals("credentials");
}
};

cached.authenticate("credentials"); cached.authenticate("credentials");
cached.invalidateAll(predicate); cached.invalidateAll("credentials"::equals);
cached.authenticate("credentials"); cached.authenticate("credentials");


verify(underlying, times(2)).authenticate("credentials"); verify(underlying, times(2)).authenticate("credentials");
Expand Down Expand Up @@ -108,8 +100,8 @@ public void calculatesCacheStats() throws Exception {


@Test @Test
public void shouldNotCacheAbsentPrincipals() throws Exception { public void shouldNotCacheAbsentPrincipals() throws Exception {
when(underlying.authenticate(anyString())).thenReturn(Optional.<Principal>absent()); when(underlying.authenticate(anyString())).thenReturn(Optional.<Principal>empty());
assertThat(cached.authenticate("credentials")).isEqualTo(Optional.absent()); assertThat(cached.authenticate("credentials")).isEqualTo(Optional.empty());
verify(underlying).authenticate("credentials"); verify(underlying).authenticate("credentials");
assertThat(cached.size()).isEqualTo(0); assertThat(cached.size()).isEqualTo(0);
} }
Expand Down
Expand Up @@ -21,6 +21,7 @@
public class ChainedAuthProviderTest extends AuthBaseTest<ChainedAuthProviderTest.ChainedAuthTestResourceConfig>{ public class ChainedAuthProviderTest extends AuthBaseTest<ChainedAuthProviderTest.ChainedAuthTestResourceConfig>{
private static final String BEARER_USER = "A12B3C4D"; private static final String BEARER_USER = "A12B3C4D";
public static class ChainedAuthTestResourceConfig extends DropwizardResourceConfig { public static class ChainedAuthTestResourceConfig extends DropwizardResourceConfig {
@SuppressWarnings("unchecked")
public ChainedAuthTestResourceConfig() { public ChainedAuthTestResourceConfig() {
super(true, new MetricRegistry()); super(true, new MetricRegistry());


Expand Down
69 changes: 29 additions & 40 deletions dropwizard-auth/src/test/java/io/dropwizard/auth/util/AuthUtil.java
@@ -1,69 +1,58 @@
package io.dropwizard.auth.util; package io.dropwizard.auth.util;


import com.google.common.base.Optional; import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.*; import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.Authorizer;
import io.dropwizard.auth.PrincipalImpl;
import io.dropwizard.auth.basic.BasicCredentials; import io.dropwizard.auth.basic.BasicCredentials;


import java.security.Principal; import java.security.Principal;
import java.util.List; import java.util.List;
import java.util.Optional;


public class AuthUtil { public class AuthUtil {


public static Authenticator<BasicCredentials, Principal> getBasicAuthenticator(final List<String> validUsers) { public static Authenticator<BasicCredentials, Principal> getBasicAuthenticator(final List<String> validUsers) {
return new Authenticator<BasicCredentials, Principal>() { return credentials -> {
@Override if (validUsers.contains(credentials.getUsername()) && "secret".equals(credentials.getPassword())) {
public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException { return Optional.<Principal>of(new PrincipalImpl(credentials.getUsername()));
if (validUsers.contains(credentials.getUsername()) && "secret".equals(credentials.getPassword())) {
return Optional.<Principal>of(new PrincipalImpl(credentials.getUsername()));
}
if ("bad-guy".equals(credentials.getUsername())) {
throw new AuthenticationException("CRAP");
}
return Optional.absent();
} }
if ("bad-guy".equals(credentials.getUsername())) {
throw new AuthenticationException("CRAP");
}
return Optional.empty();
}; };
} }


public static Authenticator<String, Principal> getSingleUserOAuthAuthenticator(final String presented, public static Authenticator<String, Principal> getSingleUserOAuthAuthenticator(final String presented,
final String returned) { final String returned) {
return new Authenticator<String, Principal>() { return user -> {
@Override if (presented.equals(user)) {
public Optional<Principal> authenticate(String user) throws AuthenticationException { return Optional.<Principal>of(new PrincipalImpl(returned));
if (presented.equals(user)) { }
return Optional.<Principal>of(new PrincipalImpl(returned)); if ("bad-guy".equals(user)) {
} throw new AuthenticationException("CRAP");
if ("bad-guy".equals(user)) {
throw new AuthenticationException("CRAP");
}
return Optional.absent();
} }
return Optional.empty();
}; };
} }


public static Authenticator<String, Principal> getMultiplyUsersOAuthAuthenticator(final List<String> validUsers) { public static Authenticator<String, Principal> getMultiplyUsersOAuthAuthenticator(final List<String> validUsers) {
return new Authenticator<String, Principal>() { return credentials -> {
@Override if (validUsers.contains(credentials)) {
public Optional<Principal> authenticate(String credentials) throws AuthenticationException { return Optional.<Principal>of(new PrincipalImpl(credentials));
if (validUsers.contains(credentials)) { }
return Optional.<Principal>of(new PrincipalImpl(credentials)); if ("bad-guy".equals(credentials)) {
} throw new AuthenticationException("CRAP");
if (credentials.equals("bad-guy")) {
throw new AuthenticationException("CRAP");
}
return Optional.absent();
} }
return Optional.empty();
}; };
} }


public static Authorizer<Principal> getTestAuthorizer(final String validUser, public static Authorizer<Principal> getTestAuthorizer(final String validUser,
final String validRole) { final String validRole) {
return new Authorizer<Principal>() { return (principal, role) -> principal != null
@Override && validUser.equals(principal.getName())
public boolean authorize(Principal principal, String role) { && validRole.equals(role);
return principal != null
&& validUser.equals(principal.getName())
&& validRole.equals(role);
}
};
} }
} }
10 changes: 10 additions & 0 deletions dropwizard-bom/pom.xml
Expand Up @@ -274,6 +274,16 @@
<artifactId>jackson-datatype-jdk7</artifactId> <artifactId>jackson-datatype-jdk7</artifactId>
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId> <artifactId>jackson-datatype-guava</artifactId>
Expand Down
Expand Up @@ -8,10 +8,10 @@
import io.dropwizard.Configuration; import io.dropwizard.Configuration;
import io.dropwizard.configuration.DefaultConfigurationFactoryFactory; import io.dropwizard.configuration.DefaultConfigurationFactoryFactory;
import io.dropwizard.configuration.FileConfigurationSourceProvider; import io.dropwizard.configuration.FileConfigurationSourceProvider;

import io.dropwizard.jackson.Jackson; import io.dropwizard.jackson.Jackson;
import io.dropwizard.jersey.validation.NonEmptyStringParamUnwrapper; import io.dropwizard.jersey.validation.NonEmptyStringParamUnwrapper;
import io.dropwizard.jersey.validation.ParamValidatorUnwrapper; import io.dropwizard.jersey.validation.ParamValidatorUnwrapper;
import io.dropwizard.validation.valuehandling.GuavaOptionalValidatedValueUnwrapper;
import io.dropwizard.validation.valuehandling.OptionalValidatedValueUnwrapper; import io.dropwizard.validation.valuehandling.OptionalValidatedValueUnwrapper;
import org.hibernate.validator.HibernateValidator; import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.internal.engine.ValidatorFactoryImpl; import org.hibernate.validator.internal.engine.ValidatorFactoryImpl;
Expand Down Expand Up @@ -103,7 +103,8 @@ public void defaultsToDefaultValidatorFactory() throws Exception {
// https://hibernate.atlassian.net/browse/HV-904 // https://hibernate.atlassian.net/browse/HV-904
assertThat(validatorFactory.getValidatedValueHandlers()) assertThat(validatorFactory.getValidatedValueHandlers())
.extractingResultOf("getClass") .extractingResultOf("getClass")
.containsSubsequence(OptionalValidatedValueUnwrapper.class, .containsSubsequence(GuavaOptionalValidatedValueUnwrapper.class,
OptionalValidatedValueUnwrapper.class,
NonEmptyStringParamUnwrapper.class, NonEmptyStringParamUnwrapper.class,
ParamValidatorUnwrapper.class); ParamValidatorUnwrapper.class);
} }
Expand Down
@@ -1,17 +1,18 @@
package com.example.helloworld.auth; package com.example.helloworld.auth;


import com.example.helloworld.core.User; import com.example.helloworld.core.User;
import com.google.common.base.Optional;
import io.dropwizard.auth.AuthenticationException; import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials; import io.dropwizard.auth.basic.BasicCredentials;


import java.util.Optional;

public class ExampleAuthenticator implements Authenticator<BasicCredentials, User> { public class ExampleAuthenticator implements Authenticator<BasicCredentials, User> {
@Override @Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException { public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
if ("secret".equals(credentials.getPassword())) { if ("secret".equals(credentials.getPassword())) {
return Optional.of(new User(credentials.getUsername())); return Optional.of(new User(credentials.getUsername()));
} }
return Optional.absent(); return Optional.empty();
} }
} }
8 changes: 8 additions & 0 deletions dropwizard-jackson/pom.xml
Expand Up @@ -52,6 +52,14 @@
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId> <artifactId>jackson-datatype-guava</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.module</groupId> <groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-afterburner</artifactId> <artifactId>jackson-module-afterburner</artifactId>
Expand Down
Expand Up @@ -4,7 +4,9 @@
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.guava.GuavaModule; import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.datatype.jdk7.Jdk7Module; import com.fasterxml.jackson.datatype.jdk7.Jdk7Module;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.joda.JodaModule; import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule; import com.fasterxml.jackson.module.afterburner.AfterburnerModule;


/** /**
Expand Down Expand Up @@ -57,6 +59,8 @@ private static ObjectMapper configure(ObjectMapper mapper) {
mapper.registerModule(new AfterburnerModule()); mapper.registerModule(new AfterburnerModule());
mapper.registerModule(new FuzzyEnumModule()); mapper.registerModule(new FuzzyEnumModule());
mapper.registerModule(new Jdk7Module()); mapper.registerModule(new Jdk7Module());
mapper.registerModules(new Jdk8Module());
mapper.registerModules(new JavaTimeModule());
mapper.setPropertyNamingStrategy(new AnnotationSensitivePropertyNamingStrategy()); mapper.setPropertyNamingStrategy(new AnnotationSensitivePropertyNamingStrategy());
mapper.setSubtypeResolver(new DiscoverableSubtypeResolver()); mapper.setSubtypeResolver(new DiscoverableSubtypeResolver());


Expand Down

0 comments on commit 3a05b91

Please sign in to comment.