JAMES-2525 implements Keystone v3 ObjectStorageBlobsDAOBuilder
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/be1702dd Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/be1702dd Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/be1702dd Branch: refs/heads/master Commit: be1702ddc7d0be43bfbe833cd660d6cb172254ef Parents: 1c47e2f Author: Jean Helou <j...@codamens.fr> Authored: Fri Aug 31 18:09:54 2018 +0200 Committer: Benoit Tellier <btell...@linagora.com> Committed: Fri Oct 5 18:11:43 2018 +0700 ---------------------------------------------------------------------- server/blob/blob-objectstorage/pom.xml | 6 + .../objectstorage/ObjectStorageBlobsDAO.java | 5 + .../swift/SwiftKeystone3ObjectStorage.java | 244 +++++++++++++++++++ .../objectstorage/DockerSwiftExtension.java | 6 +- .../ObjectStorageBlobsDAOContract.java | 12 +- ...ystone2ObjectStorageBlobsDAOBuilderTest.java | 18 +- ...ystone3ObjectStorageBlobsDAOBuilderTest.java | 128 ++++++++++ ...Keystone3ObjectStorageConfigurationTest.java | 161 ++++++++++++ ...empAuthObjectStorageBlobsDAOBuilderTest.java | 23 +- 9 files changed, 572 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/pom.xml ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/pom.xml b/server/blob/blob-objectstorage/pom.xml index 8e4eb44..3b895b5 100644 --- a/server/blob/blob-objectstorage/pom.xml +++ b/server/blob/blob-objectstorage/pom.xml @@ -96,10 +96,16 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <scope>test</scope> </dependency> + </dependencies> </project> http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/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 index 478bb67..176e5a4 100644 --- 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 @@ -29,6 +29,7 @@ import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.ObjectStoreException; import org.apache.james.blob.objectstorage.swift.SwiftKeystone2ObjectStorage; +import org.apache.james.blob.objectstorage.swift.SwiftKeystone3ObjectStorage; import org.apache.james.blob.objectstorage.swift.SwiftTempAuthObjectStorage; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.options.CopyOptions; @@ -62,6 +63,10 @@ public class ObjectStorageBlobsDAO implements BlobStore { return SwiftKeystone2ObjectStorage.daoBuilder(testConfig); } + public static ObjectStorageBlobsDAOBuilder builder(SwiftKeystone3ObjectStorage.Configuration testConfig) { + return SwiftKeystone3ObjectStorage.daoBuilder(testConfig); + } + @Override public CompletableFuture<BlobId> save(byte[] data) { return save(new ByteArrayInputStream(data)); http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java new file mode 100644 index 0000000..e544735 --- /dev/null +++ b/server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorage.java @@ -0,0 +1,244 @@ +/**************************************************************** + * 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.swift; + +import java.net.URI; +import java.util.Optional; +import java.util.Properties; +import java.util.function.Supplier; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder; +import org.apache.james.util.OptionalUtils; +import org.jclouds.ContextBuilder; +import org.jclouds.blobstore.BlobStore; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; +import org.jclouds.openstack.keystone.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +public class SwiftKeystone3ObjectStorage { + private static final Iterable<Module> JCLOUDS_MODULES = + ImmutableSet.of(new SLF4JLoggingModule()); + + public static ObjectStorageBlobsDAOBuilder daoBuilder(Configuration testConfig) { + return new ObjectStorageBlobsDAOBuilder(new BlobStoreBuilder(testConfig)); + } + + public static Configuration.Builder configBuilder() { + return new Configuration.Builder(); + } + + public static class BlobStoreBuilder implements Supplier<BlobStore> { + private final Configuration testConfig; + + private BlobStoreBuilder(Configuration testConfig) { + this.testConfig = testConfig; + } + + @Override + public BlobStore get() { + RegionScopedBlobStoreContext blobStoreContext = contextBuilder() + .endpoint(testConfig.getEndpoint().toString()) + .credentials(testConfig.getIdentity().asString(), testConfig.getCredentials().value()) + .overrides(testConfig.getOverrides()) + .modules(JCLOUDS_MODULES) + .buildView(RegionScopedBlobStoreContext.class); + + return testConfig.getRegion() + .map(Region::value) + .map(blobStoreContext::getBlobStore) + .orElseGet(blobStoreContext::getBlobStore); + } + + private ContextBuilder contextBuilder() { + return ContextBuilder.newBuilder("openstack-swift"); + } + } + + public static final class Configuration { + public static class Builder { + private URI endpoint; + private UserName userName; + private DomainName domainName; + private Credentials credentials; + private Optional<Region> region; + private Optional<Project> project; + private Optional<DomainId> domainId; + + private Builder() { + region = Optional.empty(); + project = Optional.empty(); + domainId = Optional.empty(); + } + + public Builder endpoint(URI endpoint) { + this.endpoint = endpoint; + return this; + } + + public Builder identity(IdentityV3 identity) { + this.domainName = identity.getDomainName(); + this.userName = identity.getUserName(); + return this; + } + + public Builder credentials(Credentials credentials) { + this.credentials = credentials; + return this; + } + + public Builder region(Region region) { + this.region = Optional.of(region); + return this; + } + + public Builder domainId(DomainId domainId) { + this.domainId = Optional.of(domainId); + return this; + } + + public Builder project(Project project) { + this.project = Optional.of(project); + return this; + } + + public Configuration build() { + Preconditions.checkState(endpoint != null); + Preconditions.checkState(domainName != null); + Preconditions.checkState(userName != null); + Preconditions.checkState(credentials != null); + IdentityV3 identity = IdentityV3.of(domainName, userName); + return new Configuration(endpoint, identity, credentials, region, project, domainId); + } + } + + private final URI endpoint; + private final IdentityV3 identity; + private final Optional<Region> region; + private final Credentials credentials; + private final Optional<Project> project; + private final Optional<DomainId> domainId; + + private Configuration(URI endpoint, + IdentityV3 identity, + Credentials credentials, + Optional<Region> region, + Optional<Project> project, + Optional<DomainId> domainId) { + this.endpoint = endpoint; + this.identity = identity; + this.region = region; + this.credentials = credentials; + this.project = project; + this.domainId = domainId; + } + + public URI getEndpoint() { + return endpoint; + } + + public IdentityV3 getIdentity() { + return identity; + } + + public Credentials getCredentials() { + return credentials; + } + + public Properties getOverrides() { + Properties properties = new Properties(); + properties.setProperty(KeystoneProperties.KEYSTONE_VERSION, "3"); + OptionalUtils.or( + project.map(project -> setScope(project)), + domainId.map(domain -> setScope(domain)) + ).ifPresent(scopeProps -> + properties.putAll(scopeProps) + ); + return properties; + } + + private Properties setScope(DomainId domainId) { + Properties properties = new Properties(); + properties.setProperty(KeystoneProperties.SCOPE, domainId.asString()); + return properties; + } + + private Properties setScope(Project project) { + Properties properties = new Properties(); + properties.setProperty(KeystoneProperties.SCOPE, project.name().asString()); + project.domainName() + .map(domain -> Pair.of(KeystoneProperties.PROJECT_DOMAIN_NAME, domain)); + OptionalUtils.or( + project.domainName() + .map(domain -> Pair.of(KeystoneProperties.PROJECT_DOMAIN_NAME, domain.value())), + project.domainId() + .map(domain -> Pair.of(KeystoneProperties.PROJECT_DOMAIN_ID, domain.value())) + ).ifPresent(pair -> + properties.setProperty(pair.getKey(), pair.getValue()) + ); + + return properties; + } + + public Optional<Region> getRegion() { + return region; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Configuration that = (Configuration) o; + return Objects.equal(endpoint, that.endpoint) && + Objects.equal(identity, that.identity) && + Objects.equal(region, that.region) && + Objects.equal(credentials, that.credentials) && + Objects.equal(project, that.project) && + Objects.equal(domainId, that.domainId); + } + + @Override + public int hashCode() { + return Objects.hashCode(endpoint, identity, region, credentials, project, domainId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("endpoint", endpoint) + .add("identity", identity) + .add("region", region) + .add("credentials", credentials) + .add("project", project) + .add("domainId", domainId) + .toString(); + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftExtension.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftExtension.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftExtension.java index 48b2d3a..b30bd44 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftExtension.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/DockerSwiftExtension.java @@ -81,8 +81,10 @@ public class DockerSwiftExtension implements ParameterResolver, BeforeAllCallbac } URI keystoneV2Endpoint = URI.create("http://" + containerIpAddress + ":" + keystonePort + "/v2.0"); - URI keystoneV3Endpoint = URI.create("http://" + containerIpAddress + ":" + keystonePort + "/v3"); - URI swiftEndpoint = URI.create("http://" + containerIpAddress + ":" + swiftPort + "/auth/v1.0"); + URI keystoneV3Endpoint = + URI.create("http://" + containerIpAddress + ":" + keystonePort + "/v3"); + URI swiftEndpoint = + URI.create("http://" + containerIpAddress + ":" + swiftPort + "/auth/v1.0"); dockerSwift = new DockerSwift(keystoneV2Endpoint, keystoneV3Endpoint, swiftEndpoint); } http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOContract.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOContract.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOContract.java index 07da03b..a6cb4b4 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOContract.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobsDAOContract.java @@ -25,25 +25,23 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import org.apache.james.blob.api.BlobId; import org.jclouds.blobstore.BlobStore; import org.jclouds.domain.Location; -import org.junit.jupiter.api.Test; public interface ObjectStorageBlobsDAOContract { - ObjectStorageBlobsDAOBuilder builder(); - Location DEFAULT_LOCATION = null; ContainerName containerName(); - @Test - default void builtBlobsDAOCanStoreAndRetrieve() throws Exception { - ObjectStorageBlobsDAOBuilder builder = builder(); - + default void assertBlobsDAOCanStoreAndRetrieve(ObjectStorageBlobsDAOBuilder builder) + throws InterruptedException, ExecutionException, TimeoutException { BlobStore blobStore = builder.getSupplier().get(); blobStore.createContainerInLocation(DEFAULT_LOCATION, containerName().value()); ObjectStorageBlobsDAO dao = builder.build(); http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java index 8821d31..36e01fe 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone2ObjectStorageBlobsDAOBuilderTest.java @@ -58,14 +58,6 @@ class SwiftKeystone2ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo } @Override - public ObjectStorageBlobsDAOBuilder builder() { - return ObjectStorageBlobsDAO - .builder(testConfig) - .container(containerName) - .blobIdFactory(new HashBlobId.Factory()); - } - - @Override public ContainerName containerName() { return containerName; } @@ -87,4 +79,14 @@ class SwiftKeystone2ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlo assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); } + + @Test + public void builtBlobsDAOCanStoreAndRetrieve() throws Exception { + ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO + .builder(testConfig) + .container(containerName) + .blobIdFactory(new HashBlobId.Factory()); + + assertBlobsDAOCanStoreAndRetrieve(builder); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.java new file mode 100644 index 0000000..db5edd3 --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageBlobsDAOBuilderTest.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.swift; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.james.blob.api.HashBlobId; +import org.apache.james.blob.objectstorage.ContainerName; +import org.apache.james.blob.objectstorage.DockerSwift; +import org.apache.james.blob.objectstorage.DockerSwiftExtension; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAO; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOBuilder; +import org.apache.james.blob.objectstorage.ObjectStorageBlobsDAOContract; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@ExtendWith(DockerSwiftExtension.class) +class SwiftKeystone3ObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlobsDAOContract { + + private static final DomainName DOMAIN_NAME = DomainName.of("Default"); + private static final DomainId DOMAIN_ID = DomainId.of("default"); + private static final ProjectName PROJECT_NAME = ProjectName.of("test"); + private static final UserName DEMO_USER_NAME = UserName.of("demo"); + private static final Credentials DEMO_PASSWORD = Credentials.of("demo"); + private static final IdentityV3 DEMO_IDENTITY = IdentityV3.of(DOMAIN_NAME, DEMO_USER_NAME); + + private static final String PROJECT_CONFIG_KEY = "PROJECT_CONFIG_KEY"; + private static final SwiftKeystone3ObjectStorage.Configuration.Builder PROJECT_CONFIG = + SwiftKeystone3ObjectStorage.configBuilder() + .identity(DEMO_IDENTITY) + .credentials(DEMO_PASSWORD) + .project(Project.of(PROJECT_NAME)); + + private static final String PROJECT_DOMAIN_NAME_KEY = "PROJECT_DOMAIN_NAME_KEY"; + private static final SwiftKeystone3ObjectStorage.Configuration.Builder PROJECT_DOMAIN_NAME_SCOPE = + SwiftKeystone3ObjectStorage.configBuilder() + .identity(DEMO_IDENTITY) + .credentials(DEMO_PASSWORD) + .project(Project.of(PROJECT_NAME, DOMAIN_NAME)); + + private static final String PROJECT_DOMAIN_ID_KEY = "PROJECT_DOMAIN_ID_KEY"; + private static final SwiftKeystone3ObjectStorage.Configuration.Builder PROJECT_DOMAIN_ID_SCOPE = + SwiftKeystone3ObjectStorage.configBuilder() + .identity(DEMO_IDENTITY) + .credentials(DEMO_PASSWORD) + .project(Project.of(PROJECT_NAME, DOMAIN_ID)); + + private ContainerName containerName; + + private SwiftKeystone3ObjectStorage.Configuration testConfig; + private DockerSwift dockerSwift; + private Map<String, SwiftKeystone3ObjectStorage.Configuration.Builder> configBuilders; + + @BeforeEach + void setUp(DockerSwift dockerSwift) throws Exception { + this.dockerSwift = dockerSwift; + containerName = ContainerName.of(UUID.randomUUID().toString()); + testConfig = PROJECT_CONFIG + .endpoint(dockerSwift.keystoneV3Endpoint()) + .build(); + configBuilders = new HashMap<>(); + // There should be 2 more modes: unscoped and domain-scoped + // but the docker image doesn't support them... + configBuilders.put(PROJECT_CONFIG_KEY, PROJECT_CONFIG); + configBuilders.put(PROJECT_DOMAIN_ID_KEY, PROJECT_DOMAIN_ID_SCOPE); + configBuilders.put(PROJECT_DOMAIN_NAME_KEY, PROJECT_DOMAIN_NAME_SCOPE); + } + + @Override + public ContainerName containerName() { + return containerName; + } + + @Test + void containerNameIsMandatoryToBuildBlobsDAO() throws Exception { + ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO + .builder(testConfig) + .blobIdFactory(new HashBlobId.Factory()); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void blobIdFactoryIsMandatoryToBuildBlobsDAO() throws Exception { + ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO + .builder(testConfig) + .container(containerName); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @ParameterizedTest + @ValueSource(strings = {PROJECT_CONFIG_KEY, PROJECT_DOMAIN_ID_KEY, PROJECT_DOMAIN_NAME_KEY}) + public void builtBlobsDAOCanStoreAndRetrieve(String key) throws Exception { + SwiftKeystone3ObjectStorage.Configuration config = + configBuilders.get(key).endpoint(dockerSwift.keystoneV3Endpoint()).build(); + ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO + .builder(config) + .container(containerName) + .blobIdFactory(new HashBlobId.Factory()); + + assertBlobsDAOCanStoreAndRetrieve(builder); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageConfigurationTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageConfigurationTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageConfigurationTest.java new file mode 100644 index 0000000..90530ae --- /dev/null +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftKeystone3ObjectStorageConfigurationTest.java @@ -0,0 +1,161 @@ +/**************************************************************** + * 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.swift; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URI; + +import org.jclouds.openstack.keystone.config.KeystoneProperties; +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +class SwiftKeystone3ObjectStorageConfigurationTest { + + private static final ProjectName PROJECT_NAME = ProjectName.of("project"); + private static URI ENDPOINT = URI.create("http://example.com"); + private static Credentials CREDENTIALS = Credentials.of("fake"); + private static final DomainName DOMAIN_NAME = DomainName.of("fake"); + private static final DomainId DOMAIN_ID = DomainId.of("fake"); + private static IdentityV3 SWIFT_IDENTITY = + IdentityV3.of(DOMAIN_NAME, UserName.of("fake")); + + @Test + void enpointIsMandatoryToBuildConfiguration() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .identity(SWIFT_IDENTITY) + .credentials(CREDENTIALS); + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void identityIsMandatoryToBuildConfiguration() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .credentials(CREDENTIALS); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void credentialsIsMandatoryToBuildConfiguration() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY); + + assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); + } + + @Test + void configurationIsBuiltWhenAllMandatoryParamsAreProvided() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY) + .credentials(CREDENTIALS); + + SwiftKeystone3ObjectStorage.Configuration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(SWIFT_IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + assertThat(build.getOverrides().getProperty(KeystoneProperties.KEYSTONE_VERSION)).isEqualTo("3"); + } + + @Test + void authCanBeProjectScoped() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY) + .project(Project.of(PROJECT_NAME)) + .credentials(CREDENTIALS); + + SwiftKeystone3ObjectStorage.Configuration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(SWIFT_IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + assertThat(build.getOverrides().getProperty(KeystoneProperties.SCOPE)).isEqualTo(PROJECT_NAME.asString()); + } + + @Test + void authCanBeProjectAndDomainNameScoped() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY) + .project(Project.of(PROJECT_NAME, DOMAIN_NAME)) + .credentials(CREDENTIALS); + + SwiftKeystone3ObjectStorage.Configuration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(SWIFT_IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + assertThat(build.getOverrides().getProperty(KeystoneProperties.SCOPE)).isEqualTo(PROJECT_NAME.asString()); + assertThat(build.getOverrides().getProperty(KeystoneProperties.PROJECT_DOMAIN_NAME)).isEqualTo(DOMAIN_NAME.value()); + } + + @Test + void authCanBeProjectAndDomainIdScoped() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY) + .project(Project.of(PROJECT_NAME, DOMAIN_ID)) + .credentials(CREDENTIALS); + + SwiftKeystone3ObjectStorage.Configuration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(SWIFT_IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + assertThat(build.getOverrides().getProperty(KeystoneProperties.SCOPE)).isEqualTo(PROJECT_NAME.asString()); + assertThat(build.getOverrides().getProperty(KeystoneProperties.PROJECT_DOMAIN_ID)).isEqualTo(DOMAIN_ID.value()); + } + + @Test + void authCanBeDomainIdScoped() throws Exception { + SwiftKeystone3ObjectStorage.Configuration.Builder builder = + SwiftKeystone3ObjectStorage.configBuilder() + .endpoint(ENDPOINT) + .identity(SWIFT_IDENTITY) + .domainId(DOMAIN_ID) + .credentials(CREDENTIALS); + + SwiftKeystone3ObjectStorage.Configuration build = builder.build(); + + assertThat(build.getEndpoint()).isEqualTo(ENDPOINT); + assertThat(build.getIdentity()).isEqualTo(SWIFT_IDENTITY); + assertThat(build.getCredentials()).isEqualTo(CREDENTIALS); + assertThat(build.getOverrides().getProperty(KeystoneProperties.SCOPE)).isEqualTo(DOMAIN_ID.asString()); + } + + @Test + void configurationShouldEnforceBeanContract() { + EqualsVerifier.forClass(SwiftKeystone3ObjectStorage.Configuration.class); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/be1702dd/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java ---------------------------------------------------------------------- diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java index c44c1ad..7095624 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/swift/SwiftTempAuthObjectStorageBlobsDAOBuilderTest.java @@ -19,18 +19,11 @@ package org.apache.james.blob.objectstorage.swift; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.net.URI; -import java.nio.charset.StandardCharsets; import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.HashBlobId; import org.apache.james.blob.objectstorage.ContainerName; import org.apache.james.blob.objectstorage.DockerSwift; @@ -66,6 +59,11 @@ class SwiftTempAuthObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlob .build(); } + @Override + public ContainerName containerName() { + return containerName; + } + @Test void containerNameIsMandatoryToBuildBlobsDAO() throws Exception { ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO @@ -84,16 +82,13 @@ class SwiftTempAuthObjectStorageBlobsDAOBuilderTest implements ObjectStorageBlob assertThatThrownBy(builder::build).isInstanceOf(IllegalStateException.class); } - @Override - public ObjectStorageBlobsDAOBuilder builder() { - return ObjectStorageBlobsDAO + @Test + public void builtBlobsDAOCanStoreAndRetrieve() throws Exception { + ObjectStorageBlobsDAOBuilder builder = ObjectStorageBlobsDAO .builder(testConfig) .container(containerName) .blobIdFactory(new HashBlobId.Factory()); - } - @Override - public ContainerName containerName() { - return containerName; + assertBlobsDAOCanStoreAndRetrieve(builder); } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org