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
Expand Up @@ -229,11 +229,6 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
Expand Down
Expand Up @@ -25,9 +25,14 @@
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.ttl;
import static org.apache.james.jmap.api.access.AccessTokenRepository.TOKEN_EXPIRATION_IN_MS;

import java.util.Optional;
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.jmap.api.access.AccessToken;
Expand All @@ -47,9 +52,10 @@ public class CassandraAccessTokenDAO {
private final PreparedStatement selectStatement;
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.durationInSeconds = Ints.checkedCast(durationInMilliseconds / 1000);
this.durationInSeconds = Ints.checkedCast(TimeUnit.MILLISECONDS.toSeconds(durationInMilliseconds));

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

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

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

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

public class CassandraAccessTokenRepository implements AccessTokenRepository {

private final CassandraAccessTokenDAO cassandraAccessTokenDAO;

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

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

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

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

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

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

import com.jasongoodwin.monads.Try;

public interface AccessTokenRepository {

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

CompletableFuture<Void> removeToken(AccessToken accessToken);

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

}
Expand Up @@ -21,6 +21,7 @@

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

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

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

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

@Override
public CompletableFuture<Try<String>> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
public CompletableFuture<String> getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken {
Preconditions.checkNotNull(accessToken);
synchronized (tokensExpirationDates) {
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
Expand Up @@ -22,6 +22,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.util.concurrent.CompletionException;

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

private static final AccessToken TOKEN = AccessToken.generate();
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;

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

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

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

@Test
public void outDatedTokenMustBeInvalid() throws Exception {
accessTokenRepository.addToken(USERNAME, TOKEN);
accessTokenRepository.addToken(USERNAME, TOKEN).join();
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)
Expand Down
Expand Up @@ -19,6 +19,9 @@

package org.apache.james.jmap.crypto;

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

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

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

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

@Test(expected=NullPointerException.class)
Expand Down

0 comments on commit e71a7cd

Please sign in to comment.