Skip to content

Commit

Permalink
JAMES-1718 rely on runtime exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
chibenwa committed Apr 15, 2016
1 parent 7e39d44 commit e71a7cd
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 42 deletions.
5 changes: 0 additions & 5 deletions server/data/data-jmap-cassandra/pom.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -229,11 +229,6 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</profile> </profile>
<profile> <profile>
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto; import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
import static com.datastax.driver.core.querybuilder.QueryBuilder.select; import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl; import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl;
import static org.apache.james.jmap.api.access.AccessTokenRepository.TOKEN_EXPIRATION_IN_MS;


import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
import javax.inject.Named;


import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor; import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
import org.apache.james.jmap.api.access.AccessToken; import org.apache.james.jmap.api.access.AccessToken;
Expand All @@ -47,9 +52,10 @@ public class CassandraAccessTokenDAO {
private final PreparedStatement selectStatement; private final PreparedStatement selectStatement;
private final int durationInSeconds; private final int durationInSeconds;


public CassandraAccessTokenDAO(Session session, long durationInMilliseconds) { @Inject
public CassandraAccessTokenDAO(Session session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) {
this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session); this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
this.durationInSeconds = Ints.checkedCast(durationInMilliseconds / 1000); this.durationInSeconds = Ints.checkedCast(TimeUnit.MILLISECONDS.toSeconds(durationInMilliseconds));


this.removeStatement = session.prepare(delete() this.removeStatement = session.prepare(delete()
.from(CassandraAccessTokenTable.TABLE_NAME) .from(CassandraAccessTokenTable.TABLE_NAME)
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,23 +22,20 @@
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;


import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;


import org.apache.james.jmap.api.access.AccessToken; import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.api.access.AccessTokenRepository; import org.apache.james.jmap.api.access.AccessTokenRepository;
import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;


import com.datastax.driver.core.Session;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.jasongoodwin.monads.Try;


public class CassandraAccessTokenRepository implements AccessTokenRepository { public class CassandraAccessTokenRepository implements AccessTokenRepository {


private final CassandraAccessTokenDAO cassandraAccessTokenDAO; private final CassandraAccessTokenDAO cassandraAccessTokenDAO;


@Inject @Inject
public CassandraAccessTokenRepository(Session session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) { public CassandraAccessTokenRepository(CassandraAccessTokenDAO cassandraAccessTokenDAO) {
this.cassandraAccessTokenDAO = new CassandraAccessTokenDAO(session, durationInMilliseconds); this.cassandraAccessTokenDAO = cassandraAccessTokenDAO;
} }


@Override @Override
Expand All @@ -58,13 +55,11 @@ public CompletableFuture<Void> removeToken(AccessToken accessToken) {
} }


@Override @Override
public CompletableFuture<Try<String>> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken { public CompletableFuture<String> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
Preconditions.checkNotNull(accessToken); Preconditions.checkNotNull(accessToken);


return cassandraAccessTokenDAO.getUsernameFromToken(accessToken) return cassandraAccessTokenDAO.getUsernameFromToken(accessToken)
.thenApply( .thenApply(
optional -> Try.ofFailable( optional -> optional.<InvalidAccessToken>orElseThrow(() -> new InvalidAccessToken(accessToken)));
() -> optional.orElseThrow(
() -> new InvalidAccessToken(accessToken))));
} }
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class CassandraAccessTokenRepositoryTest extends AbstractAccessTokenRepos
@Override @Override
protected AccessTokenRepository createAccessTokenRepository() { protected AccessTokenRepository createAccessTokenRepository() {
cassandra = CassandraCluster.create(new CassandraAccessModule()); cassandra = CassandraCluster.create(new CassandraAccessModule());
return new CassandraAccessTokenRepository(cassandra.getConf(), TTL_IN_MS); return new CassandraAccessTokenRepository(new CassandraAccessTokenDAO(cassandra.getConf(), TTL_IN_MS));
} }


@After @After
Expand Down
4 changes: 0 additions & 4 deletions server/data/data-jmap/pom.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -181,10 +181,6 @@
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.jason-goodwin</groupId>
<artifactId>better-monads</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId> <artifactId>commons-collections4</artifactId>
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@


import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;


import com.jasongoodwin.monads.Try;

public interface AccessTokenRepository { public interface AccessTokenRepository {


String TOKEN_EXPIRATION_IN_MS = "tokenExpirationInMs"; String TOKEN_EXPIRATION_IN_MS = "tokenExpirationInMs";
Expand All @@ -33,6 +31,6 @@ public interface AccessTokenRepository {


CompletableFuture<Void> removeToken(AccessToken accessToken); CompletableFuture<Void> removeToken(AccessToken accessToken);


CompletableFuture<Try<String>> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken; CompletableFuture<String> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken;


} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@


import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;


import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
Expand All @@ -32,7 +33,6 @@
import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;


import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.jasongoodwin.monads.Try;


@Singleton @Singleton
public class MemoryAccessTokenRepository implements AccessTokenRepository { public class MemoryAccessTokenRepository implements AccessTokenRepository {
Expand Down Expand Up @@ -65,11 +65,12 @@ public CompletableFuture<Void> removeToken(AccessToken accessToken) {
} }


@Override @Override
public CompletableFuture<Try<String>> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken { public CompletableFuture<String> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
Preconditions.checkNotNull(accessToken); Preconditions.checkNotNull(accessToken);
synchronized (tokensExpirationDates) { synchronized (tokensExpirationDates) {
return CompletableFuture.completedFuture( return CompletableFuture.completedFuture(
Try.ofFailable(() -> Optional.ofNullable(tokensExpirationDates.get(accessToken)).orElseThrow(() -> new InvalidAccessToken(accessToken)))); Optional.ofNullable(tokensExpirationDates.get(accessToken))
.<CompletionException>orElseThrow(() -> new CompletionException(new InvalidAccessToken(accessToken))));
} }
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;


import java.util.concurrent.CompletionException;

import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
Expand All @@ -30,7 +32,7 @@ public abstract class AbstractAccessTokenRepositoryTest {


private static final AccessToken TOKEN = AccessToken.generate(); private static final AccessToken TOKEN = AccessToken.generate();
private static final String USERNAME = "username"; private static final String USERNAME = "username";
public static final long TTL_IN_MS = 1000; protected static final long TTL_IN_MS = 1000;


private AccessTokenRepository accessTokenRepository; private AccessTokenRepository accessTokenRepository;


Expand All @@ -43,27 +45,30 @@ public void setUp() {


@Test @Test
public void validTokenMustBeRetrieved() throws Throwable { public void validTokenMustBeRetrieved() throws Throwable {
accessTokenRepository.addToken(USERNAME, TOKEN); accessTokenRepository.addToken(USERNAME, TOKEN).join();
assertThat(accessTokenRepository.getUsernameFromToken(TOKEN).join().get()).isEqualTo(USERNAME); assertThat(accessTokenRepository.getUsernameFromToken(TOKEN).join()).isEqualTo(USERNAME);
} }


@Test @Test
public void absentTokensMustBeInvalid() throws Exception { public void absentTokensMustBeInvalid() throws Exception {
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join().get()).isInstanceOf(InvalidAccessToken.class); assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).isInstanceOf(CompletionException.class);
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).hasCauseInstanceOf(InvalidAccessToken.class);
} }


@Test @Test
public void removedTokensMustBeInvalid() throws Exception { public void removedTokensMustBeInvalid() throws Exception {
accessTokenRepository.addToken(USERNAME, TOKEN); accessTokenRepository.addToken(USERNAME, TOKEN).join();
accessTokenRepository.removeToken(TOKEN); accessTokenRepository.removeToken(TOKEN).join();
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join().get()).isInstanceOf(InvalidAccessToken.class); assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).isInstanceOf(CompletionException.class);
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).hasCauseInstanceOf(InvalidAccessToken.class);
} }


@Test @Test
public void outDatedTokenMustBeInvalid() throws Exception { public void outDatedTokenMustBeInvalid() throws Exception {
accessTokenRepository.addToken(USERNAME, TOKEN); accessTokenRepository.addToken(USERNAME, TOKEN).join();
Thread.sleep(2 * TTL_IN_MS); Thread.sleep(2 * TTL_IN_MS);
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join().get()).isInstanceOf(InvalidAccessToken.class); assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).isInstanceOf(CompletionException.class);
assertThatThrownBy(() -> accessTokenRepository.getUsernameFromToken(TOKEN).join()).hasCauseInstanceOf(InvalidAccessToken.class);
} }


@Test(expected = NullPointerException.class) @Test(expected = NullPointerException.class)
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@


package org.apache.james.jmap.crypto; package org.apache.james.jmap.crypto;


import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;

import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;


Expand Down Expand Up @@ -51,11 +54,13 @@ public AccessToken grantAccessToken(String username) {
@Override @Override
public String getUsernameFromToken(AccessToken token) throws InvalidAccessToken { public String getUsernameFromToken(AccessToken token) throws InvalidAccessToken {
try { try {
return accessTokenRepository.getUsernameFromToken(token).join().get(); return accessTokenRepository.getUsernameFromToken(token).join();
} catch (InvalidAccessToken invalidAccessToken) { } catch (CompletionException completionException) {
throw invalidAccessToken; if (completionException.getCause() instanceof InvalidAccessToken) {
} catch (Throwable throwable) { throw (InvalidAccessToken) completionException.getCause();
throw Throwables.propagate(throwable); } else {
throw Throwables.propagate(completionException);
}
} }
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void grantShouldGenerateATokenOnUsername() throws Exception {
@Test @Test
public void grantShouldStoreATokenOnUsername() throws Exception { public void grantShouldStoreATokenOnUsername() throws Exception {
AccessToken token = accessTokenManager.grantAccessToken("username"); AccessToken token = accessTokenManager.grantAccessToken("username");
assertThat(accessTokenRepository.getUsernameFromToken(token).join().get()).isEqualTo("username"); assertThat(accessTokenRepository.getUsernameFromToken(token).join()).isEqualTo("username");
} }


@Test(expected=NullPointerException.class) @Test(expected=NullPointerException.class)
Expand Down

0 comments on commit e71a7cd

Please sign in to comment.