You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/06/14 08:35:24 UTC

[06/13] james-project git commit: JAMES-2418 Provide MailRepositoryUrlStore cassandra implementation

JAMES-2418 Provide MailRepositoryUrlStore cassandra implementation


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c2dadb27
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c2dadb27
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c2dadb27

Branch: refs/heads/master
Commit: c2dadb276225a1f8d3e5948b48b052a2cad78bcb
Parents: 435a327
Author: benwa <bt...@linagora.com>
Authored: Fri Jun 8 11:54:48 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Jun 14 15:16:59 2018 +0700

----------------------------------------------------------------------
 .../backends/cassandra/CassandraCluster.java    |  5 +
 server/data/data-cassandra/pom.xml              | 26 +++++-
 .../CassandraMailRepositoryUrlModule.java       | 61 ++++++++++++
 .../CassandraMailRepositoryUrlStore.java        | 58 ++++++++++++
 .../james/mailrepository/cassandra/UrlsDao.java | 98 ++++++++++++++++++++
 .../mailrepository/cassandra/UrlsTable.java     | 26 ++++++
 ...assandraMailRepositoryUrlStoreExtension.java | 66 +++++++++++++
 .../CassandraMailRepositoryUrlStoreTest.java    | 28 ++++++
 8 files changed, 363 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
index 19ab763..f03ae27 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/CassandraCluster.java
@@ -33,6 +33,7 @@ import org.apache.james.backends.cassandra.init.ClusterBuilder;
 import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory;
 import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory;
 import org.apache.james.backends.cassandra.utils.FunctionRunnerWithRetry;
+import org.apache.james.util.Host;
 
 import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.Session;
