diff --git a/labs/openstack-swift/pom.xml b/labs/openstack-swift/pom.xml new file mode 100644 index 0000000000..d1480dd579 --- /dev/null +++ b/labs/openstack-swift/pom.xml @@ -0,0 +1,151 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.5.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds.labs + openstack-swift + jcloud openstack-swift api + jclouds components to access an implementation of OpenStack Swift + bundle + + + + http://localhost:5000 + + 1.0 + + FIXME_IDENTITY + FIXME_CREDENTIALS + passwordCredentials + FIXME_HTTPURL + FIXME_HTTPMD5 + + + + + org.jclouds.common + openstack-common + ${project.version} + + + org.jclouds + jclouds-blobstore + ${project.version} + + + org.jclouds + jclouds-core + ${project.version} + test-jar + test + + + org.jclouds.common + openstack-common + ${project.version} + test-jar + test + + + org.jclouds + jclouds-blobstore + ${project.version} + test-jar + test + + + org.jclouds.driver + jclouds-slf4j + ${project.version} + test + + + ch.qos.logback + logback-classic + 1.0.0 + test + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + ${test.openstack-swift.endpoint} + ${test.openstack-swift.api-version} + ${test.openstack-swift.build-version} + ${test.openstack-swift.identity} + ${test.openstack-swift.credential} + ${test.jclouds.keystone.credential-type} + ${jclouds.blobstore.httpstream.url} + ${jclouds.blobstore.httpstream.md5} + + + + + + + + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.openstack.swift.v1*;version="${project.version}" + + org.jclouds.blobstore.internal;version="${project.version}", + org.jclouds.rest.internal;version="${project.version}", + org.jclouds*;version="${project.version}", + * + + + + + + + + diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java new file mode 100644 index 0000000000..60a20eea8b --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java @@ -0,0 +1,100 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.services.ServiceType; +import org.jclouds.openstack.swift.v1.config.SwiftRestClientModule; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.internal.BaseRestApiMetadata; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; +import com.google.inject.Module; + +/** + * Implementation of {@link ApiMetadata} for Swift 1.0 API + * + * @author Adrian Cole + */ +public class SwiftApiMetadata extends BaseRestApiMetadata { + + /** The serialVersionUID */ + private static final long serialVersionUID = 6725672099385580694L; + + public static final TypeToken> CONTEXT_TOKEN = new TypeToken>() { + private static final long serialVersionUID = -5070937833892503232L; + }; + + @Override + public Builder toBuilder() { + return new Builder().fromApiMetadata(this); + } + + public SwiftApiMetadata() { + this(new Builder()); + } + + protected SwiftApiMetadata(Builder builder) { + super(builder); + } + + public static Properties defaultProperties() { + Properties properties = BaseRestApiMetadata.defaultProperties(); + properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); + // TODO: this doesn't actually do anything yet. + properties.setProperty(KeystoneProperties.VERSION, "2.0"); + return properties; + } + + public static class Builder extends BaseRestApiMetadata.Builder { + + protected Builder() { + super(SwiftClient.class, SwiftAsyncClient.class); + id("openstack-swift") + .name("OpenStack Swift Diablo+ API") + .identityName("tenantId:user") + .credentialName("password") + .documentation(URI.create("http://docs.openstack.org/api/openstack-object-storage/1.0/content/ch_object-storage-dev-overview.html")) + .version("1.0") + .defaultEndpoint("http://localhost:5000") + .defaultProperties(SwiftApiMetadata.defaultProperties()) + .defaultModules(ImmutableSet.>of(SwiftRestClientModule.class)); + } + + @Override + public SwiftApiMetadata build() { + return new SwiftApiMetadata(this); + } + + @Override + public Builder fromApiMetadata(ApiMetadata in) { + super.fromApiMetadata(in); + return this; + } + + } + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java new file mode 100644 index 0000000000..5f1fc80d59 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java @@ -0,0 +1,69 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import java.util.Set; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpoint; +import org.jclouds.openstack.swift.v1.features.AccountAsyncClient; +import org.jclouds.openstack.swift.v1.features.ContainerAsyncClient; +import org.jclouds.openstack.swift.v1.features.ObjectAsyncClient; +import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.EndpointParam; + +import com.google.inject.Provides; + +/** + * Provides asynchronous access to Swift via their REST API. + *

