Repository: james-project Updated Branches: refs/heads/master 69818cf75 -> 1968a528f
JAMES-2525 Initial implementation of ObjectStorageBlobsDAO This implementation could theoretically work with any provider but the configuration and retrieval of the blobstore API is currently hard coded on swift with tempAuthCredentials. This will be improved in further pull requests. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ca8e29fc Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ca8e29fc Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ca8e29fc Branch: refs/heads/master Commit: ca8e29fc8b8b0c69f1f6a7d8fc44cd814c06e76b Parents: 2dec9cf Author: Jean Helou <[email protected]> Authored: Thu Aug 23 18:03:00 2018 +0200 Committer: Jean Helou <[email protected]> Committed: Wed Aug 29 15:41:52 2018 +0200 ---------------------------------------------------------------------- .../java/org/apache/james/blob/api/BlobId.java | 6 + server/blob/blob-cloud/pom.xml | 99 -------------- .../james/blob/objectstorage/ContainerName.java | 63 +++++++++ .../james/blob/objectstorage/Credentials.java | 63 +++++++++ .../james/blob/objectstorage/HeaderName.java | 59 +++++++++ .../james/blob/objectstorage/Identity.java | 63 +++++++++ .../objectstorage/ObjectStorageBlobsDAO.java | 128 ++++++++++++++++++ .../ObjectStorageConfiguration.java | 132 +++++++++++++++++++ .../blob/objectstorage/PassHeaderName.java | 30 +++++ .../apache/james/blob/objectstorage/Region.java | 63 +++++++++ .../blob/objectstorage/UserHeaderName.java | 30 +++++ .../blob/objectstorage/ContainerNameTest.java | 31 +++++ .../blob/objectstorage/CredentialsTest.java | 31 +++++ .../DockerSwiftTempAuthExtension.java | 73 ++++++++++ .../blob/objectstorage/HeaderNameTest.java | 31 +++++ .../james/blob/objectstorage/IdentityTest.java | 31 +++++ .../ObjectStorageBlobsDAOTest.java | 90 +++++++++++++ .../ObjectStorageConfigurationTest.java | 72 ++++++++++ .../james/blob/objectstorage/RegionTest.java | 31 +++++ .../src/test/resources/logback-test.xml | 39 ++++++ server/blob/blob-objectstore/pom.xml | 99 -------------- 21 files changed, 1066 insertions(+), 198 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobId.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobId.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobId.java index dbfd204..a6f6229 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobId.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobId.java @@ -19,12 +19,18 @@ package org.apache.james.blob.api; +import java.util.UUID; + public interface BlobId { interface Factory { BlobId forPayload(byte[] payload); BlobId from(String id); + + default BlobId randomId() { + return from(UUID.randomUUID().toString()); + } } String asString(); http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-cloud/pom.xml ---------------------------------------------------------------------- diff --git a/server/blob/blob-cloud/pom.xml b/server/blob/blob-cloud/pom.xml deleted file mode 100644 index 6780076..0000000 --- a/server/blob/blob-cloud/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?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/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <artifactId>james-server-blob</artifactId> - <groupId>org.apache.james</groupId> - <version>3.2.0-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>blob-objectstorage</artifactId> - <packaging>jar</packaging> - - <name>Apache James :: Server :: Blob :: Objet storage</name> - - <properties> - <jcloud.version>2.1.1</jcloud.version> - </properties> - - <dependencies> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>blob-api</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>blob-api</artifactId> - <type>test-jar</type> - <scope>test</scope> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - <dependency> - <groupId>nl.jqno.equalsverifier</groupId> - <artifactId>equalsverifier</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.jclouds.api</groupId> - <artifactId>openstack-swift</artifactId> - <version>${jcloud.version}</version> - </dependency> - <dependency> - <groupId>org.apache.jclouds.driver</groupId> - <artifactId>jclouds-slf4j</artifactId> - <version>${jcloud.version}</version> - </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <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.testcontainers</groupId> - <artifactId>testcontainers</artifactId> - </dependency> - </dependencies> - -</project> http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ContainerName.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ContainerName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ContainerName.java new file mode 100644 index 0000000..5c3c05d --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ContainerName.java @@ -0,0 +1,63 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +public final class ContainerName { + public static ContainerName of(String value) { + return new ContainerName(value); + } + + private final String container; + + private ContainerName(String value) { + this.container = value; + } + + public String value() { + return container; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ContainerName that = (ContainerName) o; + return Objects.equal(container, that.container); + } + + @Override + public int hashCode() { + return Objects.hashCode(container); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("container", container) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Credentials.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Credentials.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Credentials.java new file mode 100644 index 0000000..7719894 --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Credentials.java @@ -0,0 +1,63 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +public final class Credentials { + public static Credentials of(String value) { + return new Credentials(value); + } + + private final String credentials; + + private Credentials(String value) { + this.credentials = value; + } + + public String value() { + return credentials; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Credentials that = (Credentials) o; + return Objects.equal(credentials, that.credentials); + } + + @Override + public int hashCode() { + return Objects.hashCode(credentials); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("credentials", credentials) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/HeaderName.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/HeaderName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/HeaderName.java new file mode 100644 index 0000000..79ec77e --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/HeaderName.java @@ -0,0 +1,59 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +public class HeaderName { + private final String value; + + protected HeaderName(String value) { + this.value = value; + } + + public String value() { + return value; + } + + @Override + public final boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof HeaderName)) { + return false; + } + HeaderName that = (HeaderName) o; + return Objects.equal(value, that.value); + } + + @Override + public final int hashCode() { + return Objects.hashCode(value); + } + + @Override + public final String toString() { + return MoreObjects.toStringHelper(this) + .add("value", value) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Identity.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Identity.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Identity.java new file mode 100644 index 0000000..094ba30 --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Identity.java @@ -0,0 +1,63 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +public final class Identity { + public static Identity of(String value) { + return new Identity(value); + } + + private final String identity; + + private Identity(String value) { + this.identity = value; + } + + public String value() { + return identity; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Identity identity1 = (Identity) o; + return Objects.equal(identity, identity1.identity); + } + + @Override + public int hashCode() { + return Objects.hashCode(identity); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("identity", identity) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java new file mode 100644 index 0000000..0afbbaf --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAO.java @@ -0,0 +1,128 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.CompletableFuture; + +import org.apache.commons.io.IOUtils; +import org.apache.james.blob.api.BlobId; +import org.apache.james.blob.api.BlobStore; +import org.apache.james.blob.api.HashBlobId; +import org.apache.james.blob.api.ObjectStoreException; +import org.jclouds.ContextBuilder; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.options.CopyOptions; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; +import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext; + +import com.github.fge.lambdas.Throwing; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.google.common.hash.Hashing; +import com.google.common.hash.HashingInputStream; +import com.google.inject.Inject; +import com.google.inject.Module; + +class ObjectStorageBlobsDAO implements BlobStore { + private static final InputStream EMPTY_STREAM = new ByteArrayInputStream(new byte[0]); + private static final Iterable<Module> JCLOUDS_MODULES = ImmutableSet.of(new SLF4JLoggingModule()); + + private final BlobId.Factory blobIdFactory; + private final org.jclouds.blobstore.BlobStore blobStore; + private final ContainerName containerName; + + @Inject + public ObjectStorageBlobsDAO(ContainerName containerName, HashBlobId.Factory blobIdFactory, + ObjectStorageConfiguration objectStorageConfiguration) { + this.blobIdFactory = blobIdFactory; + this.containerName = containerName; + + RegionScopedBlobStoreContext blobStoreContext = ContextBuilder.newBuilder("openstack-swift") + .endpoint(objectStorageConfiguration.getEndpoint().toString()) + .credentials( + objectStorageConfiguration.getIdentity().value(), + objectStorageConfiguration.getCredentials().value()) + .overrides(objectStorageConfiguration.getOverrides()) + .modules(JCLOUDS_MODULES) + .buildView(RegionScopedBlobStoreContext.class); + + blobStore = objectStorageConfiguration + .getRegion() + .map(region -> blobStoreContext.getBlobStore(region.value())) + .orElse(blobStoreContext.getBlobStore()); + } + + @Override + public CompletableFuture<BlobId> save(byte[] data) { + return save(new ByteArrayInputStream(data)); + } + + @Override + public CompletableFuture<BlobId> save(InputStream data) { + Preconditions.checkNotNull(data); + + BlobId tmpId = blobIdFactory.randomId(); + BlobId id = save(data, tmpId); + updateBlobId(tmpId, id); + + return CompletableFuture.completedFuture(id); + } + + private void updateBlobId(BlobId from, BlobId to) { + String containerName = this.containerName.value(); + blobStore.copyBlob(containerName, from.asString(), containerName, to.asString(), CopyOptions.NONE); + blobStore.removeBlob(containerName, from.asString()); + } + + private BlobId save(InputStream data, BlobId id) { + String containerName = this.containerName.value(); + HashingInputStream hashingInputStream = new HashingInputStream(Hashing.sha256(), data); + Blob blob = blobStore.blobBuilder(id.asString()).payload(hashingInputStream).build(); + blobStore.putBlob(containerName, blob); + return blobIdFactory.from(hashingInputStream.hash().toString()); + } + + @Override + public CompletableFuture<byte[]> readBytes(BlobId blobId) { + return CompletableFuture + .supplyAsync(Throwing.supplier(() -> IOUtils.toByteArray(read(blobId))).sneakyThrow()); + } + + @Override + public InputStream read(BlobId blobId) throws ObjectStoreException { + Blob blob = blobStore.getBlob(containerName.value(), blobId.asString()); + + try { + if (blob != null) { + return blob.getPayload().openStream(); + } else { + return EMPTY_STREAM; + } + } catch (IOException cause) { + throw new ObjectStoreException( + "Failed to read blob " + blobId.asString(), + cause); + } + + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageConfiguration.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageConfiguration.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageConfiguration.java new file mode 100644 index 0000000..67be702 --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/ObjectStorageConfiguration.java @@ -0,0 +1,132 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import java.net.URI; +import java.util.Optional; +import java.util.Properties; + +import org.jclouds.openstack.keystone.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.reference.TempAuthHeaders; + +import com.google.common.base.Preconditions; + +public class ObjectStorageConfiguration { + public static class Builder { + private URI endpoint; + private Identity identity; + private Credentials credentials; + private Optional<Region> region; + private Optional<UserHeaderName> userHeaderName; + private Optional<PassHeaderName> passHeaderName; + + public Builder() { + region = Optional.empty(); + userHeaderName = Optional.empty(); + passHeaderName = Optional.empty(); + } + + public ObjectStorageConfiguration.Builder endpoint(URI endpoint) { + this.endpoint = endpoint; + return this; + } + + public ObjectStorageConfiguration.Builder identity(Identity identity) { + this.identity = identity; + return this; + } + + public ObjectStorageConfiguration.Builder credentials(Credentials credentials) { + this.credentials = credentials; + return this; + } + + public ObjectStorageConfiguration.Builder region(Region region) { + this.region = Optional.of(region); + return this; + } + + public ObjectStorageConfiguration.Builder tempAuthHeaderUserName(UserHeaderName tmpAuthHeaderUser) { + userHeaderName = Optional.of(tmpAuthHeaderUser); + return this; + } + + public ObjectStorageConfiguration.Builder tempAuthHeaderPassName(PassHeaderName tmpAuthHeaderPass) { + passHeaderName = Optional.of(tmpAuthHeaderPass); + return this; + } + + public ObjectStorageConfiguration build() { + Preconditions.checkState(endpoint != null); + Preconditions.checkState(identity != null); + Preconditions.checkState(credentials != null); + return new ObjectStorageConfiguration(endpoint, identity, credentials, region, userHeaderName, passHeaderName); + } + } + + private final URI endpoint; + private final Optional<Region> region; + private final Identity identity; + private final Credentials credentials; + private final Optional<UserHeaderName> userHeaderName; + private final Optional<PassHeaderName> passHeaderName; + + private ObjectStorageConfiguration(URI endpoint, + Identity identity, + Credentials credentials, + Optional<Region> region, + Optional<UserHeaderName> userHeaderName, + Optional<PassHeaderName> passHeaderName) { + this.endpoint = endpoint; + this.region = region; + this.userHeaderName = userHeaderName; + this.passHeaderName = passHeaderName; + this.identity = identity; + this.credentials = credentials; + } + + public URI getEndpoint() { + return endpoint; + } + + public Identity getIdentity() { + return identity; + } + + public Credentials getCredentials() { + return credentials; + } + + public Properties getOverrides() { + Properties properties = new Properties(); + properties.setProperty(KeystoneProperties.CREDENTIAL_TYPE, "tempAuthCredentials"); + userHeaderName.ifPresent(tmpAuthHeaderUser -> + properties.setProperty(TempAuthHeaders.TEMP_AUTH_HEADER_USER, tmpAuthHeaderUser.value()) + ); + passHeaderName.ifPresent(tmpAuthHeaderPass -> + properties.setProperty(TempAuthHeaders.TEMP_AUTH_HEADER_PASS, tmpAuthHeaderPass.value()) + ); + return properties; + } + + public Optional<Region> getRegion() { + return region; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PassHeaderName.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PassHeaderName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PassHeaderName.java new file mode 100644 index 0000000..6299c9c --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PassHeaderName.java @@ -0,0 +1,30 @@ +/**************************************************************** + * 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.blob.objectstorage; + +public final class PassHeaderName extends HeaderName { + public static PassHeaderName of(String value) { + return new PassHeaderName(value); + } + + private PassHeaderName(String value) { + super(value); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Region.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Region.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Region.java new file mode 100644 index 0000000..638de2a --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/Region.java @@ -0,0 +1,63 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +public final class Region { + public static Region of(String value) { + return new Region(value); + } + + private final String region; + + private Region(String value) { + this.region = value; + } + + public String value() { + return region; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Region region1 = (Region) o; + return Objects.equal(region, region1.region); + } + + @Override + public int hashCode() { + return Objects.hashCode(region); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("region", region) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/UserHeaderName.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/UserHeaderName.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/UserHeaderName.java new file mode 100644 index 0000000..5c9bf8a --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/UserHeaderName.java @@ -0,0 +1,30 @@ +/**************************************************************** + * 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.blob.objectstorage; + +public final class UserHeaderName extends HeaderName { + public static UserHeaderName of(String value) { + return new UserHeaderName(value); + } + + private UserHeaderName(String value) { + super(value); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ContainerNameTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ContainerNameTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ContainerNameTest.java new file mode 100644 index 0000000..2043537 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ContainerNameTest.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class ContainerNameTest { + @Test + public void credentialsShouldRespectBeanContract() { + EqualsVerifier.forClass(ContainerName.class).verify(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/CredentialsTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/CredentialsTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/CredentialsTest.java new file mode 100644 index 0000000..1177167 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/CredentialsTest.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class CredentialsTest { + @Test + public void credentialsShouldRespectBeanContract() { + EqualsVerifier.forClass(Credentials.class).verify(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftTempAuthExtension.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftTempAuthExtension.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftTempAuthExtension.java new file mode 100644 index 0000000..9bc31ee --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftTempAuthExtension.java @@ -0,0 +1,73 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import java.net.URI; + +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; +import org.testcontainers.containers.GenericContainer; + +class DockerSwiftTempAuthExtension implements ParameterResolver, BeforeAllCallback, AfterAllCallback { + public static final int SWIFT_PORT = 8080; + private static GenericContainer swiftContainer = + new GenericContainer("bouncestorage/swift-aio:ea10837d") + .withExposedPorts(SWIFT_PORT); + private DockerSwift dockerSwift; + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + swiftContainer.start(); + String host = swiftContainer.getContainerIpAddress(); + Integer port = swiftContainer.getMappedPort(SWIFT_PORT); + dockerSwift = new DockerSwift(new URI("http", null, host, port, "/auth/v1.0", null, null)); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + swiftContainer.stop(); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return (parameterContext.getParameter().getType() == DockerSwift.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return dockerSwift; + } + + public static class DockerSwift { + private final URI endpoint; + + public DockerSwift(URI endpoint) { + this.endpoint = endpoint; + } + + public URI getEndpoint() { + return endpoint; + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/HeaderNameTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/HeaderNameTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/HeaderNameTest.java new file mode 100644 index 0000000..9077927 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/HeaderNameTest.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class HeaderNameTest { + @Test + public void credentialsShouldRespectBeanContract() { + EqualsVerifier.forClass(HeaderName.class).verify(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/IdentityTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/IdentityTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/IdentityTest.java new file mode 100644 index 0000000..0910bff --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/IdentityTest.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class IdentityTest { + @Test + public void credentialsShouldRespectBeanContract() { + EqualsVerifier.forClass(Identity.class).verify(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java new file mode 100644 index 0000000..8611946 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOTest.java @@ -0,0 +1,90 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import java.net.URI; +import java.util.Properties; +import java.util.UUID; + +import org.apache.james.blob.api.BlobId; +import org.apache.james.blob.api.HashBlobId; +import org.apache.james.blob.api.BlobStore; +import org.apache.james.blob.api.BlobStoreContract; +import org.jclouds.ContextBuilder; +import org.jclouds.blobstore.BlobStoreContext; +import org.jclouds.openstack.keystone.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.reference.TempAuthHeaders; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(DockerSwiftTempAuthExtension.class) +public class ObjectStorageBlobsDAOTest implements BlobStoreContract { + private static final String TENANT_NAME = "test"; + private static final String USER_NAME = "tester"; + private static final Credentials PASSWORD = Credentials.of("testing"); + private static final Identity IDENTITY = Identity.of(TENANT_NAME + ":" + USER_NAME); + + private URI swiftEndpoint; + private ContainerName containerName; + private org.jclouds.blobstore.BlobStore blobStore; + + @BeforeEach + void setUp(DockerSwiftTempAuthExtension.DockerSwift dockerSwift) throws Exception { + final Properties overrides = new Properties(); + overrides.setProperty(KeystoneProperties.CREDENTIAL_TYPE, "tempAuthCredentials"); + overrides.setProperty(TempAuthHeaders.TEMP_AUTH_HEADER_USER, "X-Storage-User"); + overrides.setProperty(TempAuthHeaders.TEMP_AUTH_HEADER_PASS, "X-Storage-Pass"); + swiftEndpoint = dockerSwift.getEndpoint(); + BlobStoreContext blobStoreContext = ContextBuilder.newBuilder("openstack-swift") + .endpoint(swiftEndpoint.toString()) + .credentials(IDENTITY.value(), PASSWORD.value()) + .overrides(overrides) + .buildView(BlobStoreContext.class); + blobStore = blobStoreContext.getBlobStore(); + containerName = ContainerName.of(UUID.randomUUID().toString()); + blobStore.createContainerInLocation(null, containerName.value()); + } + + @AfterEach + void tearDown() throws Exception { + blobStore.deleteContainer(containerName.value()); + blobStore.getContext().close(); + } + + @Override + public BlobStore testee() { + ObjectStorageConfiguration testConfig = + new ObjectStorageConfiguration.Builder() + .endpoint(swiftEndpoint) + .identity(IDENTITY) + .credentials(PASSWORD) + .tempAuthHeaderUserName(UserHeaderName.of("X-Storage-User")) + .tempAuthHeaderPassName(PassHeaderName.of("X-Storage-Pass")) + .build(); + return new ObjectStorageBlobsDAO(containerName, new HashBlobId.Factory(), testConfig); + } + + @Override + public BlobId.Factory blobIdFactory() { + return new HashBlobId.Factory(); + } +} + http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageConfigurationTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageConfigurationTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageConfigurationTest.java new file mode 100644 index 0000000..7939921 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageConfigurationTest.java @@ -0,0 +1,72 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URI; + +import org.junit.jupiter.api.Test; + +class ObjectStorageConfigurationTest { + + private static URI ENDPOINT = URI.create("http://example.com"); + private static Credentials CREDENTIALS = Credentials.of("fake"); + private static Identity IDENTITY = Identity.of("fake"); + + @Test + void enpointIsMandatoryToBuildConfiguration() throws Exception { + ObjectStorageConfiguration.Builder builder = new ObjectStorageConfiguration.Builder(); + assertThatThrownBy(() -> builder.build()).isInstanceOf(IllegalStateException.class); + } + + @Test + void identityIsMandatoryToBuildConfiguration() throws Exception { + ObjectStorageConfiguration.Builder builder = new ObjectStorageConfiguration.Builder(); + builder + .endpoint(new URI("http", "example.com", null, null)); + assertThatThrownBy(() -> builder.build()).isInstanceOf(IllegalStateException.class); + } + + @Test + void credentialsIsMandatoryToBuildConfiguration() throws Exception { + ObjectStorageConfiguration.Builder builder = new ObjectStorageConfiguration.Builder(); + builder + .endpoint(new URI("http", "example.com", null, null)) + .identity(Identity.of("fake")); + assertThatThrownBy(() -> builder.build()).isInstanceOf(IllegalStateException.class); + } + + @Test + void configurationIsBuiltWhenAllMandatoryParamsAreProvided() throws Exception { + ObjectStorageConfiguration.Builder builder = new ObjectStorageConfiguration.Builder(); + builder + .endpoint(ENDPOINT) + .identity(IDENTITY) + .credentials(CREDENTIALS); + + ObjectStorageConfiguration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/RegionTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/RegionTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/RegionTest.java new file mode 100644 index 0000000..f1f8167 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/RegionTest.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.blob.objectstorage; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class RegionTest { + @Test + public void credentialsShouldRespectBeanContract() { + EqualsVerifier.forClass(Region.class).verify(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstorage/src/test/resources/logback-test.xml ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/resources/logback-test.xml b/server/blob/blob-objectstorage/src/test/resources/logback-test.xml new file mode 100644 index 0000000..b48b76f --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/resources/logback-test.xml @@ -0,0 +1,39 @@ +<?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. ~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> + +<configuration> + <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> + <resetJUL>true</resetJUL> + </contextListener> + + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern> + </encoder> + <immediateFlush>false</immediateFlush> + </appender> + + <root level="ERROR"> + <appender-ref ref="CONSOLE" /> + </root> + + + <logger name="org.apache.james" level="ERROR"/> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ca8e29fc/server/blob/blob-objectstore/pom.xml ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstore/pom.xml b/server/blob/blob-objectstore/pom.xml deleted file mode 100644 index ea88bc3..0000000 --- a/server/blob/blob-objectstore/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?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/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <artifactId>james-server-blob</artifactId> - <groupId>org.apache.james</groupId> - <version>3.2.0-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>blob-objectstorage</artifactId> - <packaging>jar</packaging> - - <name>Apache James :: Server :: Blob :: Object storage</name> - - <properties> - <jclouds.version>2.1.1</jclouds.version> - </properties> - - <dependencies> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>blob-api</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>blob-api</artifactId> - <type>test-jar</type> - <scope>test</scope> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - <dependency> - <groupId>nl.jqno.equalsverifier</groupId> - <artifactId>equalsverifier</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.jclouds.api</groupId> - <artifactId>openstack-swift</artifactId> - <version>${jclouds.version}</version> - </dependency> - <dependency> - <groupId>org.apache.jclouds.driver</groupId> - <artifactId>jclouds-slf4j</artifactId> - <version>${jclouds.version}</version> - </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <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.testcontainers</groupId> - <artifactId>testcontainers</artifactId> - </dependency> - </dependencies> - -</project> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