@@ -55,6 +56,10 @@ public final class CassandraCluster implements AutoCloseable {
     public static CassandraCluster create(CassandraModule module, String host, int port) {
         return new CassandraCluster(module, host, port);
     }
+
+    public static CassandraCluster create(CassandraModule module, Host host) {
+        return new CassandraCluster(module, host.getHostName(), host.getPort());
+    }
     
     @Inject
     private CassandraCluster(CassandraModule module, @Named("cassandraHost") String host, @Named("cassandraPort") int port) throws RuntimeException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/pom.xml b/server/data/data-cassandra/pom.xml
index fcf3065..5e86b05 100644
--- a/server/data/data-cassandra/pom.xml
+++ b/server/data/data-cassandra/pom.xml
@@ -47,6 +47,12 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-data-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-library</artifactId>
         </dependency>
         <dependency>
@@ -97,11 +103,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>nl.jqno.equalsverifier</groupId>
             <artifactId>equalsverifier</artifactId>
             <scope>test</scope>
@@ -112,6 +113,21 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.vintage</groupId>
+            <artifactId>junit-vintage-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlModule.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlModule.java b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlModule.java
new file mode 100644
index 0000000..6caf5e1
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlModule.java
@@ -0,0 +1,61 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+import static com.datastax.driver.core.DataType.text;
+
+import java.util.List;
+
+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.backends.cassandra.utils.CassandraConstants;
+
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.google.common.collect.ImmutableList;
+
+public class CassandraMailRepositoryUrlModule implements CassandraModule {
+
+    private final List<CassandraTable> tables;
+    private final List<CassandraType> types;
+
+    public CassandraMailRepositoryUrlModule() {
+        tables = ImmutableList.of(
+            new CassandraTable(UrlsTable.TABLE_NAME,
+                SchemaBuilder.createTable(UrlsTable.TABLE_NAME)
+                    .ifNotExists()
+                    .addPartitionKey(UrlsTable.URL, text())
+                    .withOptions()
+                    .comment("Holds the list of available mail repository")
+                    .caching(SchemaBuilder.KeyCaching.ALL,
+                        SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))));
+        types = ImmutableList.of();
+    }
+
+    @Override
+    public List<CassandraTable> moduleTables() {
+        return tables;
+    }
+
+    @Override
+    public List<CassandraType> moduleTypes() {
+        return types;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStore.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStore.java b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStore.java
new file mode 100644
index 0000000..65296fc
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStore.java
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
+
+import com.github.steveash.guavate.Guavate;
+
+public class CassandraMailRepositoryUrlStore implements MailRepositoryUrlStore {
+
+    private final UrlsDao urlsDao;
+
+    @Inject
+    public CassandraMailRepositoryUrlStore(UrlsDao urlsDao) {
+        this.urlsDao = urlsDao;
+    }
+
+    @Override
+    public void add(MailRepositoryUrl url) {
+        urlsDao.addUrl(url).join();
+    }
+
+    @Override
+    public Set<MailRepositoryUrl> list() {
+        return urlsDao.retrieveUsedUrls()
+            .join()
+            .collect(Guavate.toImmutableSet());
+    }
+
+    @Override
+    public boolean contains(MailRepositoryUrl url) {
+        return urlsDao.retrieve(url)
+            .join()
+            .isPresent();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsDao.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsDao.java b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsDao.java
new file mode 100644
index 0000000..0a05b6e
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsDao.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+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 org.apache.james.mailrepository.cassandra.UrlsTable.TABLE_NAME;
+import static org.apache.james.mailrepository.cassandra.UrlsTable.URL;
+
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+
+public class UrlsDao {
+    private final CassandraAsyncExecutor executor;
+    private final PreparedStatement insert;
+    private final PreparedStatement selectAll;
+    private final PreparedStatement select;
+    private final CassandraUtils cassandraUtils;
+
+    @Inject
+    public UrlsDao(Session session, CassandraUtils cassandraUtils) {
+        this.executor = new CassandraAsyncExecutor(session);
+        this.cassandraUtils = cassandraUtils;
+
+        this.insert = prepareInsert(session);
+        this.selectAll = prepareSelectAll(session);
+        this.select = prepareSelect(session);
+    }
+
+    private PreparedStatement prepareSelect(Session session) {
+        return session.prepare(select(URL)
+            .from(TABLE_NAME)
+            .where(eq(URL, bindMarker(URL))));
+    }
+
+    private PreparedStatement prepareSelectAll(Session session) {
+        return session.prepare(select(URL)
+            .from(TABLE_NAME));
+    }
+
+    private PreparedStatement prepareInsert(Session session) {
+        return session.prepare(insertInto(TABLE_NAME)
+            .value(URL, bindMarker(URL)));
+    }
+
+    public CompletableFuture<Void> addUrl(MailRepositoryUrl url) {
+        return executor.executeVoid(
+            insert.bind()
+                .setString(URL, url.asString()));
+    }
+
+    public CompletableFuture<Optional<MailRepositoryUrl>> retrieve(MailRepositoryUrl url) {
+        return executor.executeSingleRow(
+            select.bind()
+                .setString(URL, url.asString()))
+            .thenApply(optional -> optional.map(this::toUrl));
+    }
+
+    public CompletableFuture<Stream<MailRepositoryUrl>> retrieveUsedUrls() {
+        return executor.execute(selectAll.bind())
+            .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
+                .map(this::toUrl));
+    }
+
+    private MailRepositoryUrl toUrl(Row row) {
+        return MailRepositoryUrl.from(row.getString(URL));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsTable.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsTable.java b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsTable.java
new file mode 100644
index 0000000..7a2eaa8
--- /dev/null
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/mailrepository/cassandra/UrlsTable.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+public interface UrlsTable {
+    String TABLE_NAME = "mailRepositoryUrls";
+
+    String URL = "url";
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreExtension.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreExtension.java b/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreExtension.java
new file mode 100644
index 0000000..2dec108
--- /dev/null
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreExtension.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class CassandraMailRepositoryUrlStoreExtension implements ParameterResolver, BeforeAllCallback, AfterAllCallback {
+    private final DockerCassandraRule cassandra;
+
+    public CassandraMailRepositoryUrlStoreExtension() {
+        this.cassandra = new DockerCassandraRule();
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext context) {
+        cassandra.start();
+    }
+
+    @Override
+    public void afterAll(ExtensionContext context) {
+        cassandra.stop();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return (parameterContext.getParameter().getType() == MailRepositoryUrlStore.class);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        CassandraCluster cassandraCluster = CassandraCluster.create(
+            new CassandraMailRepositoryUrlModule(),
+            cassandra.getHost());
+
+        return new CassandraMailRepositoryUrlStore(
+            new UrlsDao(
+                cassandraCluster.getConf(),
+                CassandraUtils.WITH_DEFAULT_CONFIGURATION));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c2dadb27/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreTest.java
----------------------------------------------------------------------
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreTest.java
new file mode 100644
index 0000000..92a8a37
--- /dev/null
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/mailrepository/cassandra/CassandraMailRepositoryUrlStoreTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.mailrepository.cassandra;
+
+import org.apache.james.mailrepository.api.MailRepositoryUrlStoreContract;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraMailRepositoryUrlStoreExtension.class)
+public class CassandraMailRepositoryUrlStoreTest implements MailRepositoryUrlStoreContract {
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org