mirror of https://github.com/apache/jclouds.git
openstack-nova: Adding Volume Types extension
This commit is contained in:
parent
987f2f93c6
commit
95399121bd
|
@ -173,4 +173,11 @@ public interface NovaAsyncClient {
|
||||||
Optional<QuotaClassAsyncClient> getQuotaClassExtensionForZone(
|
Optional<QuotaClassAsyncClient> getQuotaClassExtensionForZone(
|
||||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Volume Type features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<VolumeTypeAsyncClient> getVolumeTypeExtensionForZone(
|
||||||
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,4 +174,11 @@ public interface NovaClient {
|
||||||
Optional<QuotaClassClient> getQuotaClassExtensionForZone(
|
Optional<QuotaClassClient> getQuotaClassExtensionForZone(
|
||||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Volume Type features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<VolumeTypeClient> getVolumeTypeExtensionForZone(
|
||||||
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
||||||
.put(FlavorExtraSpecsClient.class, FlavorExtraSpecsAsyncClient.class)
|
.put(FlavorExtraSpecsClient.class, FlavorExtraSpecsAsyncClient.class)
|
||||||
.put(QuotaClient.class, QuotaAsyncClient.class)
|
.put(QuotaClient.class, QuotaAsyncClient.class)
|
||||||
.put(QuotaClassClient.class, QuotaClassAsyncClient.class)
|
.put(QuotaClassClient.class, QuotaClassAsyncClient.class)
|
||||||
|
.put(VolumeTypeClient.class, VolumeTypeAsyncClient.class)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public NovaRestClientModule() {
|
public NovaRestClientModule() {
|
||||||
|
|
|
@ -466,9 +466,9 @@ public class Server extends Resource {
|
||||||
* Retrieves the extended server status fields (alias "OS-EXT-STS")
|
* Retrieves the extended server status fields (alias "OS-EXT-STS")
|
||||||
* <p/>
|
* <p/>
|
||||||
* NOTE: This field is only present if the Extended Status extension is installed.
|
* NOTE: This field is only present if the Extended Status extension is installed.
|
||||||
*
|
*
|
||||||
* @see org.jclouds.openstack.nova.v1_1.features.ExtensionClient#getExtensionByAlias
|
* @see org.jclouds.openstack.nova.v1_1.features.ExtensionClient#getExtensionByAlias
|
||||||
* @see org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces#EXTENDED_STATUS (extended status?)
|
* @see org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces#EXTENDED_STATUS
|
||||||
*/
|
*/
|
||||||
public Optional<ServerExtendedStatus> getExtendedStatus() {
|
public Optional<ServerExtendedStatus> getExtendedStatus() {
|
||||||
return this.extendedStatus;
|
return this.extendedStatus;
|
||||||
|
@ -480,16 +480,19 @@ public class Server extends Resource {
|
||||||
* NOTE: This field is only present if the The Extended Server Attributes API extension is installed.
|
* NOTE: This field is only present if the The Extended Server Attributes API extension is installed.
|
||||||
*
|
*
|
||||||
* @see org.jclouds.openstack.nova.v1_1.features.ExtensionClient#getExtensionByAlias
|
* @see org.jclouds.openstack.nova.v1_1.features.ExtensionClient#getExtensionByAlias
|
||||||
* @see org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces#EXTENDED_STATUS (extended status?)
|
* @see org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces#EXTENDED_STATUS
|
||||||
*/
|
*/
|
||||||
public Optional<ServerExtendedAttributes> getExtendedAttributes() {
|
public Optional<ServerExtendedAttributes> getExtendedAttributes() {
|
||||||
return this.extendedAttributes;
|
return this.extendedAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State of task running against this instance (e.g. "suspending")
|
* Disk config attribute from the Disk Config Extension (alias "OS-DCF")
|
||||||
* <p/>
|
* <p/>
|
||||||
* NOTE: This field is only present if the Disk Config extension is installed.
|
* NOTE: This field is only present if the Disk Config extension is installed
|
||||||
|
*
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.features.ExtensionClient#getExtensionByAlias
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces#DISK_CONFIG
|
||||||
*/
|
*/
|
||||||
public Optional<String> getDiskConfig() {
|
public Optional<String> getDiskConfig() {
|
||||||
return this.diskConfig;
|
return this.diskConfig;
|
||||||
|
@ -501,10 +504,10 @@ public class Server extends Resource {
|
||||||
@Override
|
@Override
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return super.string().add("uuid", uuid).add("tenantId", tenantId).add(
|
return super.string().add("uuid", uuid).add("tenantId", tenantId).add(
|
||||||
"userId", userId).add("hostId", getHostId()).add("updated", updated).add("created", created).add(
|
"userId", userId).add("hostId", getHostId()).add("updated", updated).add("created", created).add(
|
||||||
"accessIPv4", getAccessIPv4()).add("accessIPv6", getAccessIPv6()).add("status", status).add(
|
"accessIPv4", getAccessIPv4()).add("accessIPv6", getAccessIPv6()).add("status", status).add(
|
||||||
"configDrive", getConfigDrive()).add("image", image).add("flavor", flavor).add("metadata", metadata)
|
"configDrive", getConfigDrive()).add("image", image).add("flavor", flavor).add("metadata", metadata)
|
||||||
.add("addresses", getAddresses()).add("diskConfig", diskConfig)
|
.add("addresses", getAddresses()).add("diskConfig", diskConfig)
|
||||||
.add("extendedStatus", extendedStatus).add("extendedAttributes", extendedAttributes);
|
.add("extendedStatus", extendedStatus).add("extendedAttributes", extendedAttributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Volume Type used in the Volume Type Extension for Nova
|
||||||
|
*
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.extensions.VolumeTypeClient
|
||||||
|
*/
|
||||||
|
public class VolumeType {
|
||||||
|
|
||||||
|
public static Builder<?> builder() {
|
||||||
|
return new ConcreteBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<?> toBuilder() {
|
||||||
|
return new ConcreteBuilder().fromVolumeType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class Builder<T extends Builder<T>> {
|
||||||
|
protected abstract T self();
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private Date created = new Date();
|
||||||
|
private Date updated;
|
||||||
|
private Map<String, String> extraSpecs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeType#getId()
|
||||||
|
*/
|
||||||
|
public T id(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeType#getName()
|
||||||
|
*/
|
||||||
|
public T name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeType#getCreated()
|
||||||
|
*/
|
||||||
|
public T created(Date created) {
|
||||||
|
this.created = created;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeType#getUpdated()
|
||||||
|
*/
|
||||||
|
public T updated(Date updated) {
|
||||||
|
this.updated = updated;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeType#getExtraSpecs()
|
||||||
|
*/
|
||||||
|
public T extraSpecs(Map<String, String> extraSpecs) {
|
||||||
|
this.extraSpecs = ImmutableMap.copyOf(extraSpecs);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VolumeType build() {
|
||||||
|
return new VolumeType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T fromVolumeType(VolumeType in) {
|
||||||
|
return this
|
||||||
|
.id(in.getId())
|
||||||
|
.name(in.getName())
|
||||||
|
.extraSpecs(in.getExtraSpecs())
|
||||||
|
.created(in.getCreated())
|
||||||
|
.updated(in.getUpdated().orNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
||||||
|
@Override
|
||||||
|
protected ConcreteBuilder self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
@SerializedName("created_at")
|
||||||
|
private Date created;
|
||||||
|
@SerializedName("updated_at")
|
||||||
|
private final Optional<Date> updated;
|
||||||
|
@SerializedName(value = "extra_specs")
|
||||||
|
private final Map<String, String> extraSpecs;
|
||||||
|
|
||||||
|
protected VolumeType(Builder<?> builder) {
|
||||||
|
this.id = checkNotNull(builder.id, "id");
|
||||||
|
this.name = checkNotNull(builder.name, "name");
|
||||||
|
this.extraSpecs = checkNotNull(builder.extraSpecs, "extraSpecs");
|
||||||
|
this.created = checkNotNull(builder.created, "created");
|
||||||
|
this.updated = Optional.fromNullable(builder.updated);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected VolumeType() {
|
||||||
|
this.updated = Optional.absent();
|
||||||
|
this.extraSpecs = ImmutableMap.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The Date the VolumeType was created */
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The Date the VolumeType as last updated - absent if no updates have taken place */
|
||||||
|
public Optional<Date> getUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getExtraSpecs() {
|
||||||
|
return Collections.unmodifiableMap(this.extraSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(id, name, created, updated, extraSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
VolumeType that = VolumeType.class.cast(obj);
|
||||||
|
return Objects.equal(this.id, that.id)
|
||||||
|
&& Objects.equal(this.name, that.name)
|
||||||
|
&& Objects.equal(this.created, that.created)
|
||||||
|
&& Objects.equal(this.updated, that.updated)
|
||||||
|
&& Objects.equal(this.extraSpecs, that.extraSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return Objects.toStringHelper("")
|
||||||
|
.add("id", id)
|
||||||
|
.add("name", name)
|
||||||
|
.add("created", created)
|
||||||
|
.add("updated", updated)
|
||||||
|
.add("extraSpecs", extraSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.binders.BindExtraSpecsToJsonPayload;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.VolumeType;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.options.CreateVolumeTypeOptions;
|
||||||
|
import org.jclouds.openstack.services.Extension;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.Payload;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.annotations.Unwrap;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptyMapOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Volume Type features
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see VolumeTypeClient
|
||||||
|
*/
|
||||||
|
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUME_TYPES)
|
||||||
|
@SkipEncoding({'/', '='})
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@Path("/os-volume-types")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public interface VolumeTypeAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#listVolumeTypes
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("volume_types")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<VolumeType>> listVolumeTypes();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#getVolumeType
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/{id}")
|
||||||
|
@SelectJson("volume_type")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<VolumeType> getVolumeType(@PathParam("id") String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#createVolumeType
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@SelectJson("volume_type")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Payload("%7B\"volume_type\":%7B\"name\":\"{name}\"%7D%7D")
|
||||||
|
ListenableFuture<VolumeType> createVolumeType(@PayloadParam("name") String name, CreateVolumeTypeOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#deleteVolumeType
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Path("/{id}")
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Boolean> deleteVolumeType(@PathParam("id") String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#getAllExtraSpecs(String)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("extra_specs")
|
||||||
|
@Path("/{id}/extra_specs")
|
||||||
|
@ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Map<String, String>> getAllExtraSpecs(@PathParam("id") String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#setAllExtraSpecs(String, java.util.Map)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/{id}/extra_specs")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
@MapBinder(BindExtraSpecsToJsonPayload.class)
|
||||||
|
ListenableFuture<Boolean> setAllExtraSpecs(@PathParam("id") String id, Map<String, String> specs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#getExtraSpec(String, String)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/{id}/extra_specs/{key}")
|
||||||
|
@Unwrap
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<String> getExtraSpec(@PathParam("id") String id, @PathParam("key") String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#setExtraSpec(String, String, String)
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/{id}/extra_specs/{key}")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Payload("%7B\"{key}\":\"{value}\"%7D")
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Boolean> setExtraSpec(@PathParam("id") String id,
|
||||||
|
@PathParam("key") @PayloadParam("key") String key,
|
||||||
|
@PayloadParam("value") String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VolumeTypeClient#deleteExtraSpec(String, String)
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Path("/{id}/extra_specs/{key}")
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Boolean> deleteExtraSpec(@PathParam("id") String id,
|
||||||
|
@PathParam("key") String key);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.VolumeType;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.options.CreateVolumeTypeOptions;
|
||||||
|
import org.jclouds.openstack.services.Extension;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Volume Type features
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see VolumeClient
|
||||||
|
* @see VolumeTypeAsyncClient
|
||||||
|
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.volumetypes.html"/>
|
||||||
|
* @see <a href="https://blueprints.launchpad.net/nova/+spec/volume-type"/>
|
||||||
|
*/
|
||||||
|
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUME_TYPES)
|
||||||
|
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
public interface VolumeTypeClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return set of all volume types
|
||||||
|
*/
|
||||||
|
Set<VolumeType> listVolumeTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id of the volume type to retrieve
|
||||||
|
* @return the requested volume type
|
||||||
|
*/
|
||||||
|
VolumeType getVolumeType(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new volume type
|
||||||
|
*
|
||||||
|
* @param name the name of the new volume type
|
||||||
|
* @param options optional settings for the new volume type
|
||||||
|
* @return the new volume type
|
||||||
|
*/
|
||||||
|
VolumeType createVolumeType(String name, CreateVolumeTypeOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a volume type
|
||||||
|
*/
|
||||||
|
Boolean deleteVolumeType(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id of the volume type
|
||||||
|
* @return the set of extra metadata for the flavor
|
||||||
|
*/
|
||||||
|
Map<String, String> getAllExtraSpecs(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates the extra metadata for a given flavor
|
||||||
|
*/
|
||||||
|
Boolean setAllExtraSpecs(String id, Map<String, String> specs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a single extra spec value
|
||||||
|
*
|
||||||
|
* @param id the id of the volume type
|
||||||
|
* @param key the key of the extra spec item to retrieve
|
||||||
|
*/
|
||||||
|
String getExtraSpec(String id, String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates a single extra spec value
|
||||||
|
*
|
||||||
|
* @param id the id of the volume type
|
||||||
|
* @param key the extra spec key (when creating ensure this does not include whitespace or other difficult characters)
|
||||||
|
* @param value the new value to store associate with the key
|
||||||
|
*/
|
||||||
|
Boolean setExtraSpec(String id, String key, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an existing extra spec
|
||||||
|
*
|
||||||
|
* @param id the id of the volume type
|
||||||
|
* @param key the key of the extra spec to delete
|
||||||
|
*/
|
||||||
|
Boolean deleteExtraSpec(String id, String key);
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.options;
|
||||||
|
|
||||||
|
import static com.google.common.base.Objects.equal;
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
public class CreateVolumeTypeOptions implements MapBinder {
|
||||||
|
public static final CreateVolumeTypeOptions NONE = new CreateVolumeTypeOptions();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected BindToJsonPayload jsonBinder;
|
||||||
|
|
||||||
|
protected Map<String, String> specs = ImmutableMap.of();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
|
Map<String, Object> data = Maps.newHashMap();
|
||||||
|
data.putAll(postParams);
|
||||||
|
data.put("extra_specs", specs);
|
||||||
|
return jsonBinder.bindToRequest(request, ImmutableMap.of("volume_type", data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||||
|
throw new IllegalStateException("CreateWithExtraSpecs are POST operations");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(object instanceof CreateVolumeTypeOptions)) return false;
|
||||||
|
final CreateVolumeTypeOptions other = CreateVolumeTypeOptions.class.cast(object);
|
||||||
|
return equal(specs, other.specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return toStringHelper("").add("specs", specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateVolumeTypeOptions specs(Map<String, String> specs) {
|
||||||
|
this.specs = specs;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getSpecs() {
|
||||||
|
return specs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
/**
|
||||||
|
* @see CreateVolumeTypeOptions#getSpecs()
|
||||||
|
*/
|
||||||
|
public static CreateVolumeTypeOptions specs(Map<String, String> specs) {
|
||||||
|
return new CreateVolumeTypeOptions().specs(specs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,260 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.VolumeType;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.options.CreateVolumeTypeOptions;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests guice wiring and parsing of VolumeTypeClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "VolumeTypeClientExpectTest")
|
||||||
|
public class VolumeTypeClientExpectTest extends BaseNovaClientExpectTest {
|
||||||
|
private DateService dateService = new SimpleDateFormatDateService();
|
||||||
|
|
||||||
|
public void testListVolumeTypes() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type_list.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
Set<VolumeType> types = client.listVolumeTypes();
|
||||||
|
assertEquals(types, ImmutableSet.of(testVolumeType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetVolumeType() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
VolumeType type = client.getVolumeType("8");
|
||||||
|
assertEquals(type, testVolumeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetVolumeTypeFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertNull(client.getVolumeType("8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateVolumeType() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("POST")
|
||||||
|
.payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\"}}", MediaType.APPLICATION_JSON))
|
||||||
|
.build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
VolumeType type = client.createVolumeType("jclouds-test-1");
|
||||||
|
assertEquals(type, testVolumeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateVolumeTypeWithOptsNONE() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("POST")
|
||||||
|
.payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\",\"extra_specs\":{}}}", MediaType.APPLICATION_JSON))
|
||||||
|
.build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
VolumeType type = client.createVolumeType("jclouds-test-1", CreateVolumeTypeOptions.NONE);
|
||||||
|
assertEquals(type, testVolumeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateVolumeTypeWithOptsSet() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("POST")
|
||||||
|
.payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\",\"extra_specs\":{\"x\": \"y\"}}}", MediaType.APPLICATION_JSON))
|
||||||
|
.build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
VolumeType type = client.createVolumeType("jclouds-test-1", CreateVolumeTypeOptions.Builder.specs(ImmutableMap.of("x", "y")));
|
||||||
|
assertEquals(type, testVolumeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteVolumeType() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("DELETE").build(),
|
||||||
|
standardResponseBuilder(200).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertTrue(client.deleteVolumeType("8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteVolumeTypeFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("DELETE").build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertFalse(client.deleteVolumeType("8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetAllExtraSpecs() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/volume_type_extra_specs.json")).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertEquals(client.getAllExtraSpecs("9"), ImmutableMap.of("test", "value1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetAllExtraSpecsFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertTrue(client.getAllExtraSpecs("9").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSetAllExtraSpecs() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint)
|
||||||
|
.method("POST")
|
||||||
|
.payload(payloadFromStringWithContentType("{\"extra_specs\":{\"test1\":\"somevalue\"}}", MediaType.APPLICATION_JSON)).build(),
|
||||||
|
standardResponseBuilder(200).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertTrue(client.setAllExtraSpecs("9", ImmutableMap.of("test1", "somevalue")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSetExtraSpec() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint)
|
||||||
|
.method("PUT")
|
||||||
|
.payload(payloadFromStringWithContentType("{\"test1\":\"somevalue\"}", MediaType.APPLICATION_JSON)).build(),
|
||||||
|
standardResponseBuilder(200).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertTrue(client.setExtraSpec("5", "test1", "somevalue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetExtraSpec() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromStringWithContentType("{\"test1\":\"another value\"}", MediaType.APPLICATION_JSON)).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertEquals(client.getExtraSpec("5", "test1"), "another value");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetExtraSpecFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertNull(client.getExtraSpec("5", "test1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteExtraSpec() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("DELETE").build(),
|
||||||
|
standardResponseBuilder(200).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertTrue(client.deleteExtraSpec("5", "test1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteExtraSpecFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
|
||||||
|
VolumeTypeClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).method("DELETE").build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
assertFalse(client.deleteExtraSpec("5", "test1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public VolumeType testVolumeType() {
|
||||||
|
return VolumeType.builder().id("8").name("jclouds-test-1").created(dateService.iso8601SecondsDateParse("2012-05-10 12:33:06")).extraSpecs(ImmutableMap.of("test", "value1", "test1", "wibble")).build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.VolumeType;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.options.CreateVolumeTypeOptions;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.testng.annotations.AfterGroups;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of VolumeTypeClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "VolumeTypeClientLiveTest", singleThreaded = true)
|
||||||
|
public class VolumeTypeClientLiveTest extends BaseNovaClientLiveTest {
|
||||||
|
|
||||||
|
private Optional<VolumeTypeClient> volumeTypeOption;
|
||||||
|
private String zone;
|
||||||
|
|
||||||
|
private VolumeType testVolumeType;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = {"integration", "live"})
|
||||||
|
@Override
|
||||||
|
public void setupContext() {
|
||||||
|
super.setupContext();
|
||||||
|
zone = Iterables.getLast(novaContext.getApi().getConfiguredZones(), "nova");
|
||||||
|
volumeTypeOption = novaContext.getApi().getVolumeTypeExtensionForZone(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterGroups(groups = "live")
|
||||||
|
@Override
|
||||||
|
protected void tearDown() {
|
||||||
|
if (volumeTypeOption.isPresent()) {
|
||||||
|
if (testVolumeType != null) {
|
||||||
|
final String id = testVolumeType.getId();
|
||||||
|
assertTrue(volumeTypeOption.get().deleteVolumeType(id));
|
||||||
|
assertTrue(new RetryablePredicate<VolumeTypeClient>(new Predicate<VolumeTypeClient>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(VolumeTypeClient volumeClient) {
|
||||||
|
return volumeClient.getVolumeType(id) == null;
|
||||||
|
}
|
||||||
|
}, 5 * 1000L).apply(volumeTypeOption.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateVolumeType() {
|
||||||
|
if (volumeTypeOption.isPresent()) {
|
||||||
|
testVolumeType = volumeTypeOption.get().createVolumeType(
|
||||||
|
"jclouds-test-1", CreateVolumeTypeOptions.Builder.specs(ImmutableMap.of("test", "value1")));
|
||||||
|
assertTrue(new RetryablePredicate<VolumeTypeClient>(new Predicate<VolumeTypeClient>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(VolumeTypeClient volumeTypeClient) {
|
||||||
|
return volumeTypeClient.getVolumeType(testVolumeType.getId()) != null;
|
||||||
|
}
|
||||||
|
}, 180 * 1000L).apply(volumeTypeOption.get()));
|
||||||
|
|
||||||
|
assertEquals(volumeTypeOption.get().getVolumeType(testVolumeType.getId()).getName(), "jclouds-test-1");
|
||||||
|
assertEquals(volumeTypeOption.get().getVolumeType(testVolumeType.getId()).getExtraSpecs(), ImmutableMap.of("test", "value1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateVolumeType")
|
||||||
|
public void testListVolumeTypes() {
|
||||||
|
if (volumeTypeOption.isPresent()) {
|
||||||
|
Set<VolumeType> volumeTypes = volumeTypeOption.get().listVolumeTypes();
|
||||||
|
assertNotNull(volumeTypes);
|
||||||
|
boolean foundIt = false;
|
||||||
|
for (VolumeType vt : volumeTypes) {
|
||||||
|
VolumeType details = volumeTypeOption.get().getVolumeType(vt.getId());
|
||||||
|
assertNotNull(details);
|
||||||
|
if (Objects.equal(details.getId(), testVolumeType.getId())) {
|
||||||
|
foundIt = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(foundIt, "Failed to find the volume type we created in listVolumeTypes() response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateVolumeType")
|
||||||
|
public void testExtraSpecs() {
|
||||||
|
if (volumeTypeOption.isPresent()) {
|
||||||
|
assertEquals(volumeTypeOption.get().getAllExtraSpecs(testVolumeType.getId()), ImmutableMap.of("test", "value1"));
|
||||||
|
assertEquals(volumeTypeOption.get().getExtraSpec(testVolumeType.getId(), "test"), "value1");
|
||||||
|
assertTrue(volumeTypeOption.get().setAllExtraSpecs(testVolumeType.getId(), ImmutableMap.of("test1", "wibble")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateVolumeType")
|
||||||
|
public void testUpdateIndividualSpec() {
|
||||||
|
if (volumeTypeOption.isPresent()) {
|
||||||
|
assertTrue(volumeTypeOption.get().setExtraSpec(testVolumeType.getId(), "test1", "freddy"));
|
||||||
|
assertEquals(volumeTypeOption.get().getExtraSpec(testVolumeType.getId(), "test1"), "freddy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{"volume_type": {
|
||||||
|
"name": "jclouds-test-1",
|
||||||
|
"deleted": false,
|
||||||
|
"created_at": "2012-05-10 12:33:06",
|
||||||
|
"updated_at": null,
|
||||||
|
"extra_specs": {"test": "value1", "test1": "wibble"},
|
||||||
|
"deleted_at": null,
|
||||||
|
"id": 8
|
||||||
|
}}
|
|
@ -0,0 +1 @@
|
||||||
|
{"extra_specs": {"test": "value1"}}
|
|
@ -0,0 +1 @@
|
||||||
|
{"volume_types": [{"name": "jclouds-test-1", "deleted": false, "created_at": "2012-05-10 12:33:06", "updated_at": null, "extra_specs": {"test": "value1", "test1": "wibble"}, "deleted_at": null, "id": 8}]}
|
Loading…
Reference in New Issue