+ * + * @see SwiftClient + * @see api doc + * @author Adrian Cole + */ +public interface SwiftAsyncClient { + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides asynchronous access to Account features. + */ + @Delegate + AccountAsyncClient getAccountClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides asynchronous access to Container features. + */ + @Delegate + ContainerAsyncClient getContainerClientForRegion( + @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides asynchronous access to Object features. + */ + @Delegate + ObjectAsyncClient getObjectClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java new file mode 100644 index 0000000000..4f1e30e70c --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java @@ -0,0 +1,71 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpoint; +import org.jclouds.openstack.swift.v1.features.AccountClient; +import org.jclouds.openstack.swift.v1.features.ContainerClient; +import org.jclouds.openstack.swift.v1.features.ObjectClient; +import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.EndpointParam; + +import com.google.inject.Provides; + +/** + * Provides synchronous access to Swift. + *

+ * + * @see SwiftAsyncClient + * @see api doc + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface SwiftClient { + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides synchronous access to Account features. + */ + @Delegate + AccountClient getAccountClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides synchronous access to Container features. + */ + @Delegate + ContainerClient getContainerClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides synchronous access to Object features. + */ + @Delegate + ObjectClient getObjectClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java new file mode 100644 index 0000000000..57216017cf --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java @@ -0,0 +1,28 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.config; + +/** + * Configuration properties and constants used in openstack Swift connections. + * + * @author Adam Lowe + */ +public class SwiftProperties { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java new file mode 100644 index 0000000000..54dfd01498 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java @@ -0,0 +1,85 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.config; + +import java.util.Map; + +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.annotation.ClientError; +import org.jclouds.http.annotation.Redirection; +import org.jclouds.http.annotation.ServerError; +import org.jclouds.json.config.GsonModule.DateAdapter; +import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.openstack.swift.v1.features.AccountAsyncClient; +import org.jclouds.openstack.swift.v1.features.AccountClient; +import org.jclouds.openstack.swift.v1.features.ContainerAsyncClient; +import org.jclouds.openstack.swift.v1.features.ContainerClient; +import org.jclouds.openstack.swift.v1.features.ObjectAsyncClient; +import org.jclouds.openstack.swift.v1.features.ObjectClient; +import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.config.RestClientModule; + +import com.google.common.collect.ImmutableMap; + +/** + * Configures the Swift connection. + * + * @author Adrian Cole + */ +@ConfiguresRestClient +public class SwiftRestClientModule extends RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() + .put(AccountClient.class, AccountAsyncClient.class) + .put(ContainerClient.class, ContainerAsyncClient.class) + .put(ObjectClient.class, ObjectAsyncClient.class) + .build(); + + public SwiftRestClientModule() { + super(DELEGATE_MAP); + } + + @Override + protected void configure() { + bind(DateAdapter.class).to(Iso8601DateAdapter.class); + super.configure(); + } + + @Override + protected void installLocations() { + // TODO: select this from KeystoneProperties.VERSION; note you select from + // a guice provided + // property, so it will have to come from somewhere else, maybe we move + // this to the the + // ContextBuilder + install(KeystoneAuthenticationModule.forRegions()); + super.installLocations(); + } + + @Override + protected void bindErrorHandlers() { + bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(SwiftErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(SwiftErrorHandler.class); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java new file mode 100644 index 0000000000..61a53d5c4a --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java @@ -0,0 +1,101 @@ +package org.jclouds.openstack.swift.v1.domain; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * @author Adrian Cole + * @see api doc + */ +public class AccountMetadata { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().fromAccountMetadata(this); + } + + public static class Builder { + protected int containerCount; + protected long bytesUsed; + + /** + * @see AccountMetadata#getContainerCount() + */ + public Builder containerCount(int containerCount) { + this.containerCount = containerCount; + return this; + } + + /** + * @see AccountMetadata#getBytesUsed() + */ + public Builder bytesUsed(long bytesUsed) { + this.bytesUsed = bytesUsed; + return this; + } + + public AccountMetadata build() { + return new AccountMetadata(containerCount, bytesUsed); + } + + public Builder fromAccountMetadata(AccountMetadata from) { + return containerCount(from.getContainerCount()).bytesUsed(from.getBytesUsed()); + } + } + + protected final int containerCount; + protected final long bytesUsed; + + public AccountMetadata(int containerCount, long bytesUsed) { + this.containerCount = containerCount; + this.bytesUsed = bytesUsed; + } + + /** + * + * @return the number of containers in OpenStack Object Storage for the account + */ + public int getContainerCount() { + return containerCount; + } + + /** + * @return the total bytes stored in OpenStack Object Storage for the account + */ + public long getBytesUsed() { + return bytesUsed; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof AccountMetadata) { + final AccountMetadata other = AccountMetadata.class.cast(object); + return equal(getContainerCount(), other.getContainerCount()) && equal(getBytesUsed(), other.getBytesUsed()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(getContainerCount(), getBytesUsed()); + } + + @Override + public String toString() { + return string().toString(); + } + + protected ToStringHelper string() { + return toStringHelper("").add("containerCount", getContainerCount()).add("bytesUsed", getBytesUsed()); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java new file mode 100644 index 0000000000..2852022535 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java @@ -0,0 +1,138 @@ +package org.jclouds.openstack.swift.v1.domain; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * retrieve a list of existing storage containers ordered by name. The sort order for the name is + * based on a binary comparison, a single built-in collating sequence that compares string data + * using SQLite's memcmp() function, regardless of text encoding. + * + * @author Adrian Cole + * @see api + * doc + */ +public class ContainerMetadata implements Comparable { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().fromAccountMetadata(this); + } + + public static class Builder { + protected String name; + protected int count; + protected int bytes; + + /** + * @see ContainerMetadata#getName() + */ + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + /** + * @see ContainerMetadata#getCount() + */ + public Builder count(int count) { + this.count = count; + return this; + } + + /** + * @see ContainerMetadata#getBytes() + */ + public Builder bytes(int bytes) { + this.bytes = bytes; + return this; + } + + public ContainerMetadata build() { + return new ContainerMetadata(name, count, bytes); + } + + public Builder fromAccountMetadata(ContainerMetadata from) { + return name(from.getName()).count(from.getCount()).bytes(from.getBytes()); + } + } + + protected final String name; + protected final int count; + protected final int bytes; + + public ContainerMetadata(String name, int count, int bytes) { + this.name = checkNotNull(name, "name"); + this.count = count; + this.bytes = bytes; + } + + /** + * + * @return the name of the container + */ + public String getName() { + return name; + } + + /** + * + * @return the number of objects in the container + */ + public int getCount() { + return count; + } + + /** + * @return the total bytes stored in this container + */ + public int getBytes() { + return bytes; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof ContainerMetadata) { + final ContainerMetadata other = ContainerMetadata.class.cast(object); + return equal(getName(), other.getName()) && equal(getCount(), other.getCount()) + && equal(getBytes(), other.getBytes()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(getName(), getCount(), getBytes()); + } + + @Override + public String toString() { + return string().toString(); + } + + protected ToStringHelper string() { + return toStringHelper("").add("name", getName()).add("count", getCount()).add("bytes", getBytes()); + } + + @Override + public int compareTo(ContainerMetadata that) { + if (that == null) + return 1; + if (this == that) + return 0; + return this.getName().compareTo(that.getName()); + } + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java new file mode 100644 index 0000000000..c159b221cd --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java @@ -0,0 +1,83 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.functions.ParseAccountMetadataResponseFromHeaders; +import org.jclouds.openstack.swift.v1.options.ListContainersOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Storage Account Services + * + * @see AccountClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding( { '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface AccountAsyncClient { + + /** + * @see AccountClient#getAccountMetadata + */ + @HEAD + @ResponseParser(ParseAccountMetadataResponseFromHeaders.class) + @Path("/") + ListenableFuture getAccountMetadata(); + + /** + * @see AccountClient#listContainers() + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @QueryParams(keys = "format", values = "json") + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + @Path("/") + ListenableFuture> listContainers(); + + /** + * @see AccountClient#listContainers(ListContainersOptions) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @QueryParams(keys = "format", values = "json") + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + @Path("/") + ListenableFuture> listContainers(ListContainersOptions options); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java new file mode 100644 index 0000000000..a00414c61a --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java @@ -0,0 +1,62 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.options.ListContainersOptions; + +/** + * Storage Account Services + * + * @see AccountAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface AccountClient { + /** + * Retrieve Account Metadata + * + * @return account metadata including container count and bytes used + */ + AccountMetadata getAccountMetadata(); + + /** + * @see #listContainers(ListContainersOptions) + */ + Set listContainers(); + + /** + * retrieve a list of existing storage containers ordered by name. The sort order for the name is + * based on a binary comparison, a single built-in collating sequence that compares string data + * using SQLite's memcmp() function, regardless of text encoding. + * + * @param options + * @return a list of existing storage containers ordered by name. + */ + Set listContainers(ListContainersOptions options); + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java new file mode 100644 index 0000000000..68fda93deb --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java @@ -0,0 +1,38 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; + +/** + * Storage Container Services + * + * @see ContainerClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding({ '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface ContainerAsyncClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java new file mode 100644 index 0000000000..fc91e8e253 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java @@ -0,0 +1,37 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; + +/** + * Storage Container Services + * + * @see ContainerAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface ContainerClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java new file mode 100644 index 0000000000..597a5e2e17 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java @@ -0,0 +1,38 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; + +/** + * Storage Object Services + * + * @see ObjectClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding( { '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface ObjectAsyncClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java new file mode 100644 index 0000000000..18a8145401 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java @@ -0,0 +1,43 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; + +/** + * Storage Object Services An object represents the data and any metadata for the files stored in + * the system. Through the ReST interface, metadata for an object can be included by adding custom + * HTTP headers to the request and the data payload as the request body. Objects cannot exceed 5GB + * and must have names that do not exceed 1024 bytes after URL encoding. However, objects larger + * than 5GB can be segmented and then concatenated together so that you can upload 5 GB segments and + * download a single concatenated object. You can work with the segments and manifests directly with + * HTTP requests. + * + * @see ObjectAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface ObjectClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java new file mode 100644 index 0000000000..e01ccadfed --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java @@ -0,0 +1,42 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.functions; + +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; + +import com.google.common.base.Function; + +/** + * This parses {@link AccountMetadata} from HTTP headers. + * + * @author James Murty + */ +public class ParseAccountMetadataResponseFromHeaders implements Function { + + /** + * parses the http response headers to create a new {@link AccountMetadata} object. + */ + public AccountMetadata apply(HttpResponse from) { + return AccountMetadata.builder() + .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Account-Bytes-Used"))) + .containerCount(Integer.parseInt(from.getFirstHeaderOrNull("X-Account-Container-Count"))) + .build(); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java new file mode 100644 index 0000000000..0437dd48e3 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java @@ -0,0 +1,82 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.handlers; + +import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Singleton; + +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; +import org.jclouds.rest.AuthorizationException; + +/** + * This will parse and set an appropriate exception on the command object. + * + * @author Adrian Cole + * + */ +// TODO: is there error spec someplace? let's type errors, etc. +@Singleton +public class SwiftErrorHandler implements HttpErrorHandler { + public static final String PREFIX = "^/v[0-9][^/]*/[a-zA-Z]+_[^/]+/"; + public static final Pattern CONTAINER_PATH = Pattern.compile(PREFIX + "([^/]+)$"); + public static final Pattern CONTAINER_KEY_PATH = Pattern.compile(PREFIX + "([^/]+)/(.*)"); + + public void handleError(HttpCommand command, HttpResponse response) { + // it is important to always read fully and close streams + byte[] data = closeClientButKeepContentStream(response); + String message = data != null ? new String(data) : null; + + Exception exception = message != null ? new HttpResponseException(command, response, message) + : new HttpResponseException(command, response); + message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), + response.getStatusLine()); + switch (response.getStatusCode()) { + case 401: + exception = new AuthorizationException(exception.getMessage(), exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + String path = command.getCurrentRequest().getEndpoint().getPath(); + Matcher matcher = CONTAINER_PATH.matcher(path); + Exception oldException = exception; + if (matcher.find()) { + exception = new ContainerNotFoundException(matcher.group(1), message); + exception.initCause(oldException); + } else { + matcher = CONTAINER_KEY_PATH.matcher(path); + if (matcher.find()) { + exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message); + exception.initCause(oldException); + } + } + } + break; + } + command.setException(exception); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java new file mode 100644 index 0000000000..e2afee6159 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java @@ -0,0 +1,79 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.options; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import org.jclouds.http.options.BaseHttpRequestOptions; + +/** + * Contains options supported in the REST API for the GET container operation.

+ */ +public class ListContainersOptions extends BaseHttpRequestOptions { + public static final ListContainersOptions NONE = new ListContainersOptions(); + + /** + * Given a string value x, return object names greater in value than the specified marker. + */ + public ListContainersOptions marker(String marker) { + queryParameters.put("marker", checkNotNull(marker, "marker")); + return this; + } + + public String getMarker() { + return getFirstQueryOrNull("marker"); + } + + /** + * For an integer value n, limits the number of results to n values. + */ + public ListContainersOptions limit(int limit) { + checkState(limit >= 0, "limit must be >= 0"); + checkState(limit <= 10000, "limit must be <= 10000"); + queryParameters.put("limit", Integer.toString(limit)); + return this; + } + + public int getLimit() { + String val = getFirstQueryOrNull("limit"); + return val != null ? new Integer(val) : 10000; + } + + + public static class Builder { + + /** + * @see ListContainersOptions#marker(String) + */ + public static ListContainersOptions marker(String marker) { + ListContainersOptions options = new ListContainersOptions(); + return options.marker(marker); + } + + /** + * @see ListContainersOptions#limit(int) + */ + public static ListContainersOptions limit(int limit) { + ListContainersOptions options = new ListContainersOptions(); + return options.limit(limit); + } + + } +} diff --git a/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata b/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata new file mode 100644 index 0000000000..84f1200b16 --- /dev/null +++ b/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata @@ -0,0 +1 @@ +org.jclouds.openstack.swift.v1.SwiftApiMetadata diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java new file mode 100644 index 0000000000..8ec1e81980 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java @@ -0,0 +1,75 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.jclouds.openstack.swift.v1.parse.ParseContainerListTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * + * @see KeystoneProperties#CREDENTIAL_TYPE + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "PasswordAuthenticationExpectTest") +public class PasswordAuthenticationExpectTest extends BaseSwiftClientExpectTest { + + /** + * this reflects the properties that a user would pass to createContext + */ + @Override + protected Properties setupProperties() { + Properties contextProperties = super.setupProperties(); + contextProperties.setProperty("jclouds.keystone.credential-type", "passwordCredentials"); + return contextProperties; + } + + public void testListContainersWhenResponseIs2xx() throws Exception { + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/container_list.json")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals(clientWhenContainersExist.getConfiguredRegions(), ImmutableSet.of("region-a.geo-1")); + + assertEquals(clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers().toString(), + new ParseContainerListTest().expected().toString()); + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java new file mode 100644 index 0000000000..2cd22db3c8 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java @@ -0,0 +1,38 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import org.jclouds.Wrapper; +import org.jclouds.apis.internal.BaseApiMetadataTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "SwiftApiMetadataTest") +// public class SwiftApiMetadataTest extends BaseBlobStoreApiMetadataTest { +public class SwiftApiMetadataTest extends BaseApiMetadataTest { + public SwiftApiMetadataTest() { + super(new SwiftApiMetadata(), ImmutableSet.> of()); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java new file mode 100644 index 0000000000..bc2a762f57 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java @@ -0,0 +1,120 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; + +import java.net.URI; + +import org.easymock.IArgumentMatcher; +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "SwiftErrorHandlerTest") +public class SwiftErrorHandlerTest { + + @Test + public void test404SetsKeyNotFoundExceptionMosso() { + assertCodeMakes("HEAD", URI + .create("http://host/v1/MossoCloudFS_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1/key"), 404, + "Not Found", "", KeyNotFoundException.class); + } + + @Test + public void test404SetsKeyNotFoundExceptionSwift() { + assertCodeMakes("HEAD", URI + .create("http://67.202.39.175:8080/v1/AUTH_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1/key"), + 404, "Not Found", "", KeyNotFoundException.class); + } + + @Test + public void test404SetsContainerNotFoundExceptionMosso() { + assertCodeMakes("HEAD", URI + .create("http://host/v1/MossoCloudFS_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1"), 404, + "Not Found", "", ContainerNotFoundException.class); + } + + @Test + public void test404SetsContainerNotFoundExceptionSwift() { + assertCodeMakes("HEAD", URI + .create("http://67.202.39.175:8080/v1/AUTH_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1"), + 404, "Not Found", "", ContainerNotFoundException.class); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, + Class expected) { + assertCodeMakes(method, uri, statusCode, message, "text/plain", content, expected); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, + String content, Class expected) { + + SwiftErrorHandler function = new SwiftErrorHandler(); + + HttpCommand command = createMock(HttpCommand.class); + HttpRequest request = new HttpRequest(method, uri); + HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 + .toInputStream(content))); + response.getPayload().getContentMetadata().setContentType(contentType); + + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); + command.setException(classEq(expected)); + + replay(command); + + function.handleError(command, response); + + verify(command); + } + + public static Exception classEq(final Class in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("classEq("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return arg.getClass() == in; + } + + }); + return null; + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java new file mode 100644 index 0000000000..5038f6cae4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java @@ -0,0 +1,104 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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 + * + * Unles 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 expres or implied. See the License for the + * specific language governing permisions and limitations + * under the License. + */ +package org.jclouds.openstack.swift.v1.features; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.jclouds.openstack.swift.v1.parse.ParseContainerListTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "AccountClientExpectTest") +public class AccountClientExpectTest extends BaseSwiftClientExpectTest { + + public void testGetAccountMetadataWhenResponseIs2xx() throws Exception { + + HttpRequest getAccountMetadata = HttpRequest + .builder() + .method("HEAD") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/")) + .headers( + ImmutableMultimap. builder() + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(204) + .headers(ImmutableMultimap.of( + "X-Account-Container-Count", "3", + "X-Account-Bytes-Used", "323479")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, getAccountMetadata, listContainersResponse); + + assertEquals( + clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").getAccountMetadata(), + AccountMetadata.builder().containerCount(3).bytesUsed(323479).build()); + } + + public void testListContainersWhenResponseIs2xx() throws Exception { + + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/container_list.json")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals( + clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers() + .toString(), new ParseContainerListTest().expected().toString()); + } + + public void testListContainersWhenResponseIs404() throws Exception { + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(404).build(); + + SwiftClient clientWhenNoContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals(clientWhenNoContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers(), ImmutableSet.of()); + + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java new file mode 100644 index 0000000000..1eb410a1db --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java @@ -0,0 +1,61 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.Set; + +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ContainerClientLiveTest") +public class AccountClientLiveTest extends BaseSwiftClientLiveTest { + + @Test + public void testGetAccountMetadata() throws Exception { + for (String regionId : swiftContext.getApi().getConfiguredRegions()) { + AccountClient client = swiftContext.getApi().getAccountClientForRegion(regionId); + AccountMetadata account = client.getAccountMetadata(); + assertNotNull(account); + assertTrue(account.getContainerCount() >= 0); + assertTrue(account.getBytesUsed() >= 0); + } + } + + @Test + public void testListContainers() throws Exception { + for (String regionId : swiftContext.getApi().getConfiguredRegions()) { + AccountClient client = swiftContext.getApi().getAccountClientForRegion(regionId); + Set response = client.listContainers(); + assertNotNull(response); + for (ContainerMetadata container : response) { + assertNotNull(container.getName()); + assertTrue(container.getCount() >= 0); + assertTrue(container.getBytes() >= 0); + } + } + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java new file mode 100644 index 0000000000..ecec4c562c --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java @@ -0,0 +1,31 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ContainerAsyncClientTest") +public class ContainerClientExpectTest extends BaseSwiftClientExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java new file mode 100644 index 0000000000..dcbe482135 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java @@ -0,0 +1,31 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ContainerClientLiveTest") +public class ContainerClientLiveTest extends BaseSwiftClientLiveTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java new file mode 100644 index 0000000000..f38bf988e1 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java @@ -0,0 +1,30 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ObjectAsyncClientTest") +public class ObjectClientExpectTest extends BaseSwiftClientExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java new file mode 100644 index 0000000000..f8d816c48e --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java @@ -0,0 +1,30 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ObjectClientLiveTest") +public class ObjectClientLiveTest extends BaseSwiftClientLiveTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java new file mode 100644 index 0000000000..1668d4276b --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java @@ -0,0 +1,39 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.internal; + +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; + +import com.google.common.base.Function; +import com.google.inject.Module; + +/** + * Base class for writing KeyStone Rest Client Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftAsyncClientExpectTest extends BaseSwiftExpectTest { + public SwiftAsyncClient createClient(Function fn, Module module, Properties props) { + return createInjector(fn, module, props).getInstance(SwiftAsyncClient.class); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java new file mode 100644 index 0000000000..b3f4330057 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java @@ -0,0 +1,30 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.internal; + +import org.jclouds.openstack.swift.v1.SwiftClient; + +/** + * Base class for writing KeyStone Rest Client Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftClientExpectTest extends BaseSwiftExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java new file mode 100644 index 0000000000..3eb8dfb0b4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java @@ -0,0 +1,74 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.internal; + +import java.util.Properties; + +import org.jclouds.apis.BaseContextLiveTest; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.SwiftApiMetadata; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +/** + * Tests behavior of {@code SwiftClient} + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class BaseSwiftClientLiveTest extends BaseContextLiveTest> { + + public BaseSwiftClientLiveTest() { + provider = "openstack-swift"; + } + + protected RestContext swiftContext; + + @BeforeGroups(groups = { "integration", "live" }) + @Override + public void setupContext() { + super.setupContext(); + swiftContext = context; + } + + @Override + protected Properties setupProperties() { + Properties props = super.setupProperties(); + setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE); + return props; + } + + @AfterGroups(groups = "live") + protected void tearDown() { + if (swiftContext != null) + swiftContext.close(); + } + + @Override + protected TypeToken> contextType() { + return SwiftApiMetadata.CONTEXT_TOKEN; + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java new file mode 100644 index 0000000000..67d55b8832 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java @@ -0,0 +1,52 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.internal; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture; +import org.jclouds.rest.internal.BaseRestClientExpectTest; + +/** + * Base class for writing Swift Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftExpectTest extends BaseRestClientExpectTest { + protected HttpRequest keystoneAuthWithUsernameAndPassword; + protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey; + protected String authToken; + protected HttpResponse responseWithKeystoneAccess; + protected HttpRequest extensionsOfSwiftRequest; + protected HttpResponse extensionsOfSwiftResponse; + protected HttpResponse unmatchedExtensionsOfSwiftResponse; + + public BaseSwiftExpectTest() { + provider = "openstack-swift"; + keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity, + credential); + keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity, + credential); + + authToken = KeystoneFixture.INSTANCE.getAuthToken(); + responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess(); + // now, createContext arg will need tenant prefix + identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity; + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java new file mode 100644 index 0000000000..64b207034b --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java @@ -0,0 +1,96 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.options; + +import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.limit; +import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.marker; +import static org.testng.Assert.assertEquals; + +import java.util.Collections; + +import org.jclouds.http.options.HttpRequestOptions; +import org.testng.annotations.Test; + +/** + * Tests possible uses of ListContainerOptions and ListContainerOptions.Builder.* + * + * @author Adrian Cole + */ +@Test(testName = "ListContainersOptionsTest") +public class ListContainersOptionsTest { + + @Test + public void testAssignability() { + assert HttpRequestOptions.class.isAssignableFrom(ListContainersOptions.class); + assert !String.class.isAssignableFrom(ListContainersOptions.class); + } + @Test + public void testNoOptionsQueryString() { + HttpRequestOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().size(), 0); + } + + @Test + public void testMarker() { + ListContainersOptions options = new ListContainersOptions(); + options.marker("test"); + assertEquals(options.buildQueryParameters().get("marker"), Collections.singletonList("test")); + } + + @Test + public void testNullMarker() { + ListContainersOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().get("marker"), Collections.EMPTY_LIST); + } + + @Test + public void testMarkerStatic() { + ListContainersOptions options = marker("test"); + assertEquals(options.buildQueryParameters().get("marker"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testMarkerNPE() { + marker(null); + } + + @Test + public void testLimit() { + ListContainersOptions options = new ListContainersOptions(); + options.limit(1000); + assertEquals(options.buildQueryParameters().get("limit"), Collections.singletonList("1000")); + } + + @Test + public void testNullLimit() { + ListContainersOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().get("limit"), Collections.EMPTY_LIST); + } + + @Test + public void testLimitStatic() { + ListContainersOptions options = limit(1000); + assertEquals(options.buildQueryParameters().get("limit"), Collections.singletonList("1000")); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testLimitNegative() { + limit(-1); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java new file mode 100644 index 0000000000..3c583121c4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java @@ -0,0 +1,59 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.openstack.swift.v1.parse; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.json.BaseSetParserTest; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ParseContainerListTest") +public class ParseContainerListTest extends BaseSetParserTest { + + @Override + public String resource() { + return "/container_list.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public Set expected() { + return ImmutableSet + .of(ContainerMetadata.builder() + .name("test_container_1") + .count(2) + .bytes(78) + .build(), + ContainerMetadata.builder() + .name("test_container_2") + .count(1) + .bytes(17) + .build()); + } +} diff --git a/labs/openstack-swift/src/test/resources/container_list.json b/labs/openstack-swift/src/test/resources/container_list.json new file mode 100644 index 0000000000..ef7e791530 --- /dev/null +++ b/labs/openstack-swift/src/test/resources/container_list.json @@ -0,0 +1,4 @@ +[ + {"name":"test_container_1", "count":2, "bytes":78}, + {"name":"test_container_2", "count":1, "bytes":17} +] \ No newline at end of file diff --git a/labs/openstack-swift/src/test/resources/logback.xml b/labs/openstack-swift/src/test/resources/logback.xml new file mode 100644 index 0000000000..bd89efb8c0 --- /dev/null +++ b/labs/openstack-swift/src/test/resources/logback.xml @@ -0,0 +1,51 @@ + + + + target/test-data/jclouds.log + + + %d %-5p [%c] [%thread] %m%n + + + + + target/test-data/jclouds-wire.log + + + %d %-5p [%c] [%thread] %m%n + + + + + target/test-data/jclouds-blobstore.log + + + %d %-5p [%c] [%thread] %m%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/pom.xml b/labs/pom.xml index 60b5dee8da..b774ad00cb 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -41,5 +41,6 @@ savvis-symphonyvpdc dmtf carrenza-vcloud-director + openstack-swift