JAMES-1718 Cassandra JMAP data classes should be located in a specific project
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/86ba885e Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/86ba885e Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/86ba885e Branch: refs/heads/master Commit: 86ba885e6fa1c3d2ccd71caebd55c4c88b80e6da Parents: e344967 Author: Benoit Tellier <[email protected]> Authored: Mon Apr 11 16:35:28 2016 +0700 Committer: Benoit Tellier <[email protected]> Committed: Fri Apr 15 15:49:48 2016 +0700 ---------------------------------------------------------------------- server/container/guice/cassandra-guice/pom.xml | 4 + .../james/modules/data/CassandraJmapModule.java | 2 + server/data/data-cassandra/pom.xml | 10 - .../cassandra/access/CassandraAccessModule.java | 67 ----- .../access/CassandraAccessTokenRepository.java | 113 -------- .../access/table/CassandraAccessTokenTable.java | 29 -- .../CassandraAccessTokenRepositoryTest.java | 41 --- server/data/data-jmap-cassandra/pom.xml | 262 +++++++++++++++++++ .../cassandra/access/CassandraAccessModule.java | 67 +++++ .../access/CassandraAccessTokenRepository.java | 113 ++++++++ .../access/table/CassandraAccessTokenTable.java | 29 ++ .../CassandraAccessTokenRepositoryTest.java | 41 +++ server/pom.xml | 6 + 13 files changed, 524 insertions(+), 260 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/container/guice/cassandra-guice/pom.xml ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml index 254d6ef..b554af0 100644 --- a/server/container/guice/cassandra-guice/pom.xml +++ b/server/container/guice/cassandra-guice/pom.xml @@ -225,6 +225,10 @@ <artifactId>james-server-data-cassandra</artifactId> </dependency> <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-data-jmap-cassandra</artifactId> + </dependency> + <dependency> <groupId>${project.groupId}</groupId> <artifactId>james-server-guice-common</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java index 23f3d2a..7162434 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraJmapModule.java @@ -25,12 +25,14 @@ import org.apache.james.jmap.cassandra.access.CassandraAccessModule; import org.apache.james.jmap.cassandra.access.CassandraAccessTokenRepository; import com.google.inject.AbstractModule; +import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; public class CassandraJmapModule extends AbstractModule { @Override protected void configure() { + bind(CassandraAccessTokenRepository.class).in(Scopes.SINGLETON); bind(AccessTokenRepository.class).to(CassandraAccessTokenRepository.class); Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class); http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/pom.xml b/server/data/data-cassandra/pom.xml index d10118e..f37e520 100644 --- a/server/data/data-cassandra/pom.xml +++ b/server/data/data-cassandra/pom.xml @@ -178,16 +178,6 @@ <artifactId>james-server-data-api</artifactId> </dependency> <dependency> - <groupId>org.apache.james</groupId> - <artifactId>james-server-data-jmap</artifactId> - </dependency> - <dependency> - <groupId>org.apache.james</groupId> - <artifactId>james-server-data-jmap</artifactId> - <scope>test</scope> - <type>test-jar</type> - </dependency> - <dependency> <groupId>${project.groupId}</groupId> <artifactId>james-server-data-library</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java deleted file mode 100644 index 8125ef2..0000000 --- a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.cassandra.access; - -import static com.datastax.driver.core.DataType.text; -import static com.datastax.driver.core.DataType.uuid; - -import java.util.List; - -import org.apache.james.backends.cassandra.components.CassandraIndex; -import org.apache.james.backends.cassandra.components.CassandraModule; -import org.apache.james.backends.cassandra.components.CassandraTable; -import org.apache.james.backends.cassandra.components.CassandraType; -import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; - -import com.datastax.driver.core.schemabuilder.SchemaBuilder; -import com.google.common.collect.ImmutableList; - -public class CassandraAccessModule implements CassandraModule { - - private final List<CassandraTable> tables; - private final List<CassandraIndex> index; - private final List<CassandraType> types; - - public CassandraAccessModule() { - tables = ImmutableList.of( - new CassandraTable(CassandraAccessTokenTable.TABLE_NAME, - SchemaBuilder.createTable(CassandraAccessTokenTable.TABLE_NAME) - .ifNotExists() - .addPartitionKey(CassandraAccessTokenTable.TOKEN, uuid()) - .addColumn(CassandraAccessTokenTable.USERNAME, text()))); - index = ImmutableList.of(); - types = ImmutableList.of(); - } - - @Override - public List<CassandraTable> moduleTables() { - return tables; - } - - @Override - public List<CassandraIndex> moduleIndex() { - return index; - } - - @Override - public List<CassandraType> moduleTypes() { - return types; - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java deleted file mode 100644 index b1b1b23..0000000 --- a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.cassandra.access; - -import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker; -import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; -import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; -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 java.util.Optional; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.apache.james.backends.cassandra.utils.CassandraConstants; -import org.apache.james.jmap.api.access.AccessToken; -import org.apache.james.jmap.api.access.AccessTokenRepository; -import org.apache.james.jmap.api.access.exceptions.AccessTokenAlreadyStored; -import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; -import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; - -import com.datastax.driver.core.PreparedStatement; -import com.datastax.driver.core.Session; -import com.google.common.base.Preconditions; - -public class CassandraAccessTokenRepository implements AccessTokenRepository { - - private static final String TTL = "ttl"; - - private final Session session; - private final PreparedStatement removeStatement; - private final PreparedStatement insertStatement; - private final PreparedStatement selectStatement; - private final int durationInSeconds; - - @Inject - public CassandraAccessTokenRepository(Session session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) { - this.session = session; - this.durationInSeconds = (int) (durationInMilliseconds / 1000); - - this.removeStatement = this.session.prepare(delete() - .from(CassandraAccessTokenTable.TABLE_NAME) - .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); - - this.insertStatement = this.session.prepare(insertInto(CassandraAccessTokenTable.TABLE_NAME) - .ifNotExists() - .value(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)) - .value(CassandraAccessTokenTable.USERNAME, bindMarker(CassandraAccessTokenTable.USERNAME)) - .using(ttl(bindMarker(TTL)))); - - this.selectStatement = this.session.prepare(select() - .from(CassandraAccessTokenTable.TABLE_NAME) - .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); - } - - @Override - public void addToken(String username, AccessToken accessToken) throws AccessTokenAlreadyStored { - Preconditions.checkNotNull(username); - Preconditions.checkArgument(! username.isEmpty(), "Username should not be empty"); - Preconditions.checkNotNull(accessToken); - - boolean applied = session.execute(insertStatement.bind() - .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken()) - .setString(CassandraAccessTokenTable.USERNAME, username) - .setInt(TTL, durationInSeconds)) - .one() - .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED); - - if (!applied) { - throw new AccessTokenAlreadyStored(accessToken); - } - } - - @Override - public void removeToken(AccessToken accessToken) { - Preconditions.checkNotNull(accessToken); - - session.execute(removeStatement.bind() - .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())); - } - - @Override - public String getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken { - Preconditions.checkNotNull(accessToken); - - return Optional.ofNullable( - session.execute( - selectStatement.bind() - .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())) - .one()) - .map(row -> row.getString(CassandraAccessTokenTable.USERNAME)) - .orElseThrow(() -> new InvalidAccessToken(accessToken)); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java b/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java deleted file mode 100644 index 482e4ef..0000000 --- a/server/data/data-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.cassandra.access.table; - -public interface CassandraAccessTokenTable { - - String TABLE_NAME = "access_token"; - - String TOKEN = "access_token"; - String USERNAME = "username"; - -} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java deleted file mode 100644 index 355e45d..0000000 --- a/server/data/data-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.cassandra.access; - -import org.apache.james.backends.cassandra.CassandraCluster; -import org.apache.james.jmap.api.access.AbstractAccessTokenRepositoryTest; -import org.apache.james.jmap.api.access.AccessTokenRepository; -import org.junit.After; - -public class CassandraAccessTokenRepositoryTest extends AbstractAccessTokenRepositoryTest { - - private CassandraCluster cassandra; - - @Override - protected AccessTokenRepository createAccessTokenRepository() { - cassandra = CassandraCluster.create(new CassandraAccessModule()); - return new CassandraAccessTokenRepository(cassandra.getConf(), TTL_IN_MS); - } - - @After - public void tearDown() { - cassandra.clearAllTables(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-jmap-cassandra/pom.xml ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/pom.xml b/server/data/data-jmap-cassandra/pom.xml new file mode 100644 index 0000000..10cae1a --- /dev/null +++ b/server/data/data-jmap-cassandra/pom.xml @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <parent> + <artifactId>james-server</artifactId> + <groupId>org.apache.james</groupId> + <version>3.0.0-beta5-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + + <artifactId>james-server-data-jmap-cassandra</artifactId> + <packaging>jar</packaging> + + <name>Apache James :: Server :: Data :: JMAP :: Cassandra persistance</name> + + <profiles> + <profile> + <id>noTest</id> + <activation> + <os> + <family>windows</family> + </os> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>disable-build-for-older-jdk</id> + <activation> + <jdk>(,1.8)</jdk> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <id>default-jar</id> + <phase>none</phase> + </execution> + <execution> + <id>jar</id> + <phase>none</phase> + </execution> + <execution> + <id>test-jar</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <executions> + <execution> + <id>default-compile</id> + <phase>none</phase> + </execution> + <execution> + <id>default-testCompile</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <executions> + <execution> + <id>default-test</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>attach-sources</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-install-plugin</artifactId> + <executions> + <execution> + <id>default-install</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>default-resources</id> + <phase>none</phase> + </execution> + <execution> + <id>default-testResources</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-site-plugin</artifactId> + <executions> + <execution> + <id>attach-descriptor</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>build-for-jdk-8</id> + <activation> + <jdk>[1.8,)</jdk> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>fully.qualified.MainClass</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>apache-james-backends-cassandra</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>apache-james-backends-cassandra</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-data-jmap</artifactId> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-data-jmap</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>${assertj-3.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.cassandraunit</groupId> + <artifactId>cassandra-unit</artifactId> + <version>${cassandra-unit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <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> + <id>disable-animal-sniffer</id> + <activation> + <jdk>[1.6,)</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>animal-sniffer-maven-plugin</artifactId> + <executions> + <execution> + <id>check_java_6</id> + <phase>none</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java new file mode 100644 index 0000000..8125ef2 --- /dev/null +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessModule.java @@ -0,0 +1,67 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.cassandra.access; + +import static com.datastax.driver.core.DataType.text; +import static com.datastax.driver.core.DataType.uuid; + +import java.util.List; + +import org.apache.james.backends.cassandra.components.CassandraIndex; +import org.apache.james.backends.cassandra.components.CassandraModule; +import org.apache.james.backends.cassandra.components.CassandraTable; +import org.apache.james.backends.cassandra.components.CassandraType; +import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; + +import com.datastax.driver.core.schemabuilder.SchemaBuilder; +import com.google.common.collect.ImmutableList; + +public class CassandraAccessModule implements CassandraModule { + + private final List<CassandraTable> tables; + private final List<CassandraIndex> index; + private final List<CassandraType> types; + + public CassandraAccessModule() { + tables = ImmutableList.of( + new CassandraTable(CassandraAccessTokenTable.TABLE_NAME, + SchemaBuilder.createTable(CassandraAccessTokenTable.TABLE_NAME) + .ifNotExists() + .addPartitionKey(CassandraAccessTokenTable.TOKEN, uuid()) + .addColumn(CassandraAccessTokenTable.USERNAME, text()))); + index = ImmutableList.of(); + types = ImmutableList.of(); + } + + @Override + public List<CassandraTable> moduleTables() { + return tables; + } + + @Override + public List<CassandraIndex> moduleIndex() { + return index; + } + + @Override + public List<CassandraType> moduleTypes() { + return types; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java new file mode 100644 index 0000000..9683503 --- /dev/null +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepository.java @@ -0,0 +1,113 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.cassandra.access; + +import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker; +import static com.datastax.driver.core.querybuilder.QueryBuilder.delete; +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +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 java.util.Optional; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.james.backends.cassandra.utils.CassandraConstants; +import org.apache.james.jmap.cassandra.access.table.CassandraAccessTokenTable; +import org.apache.james.jmap.api.access.AccessToken; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.apache.james.jmap.api.access.exceptions.AccessTokenAlreadyStored; +import org.apache.james.jmap.api.access.exceptions.InvalidAccessToken; + +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.Session; +import com.google.common.base.Preconditions; + +public class CassandraAccessTokenRepository implements AccessTokenRepository { + + private static final String TTL = "ttl"; + + private final Session session; + private final PreparedStatement removeStatement; + private final PreparedStatement insertStatement; + private final PreparedStatement selectStatement; + private final int durationInSeconds; + + @Inject + public CassandraAccessTokenRepository(Session session, @Named(TOKEN_EXPIRATION_IN_MS) long durationInMilliseconds) { + this.session = session; + this.durationInSeconds = (int) (durationInMilliseconds / 1000); + + this.removeStatement = this.session.prepare(delete() + .from(CassandraAccessTokenTable.TABLE_NAME) + .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); + + this.insertStatement = this.session.prepare(insertInto(CassandraAccessTokenTable.TABLE_NAME) + .ifNotExists() + .value(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)) + .value(CassandraAccessTokenTable.USERNAME, bindMarker(CassandraAccessTokenTable.USERNAME)) + .using(ttl(bindMarker(TTL)))); + + this.selectStatement = this.session.prepare(select() + .from(CassandraAccessTokenTable.TABLE_NAME) + .where(eq(CassandraAccessTokenTable.TOKEN, bindMarker(CassandraAccessTokenTable.TOKEN)))); + } + + @Override + public void addToken(String username, AccessToken accessToken) throws AccessTokenAlreadyStored { + Preconditions.checkNotNull(username); + Preconditions.checkArgument(! username.isEmpty(), "Username should not be empty"); + Preconditions.checkNotNull(accessToken); + + boolean applied = session.execute(insertStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken()) + .setString(CassandraAccessTokenTable.USERNAME, username) + .setInt(TTL, durationInSeconds)) + .one() + .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED); + + if (!applied) { + throw new AccessTokenAlreadyStored(accessToken); + } + } + + @Override + public void removeToken(AccessToken accessToken) { + Preconditions.checkNotNull(accessToken); + + session.execute(removeStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())); + } + + @Override + public String getUsernameFromToken(AccessToken accessToken) throws InvalidAccessToken { + Preconditions.checkNotNull(accessToken); + + return Optional.ofNullable( + session.execute( + selectStatement.bind() + .setUUID(CassandraAccessTokenTable.TOKEN, accessToken.getToken())) + .one()) + .map(row -> row.getString(CassandraAccessTokenTable.USERNAME)) + .orElseThrow(() -> new InvalidAccessToken(accessToken)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java new file mode 100644 index 0000000..482e4ef --- /dev/null +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/access/table/CassandraAccessTokenTable.java @@ -0,0 +1,29 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.cassandra.access.table; + +public interface CassandraAccessTokenTable { + + String TABLE_NAME = "access_token"; + + String TOKEN = "access_token"; + String USERNAME = "username"; + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java new file mode 100644 index 0000000..355e45d --- /dev/null +++ b/server/data/data-jmap-cassandra/src/test/java/org/apache/james/jmap/cassandra/access/CassandraAccessTokenRepositoryTest.java @@ -0,0 +1,41 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.cassandra.access; + +import org.apache.james.backends.cassandra.CassandraCluster; +import org.apache.james.jmap.api.access.AbstractAccessTokenRepositoryTest; +import org.apache.james.jmap.api.access.AccessTokenRepository; +import org.junit.After; + +public class CassandraAccessTokenRepositoryTest extends AbstractAccessTokenRepositoryTest { + + private CassandraCluster cassandra; + + @Override + protected AccessTokenRepository createAccessTokenRepository() { + cassandra = CassandraCluster.create(new CassandraAccessModule()); + return new CassandraAccessTokenRepository(cassandra.getConf(), TTL_IN_MS); + } + + @After + public void tearDown() { + cassandra.clearAllTables(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/86ba885e/server/pom.xml ---------------------------------------------------------------------- diff --git a/server/pom.xml b/server/pom.xml index 074b93b..47399c4 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -84,6 +84,7 @@ <module>data/data-jcr</module> <module>data/data-jdbc</module> <module>data/data-jmap</module> + <module>data/data-jmap-cassandra</module> <module>data/data-file</module> <module>data/data-ldap</module> <module>data/data-hbase</module> @@ -544,6 +545,11 @@ </dependency> <dependency> <groupId>org.apache.james</groupId> + <artifactId>james-server-data-jmap-cassandra</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> <artifactId>james-server-data-jcr</artifactId> <version>${project.version}</version> </dependency> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
