mirror of https://github.com/apache/jclouds.git
added extension api to nova
This commit is contained in:
parent
67d70fae62
commit
ee4f00b645
|
@ -25,6 +25,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@ -50,6 +52,10 @@ public class Link {
|
||||||
* a permanent link to a resource that is appropriate for long term storage.
|
* a permanent link to a resource that is appropriate for long term storage.
|
||||||
*/
|
*/
|
||||||
BOOKMARK,
|
BOOKMARK,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DESCRIBEDBY,
|
||||||
/**
|
/**
|
||||||
* an alternate representation of the resource. For example, an OpenStack Compute image may
|
* an alternate representation of the resource. For example, an OpenStack Compute image may
|
||||||
* have an alternate representation in the OpenStack Image service.
|
* have an alternate representation in the OpenStack Image service.
|
||||||
|
@ -75,7 +81,11 @@ public class Link {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Link create(Relation relation, URI href) {
|
public static Link create(Relation relation, URI href) {
|
||||||
return new Link(relation, href);
|
return new Link(relation, null, href);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Link create(Relation relation,String type, URI href) {
|
||||||
|
return new Link(relation, type, href);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -88,6 +98,7 @@ public class Link {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
protected Relation relation;
|
protected Relation relation;
|
||||||
|
protected String type;
|
||||||
protected URI href;
|
protected URI href;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,25 +109,39 @@ public class Link {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Link#getType()
|
||||||
|
*/
|
||||||
|
public Builder type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Link#getHref()
|
* @see Link#getHref()
|
||||||
*/
|
*/
|
||||||
protected Builder href(URI href) {
|
public Builder href(URI href) {
|
||||||
this.href = checkNotNull(href, "href");
|
this.href = checkNotNull(href, "href");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Link build(){
|
||||||
|
return new Link(relation, type, href);
|
||||||
|
}
|
||||||
|
|
||||||
public Builder fromLink(Link from) {
|
public Builder fromLink(Link from) {
|
||||||
return relation(from.getRelation()).href(from.getHref());
|
return relation(from.getRelation()).type(from.getType()).href(from.getHref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SerializedName("rel")
|
@SerializedName("rel")
|
||||||
protected final Relation relation;
|
protected final Relation relation;
|
||||||
|
protected final String type;
|
||||||
protected final URI href;
|
protected final URI href;
|
||||||
|
|
||||||
protected Link(Relation relation, URI href) {
|
protected Link(Relation relation, @Nullable String type, URI href) {
|
||||||
this.relation = checkNotNull(relation, "relation");
|
this.relation = checkNotNull(relation, "relation");
|
||||||
|
this.type = type;
|
||||||
this.href = checkNotNull(href, "href");
|
this.href = checkNotNull(href, "href");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +160,14 @@ public class Link {
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the type of the resource or null if not specified
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the href of the resource
|
* @return the href of the resource
|
||||||
*/
|
*/
|
||||||
|
@ -149,7 +182,7 @@ public class Link {
|
||||||
}
|
}
|
||||||
if (object instanceof Link) {
|
if (object instanceof Link) {
|
||||||
final Link other = Link.class.cast(object);
|
final Link other = Link.class.cast(object);
|
||||||
return equal(relation, other.relation) && equal(href, other.href);
|
return equal(relation, other.relation) && equal(type, other.type) && equal(href, other.href);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -157,12 +190,12 @@ public class Link {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(relation, href);
|
return Objects.hashCode(relation, type, href);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toStringHelper("").add("relation", relation).add("href", href).toString();
|
return toStringHelper("").add("relation", relation).add("type", type).add("href", href).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class Resource implements Comparable<Resource> {
|
||||||
}
|
}
|
||||||
if (object instanceof Resource) {
|
if (object instanceof Resource) {
|
||||||
final Resource other = Resource.class.cast(object);
|
final Resource other = Resource.class.cast(object);
|
||||||
return equal(id, other.id) && equal(name, other.name) && equal(links, other.links);
|
return equal(getId(), other.getId()) && equal(name, other.name) && equal(links, other.links);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -140,12 +140,12 @@ public class Resource implements Comparable<Resource> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(id, name, links);
|
return Objects.hashCode(getId(), name, links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toStringHelper("").add("id", id).add("name", name).add("links", links).toString();
|
return toStringHelper("").add("id", getId()).add("name", name).add("links", links).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,7 +154,7 @@ public class Resource implements Comparable<Resource> {
|
||||||
return 1;
|
return 1;
|
||||||
if (this == that)
|
if (this == that)
|
||||||
return 0;
|
return 0;
|
||||||
return this.id.compareTo(that.id);
|
return this.getId().compareTo(that.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Link.Relation;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicates handy when working with Link Types
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LinkPredicates {
|
||||||
|
/**
|
||||||
|
* matches links of the given relation
|
||||||
|
*
|
||||||
|
* @param rel relation of the link
|
||||||
|
* @return predicate that will match links of the given rel
|
||||||
|
*/
|
||||||
|
public static Predicate<Link> relationEquals(final Relation rel) {
|
||||||
|
checkNotNull(rel, "rel must be defined");
|
||||||
|
|
||||||
|
return new Predicate<Link>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Link link) {
|
||||||
|
return rel.equals(link.getRelation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "relEquals(" + rel + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matches links of the given href
|
||||||
|
*
|
||||||
|
* @param href
|
||||||
|
* @return predicate that will match links of the given href
|
||||||
|
*/
|
||||||
|
public static Predicate<Link> hrefEquals(final URI href) {
|
||||||
|
checkNotNull(href, "href must be defined");
|
||||||
|
|
||||||
|
return new Predicate<Link>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Link link) {
|
||||||
|
return href.equals(link.getHref());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "hrefEquals(" + href + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matches links of the given type
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* ex. application/pdf
|
||||||
|
* @return predicate that will match links of the given type
|
||||||
|
*/
|
||||||
|
public static Predicate<Link> typeEquals(final String type) {
|
||||||
|
checkNotNull(type, "type must be defined");
|
||||||
|
|
||||||
|
return new Predicate<Link>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Link link) {
|
||||||
|
return type.equals(link.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "typeEquals(" + type + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.jclouds.openstack.predicates;
|
||||||
|
|
||||||
|
import static org.jclouds.openstack.predicates.LinkPredicates.hrefEquals;
|
||||||
|
import static org.jclouds.openstack.predicates.LinkPredicates.relationEquals;
|
||||||
|
import static org.jclouds.openstack.predicates.LinkPredicates.typeEquals;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Link.Relation;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "LinkPredicatesTest")
|
||||||
|
public class LinkPredicatesTest {
|
||||||
|
Link ref = Link.builder().type("application/pdf").relation(Relation.DESCRIBEDBY).href(
|
||||||
|
URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRelationEqualsWhenEqual() {
|
||||||
|
assert relationEquals(Relation.DESCRIBEDBY).apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRelationEqualsWhenNotEqual() {
|
||||||
|
assert !relationEquals(Relation.UNRECOGNIZED).apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypeEqualsWhenEqual() {
|
||||||
|
assert typeEquals("application/pdf").apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypeEqualsWhenNotEqual() {
|
||||||
|
assert !typeEquals("foo").apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHrefEqualsWhenEqual() {
|
||||||
|
assert hrefEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHrefEqualsWhenNotEqual() {
|
||||||
|
assert !hrefEquals(URI.create("foo")).apply(ref);
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
||||||
|
@ -66,6 +67,13 @@ public interface NovaAsyncClient {
|
||||||
FlavorAsyncClient getFlavorClientForRegion(
|
FlavorAsyncClient getFlavorClientForRegion(
|
||||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Extension features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
ExtensionAsyncClient getExtensionClientForRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides asynchronous access to Image features.
|
* Provides asynchronous access to Image features.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||||
|
@ -68,6 +69,13 @@ public interface NovaClient {
|
||||||
FlavorClient getFlavorClientForRegion(
|
FlavorClient getFlavorClientForRegion(
|
||||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Extension features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
ExtensionClient getExtensionClientForRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides synchronous access to Image features.
|
* Provides synchronous access to Image features.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,8 @@ import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
||||||
|
@ -59,6 +61,7 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
||||||
.put(ServerClient.class, ServerAsyncClient.class)//
|
.put(ServerClient.class, ServerAsyncClient.class)//
|
||||||
.put(FlavorClient.class, FlavorAsyncClient.class)
|
.put(FlavorClient.class, FlavorAsyncClient.class)
|
||||||
.put(ImageClient.class, ImageAsyncClient.class)
|
.put(ImageClient.class, ImageAsyncClient.class)
|
||||||
|
.put(ExtensionClient.class, ExtensionAsyncClient.class)
|
||||||
.put(FloatingIPClient.class, FloatingIPAsyncClient.class)
|
.put(FloatingIPClient.class, FloatingIPAsyncClient.class)
|
||||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)
|
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)
|
||||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)
|
.put(KeyPairClient.class, KeyPairAsyncClient.class)
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/**
|
||||||
|
* 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, Name 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.Objects.toStringHelper;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OpenStack Compute API is extensible. Extensions serve two purposes: They allow the
|
||||||
|
* introduction of new features in the API without requiring a version change and they allow the
|
||||||
|
* introduction of vendor specific niche functionality.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see <a href= "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class Extension extends Resource {
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromExtension(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends Resource.Builder {
|
||||||
|
|
||||||
|
private URI namespace;
|
||||||
|
private String alias;
|
||||||
|
private Date updated;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public Builder namespace(URI namespace) {
|
||||||
|
this.namespace = namespace;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder alias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder updated(Date updated) {
|
||||||
|
this.updated = updated;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Extension build() {
|
||||||
|
return new Extension(name, links, namespace, alias, updated, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromExtension(Extension in) {
|
||||||
|
return fromResource(in).namespace(in.getNamespace()).alias(in.getAlias()).updated(in.getUpdated())
|
||||||
|
.description(in.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder id(String id) {
|
||||||
|
return alias(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder name(String name) {
|
||||||
|
return Builder.class.cast(super.name(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder links(Set<Link> links) {
|
||||||
|
return Builder.class.cast(super.links(links));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder fromResource(Resource in) {
|
||||||
|
return Builder.class.cast(super.fromResource(in));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private URI namespace;
|
||||||
|
private String alias;
|
||||||
|
private Date updated;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
protected Extension(String name, Set<Link> links, URI namespace, String alias, Date updated,
|
||||||
|
String description) {
|
||||||
|
super(alias, name, links);
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.alias = alias;
|
||||||
|
this.updated = updated;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URI getNamespace() {
|
||||||
|
return this.namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return this.alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return this.alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdated() {
|
||||||
|
return this.updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper("").add("id", getId()).add("name", name).add("links", links).add("namespace", namespace).add(
|
||||||
|
"alias", alias).add("updated", updated).add("description", description).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* 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, Name 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.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension namespaces
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see <a href= "http://nova.openstack.org/api_ext/" />
|
||||||
|
*/
|
||||||
|
public interface ExtensionNamespaces {
|
||||||
|
public static URI KEYPAIRS = URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1");
|
||||||
|
public static URI VOLUMES = URI.create("http://docs.openstack.org/ext/volumes/api/v1.1");
|
||||||
|
public static URI SECURITY_GROUPS = URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1");
|
||||||
|
public static URI FLOATING_IPS = URI.create("http://docs.openstack.org/ext/floating_ips/api/v1.1");
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.Payload;
|
import org.jclouds.rest.annotations.Payload;
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
@ -48,6 +49,9 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
*
|
*
|
||||||
* @see FloatingIPClient
|
* @see FloatingIPClient
|
||||||
* @author Jeremy Daggett
|
* @author Jeremy Daggett
|
||||||
|
* @see ExtensionAsyncClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||||
|
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||||
* @see <a href="http://wiki.openstack.org/os_api_floating_ip"/>
|
* @see <a href="http://wiki.openstack.org/os_api_floating_ip"/>
|
||||||
*/
|
*/
|
||||||
@SkipEncoding({ '/', '=' })
|
@SkipEncoding({ '/', '=' })
|
||||||
|
|
|
@ -32,6 +32,7 @@ import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.Payload;
|
import org.jclouds.rest.annotations.Payload;
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
@ -49,6 +50,9 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
*
|
*
|
||||||
* @see KeyPairClient
|
* @see KeyPairClient
|
||||||
* @author Jeremy Daggett
|
* @author Jeremy Daggett
|
||||||
|
* @see ExtensionAsyncClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||||
|
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||||
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
||||||
*/
|
*/
|
||||||
@SkipEncoding({ '/', '=' })
|
@SkipEncoding({ '/', '=' })
|
||||||
|
|
|
@ -50,6 +50,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
*
|
*
|
||||||
* @see SecurityGroupClient
|
* @see SecurityGroupClient
|
||||||
* @author Jeremy Daggett
|
* @author Jeremy Daggett
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||||
|
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||||
* @see <a href="http://wiki.openstack.org/os-security-groups" />
|
* @see <a href="http://wiki.openstack.org/os-security-groups" />
|
||||||
*/
|
*/
|
||||||
@SkipEncoding({ '/', '=' })
|
@SkipEncoding({ '/', '=' })
|
||||||
|
|
|
@ -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.nova.v1_1.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Extensions via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see ExtensionClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||||
|
* />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
public interface ExtensionAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ExtensionClient#listExtensions
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("extensions")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/extensions")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Extension>> listExtensions();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ExtensionClient#getExtensionByAlias
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("extension")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/extensions/{alias}")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Extension> getExtensionByAlias(@PathParam("alias") String id);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Extensions via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see ExtensionClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||||
|
* />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface ExtensionClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all available extensions
|
||||||
|
*
|
||||||
|
* @return all extensions
|
||||||
|
*/
|
||||||
|
Set<Extension> listExtensions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extensions may also be queried individually by their unique alias.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* id of the extension
|
||||||
|
* @return extension or null if not found
|
||||||
|
*/
|
||||||
|
Extension getExtensionByAlias(String alias);
|
||||||
|
|
||||||
|
}
|
|
@ -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.nova.v1_1.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicates handy when working with Extensions
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ExtensionPredicates {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matches namespace of the given extension
|
||||||
|
*
|
||||||
|
* @param namespace
|
||||||
|
* ex {@code http://docs.openstack.org/ext/keypairs/api/v1.1}
|
||||||
|
* @return predicate that will match namespace of the given extension
|
||||||
|
*/
|
||||||
|
public static Predicate<Extension> namespaceEquals(final URI namespace) {
|
||||||
|
checkNotNull(namespace, "namespace must be defined");
|
||||||
|
|
||||||
|
return new Predicate<Extension>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Extension ext) {
|
||||||
|
return namespace.equals(ext.getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "namespaceEquals(" + namespace + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matches alias of the given extension
|
||||||
|
*
|
||||||
|
* @param alias
|
||||||
|
* ex. {@code os-keypairs}
|
||||||
|
* @return predicate that will alias of the given extension
|
||||||
|
*/
|
||||||
|
public static Predicate<Extension> aliasEquals(final String alias) {
|
||||||
|
checkNotNull(alias, "alias must be defined");
|
||||||
|
|
||||||
|
return new Predicate<Extension>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Extension ext) {
|
||||||
|
return alias.equals(ext.getAlias());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "aliasEquals(" + alias + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/**
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionListTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests annotation parsing of {@code ExtensionAsyncClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ExtensionClientExpectTest")
|
||||||
|
public class ExtensionClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||||
|
|
||||||
|
public void testListExtensionsWhenResponseIs2xx() throws Exception {
|
||||||
|
HttpRequest listExtensions = HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("GET")
|
||||||
|
.endpoint(
|
||||||
|
URI.create("https://compute.north.host/v1.1/3456/extensions"))
|
||||||
|
.headers(
|
||||||
|
ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(200)
|
||||||
|
.payload(payloadFromResource("/extension_list.json")).build();
|
||||||
|
|
||||||
|
NovaClient clientWhenExtensionsExist = requestsSendResponses(
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||||
|
listExtensions, listExtensionsResponse);
|
||||||
|
|
||||||
|
assertEquals(clientWhenExtensionsExist.getConfiguredRegions(),
|
||||||
|
ImmutableSet.of("North"));
|
||||||
|
|
||||||
|
assertEquals(clientWhenExtensionsExist.getExtensionClientForRegion("North")
|
||||||
|
.listExtensions().toString(), new ParseExtensionListTest().expected()
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListExtensionsWhenReponseIs404IsEmpty() throws Exception {
|
||||||
|
HttpRequest listExtensions = HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("GET")
|
||||||
|
.endpoint(
|
||||||
|
URI.create("https://compute.north.host/v1.1/3456/extensions"))
|
||||||
|
.headers(
|
||||||
|
ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(404)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
NovaClient clientWhenNoServersExist = requestsSendResponses(
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||||
|
listExtensions, listExtensionsResponse);
|
||||||
|
|
||||||
|
assertTrue(clientWhenNoServersExist.getExtensionClientForRegion("North")
|
||||||
|
.listExtensions().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: gson deserializer for Multimap
|
||||||
|
public void testGetExtensionByAliasWhenResponseIs2xx() throws Exception {
|
||||||
|
|
||||||
|
HttpRequest getExtension = HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("GET")
|
||||||
|
.endpoint(
|
||||||
|
URI.create("https://compute.north.host/v1.1/3456/extensions/RS-PIE"))
|
||||||
|
.headers(
|
||||||
|
ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(200)
|
||||||
|
.payload(payloadFromResource("/extension_details.json")).build();
|
||||||
|
|
||||||
|
NovaClient clientWhenExtensionsExist = requestsSendResponses(
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||||
|
getExtension, getExtensionResponse);
|
||||||
|
|
||||||
|
assertEquals(clientWhenExtensionsExist.getExtensionClientForRegion("North")
|
||||||
|
.getExtensionByAlias("RS-PIE").toString(),
|
||||||
|
new ParseExtensionTest().expected().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetExtensionByAliasWhenResponseIs404() throws Exception {
|
||||||
|
HttpRequest getExtension = HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("GET")
|
||||||
|
.endpoint(
|
||||||
|
URI.create("https://compute.north.host/v1.1/3456/extensions/RS-PIE"))
|
||||||
|
.headers(
|
||||||
|
ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(404)
|
||||||
|
.payload(payloadFromResource("/extension_details.json")).build();
|
||||||
|
|
||||||
|
NovaClient clientWhenNoExtensionsExist = requestsSendResponses(
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||||
|
getExtension, getExtensionResponse);
|
||||||
|
|
||||||
|
assertNull(clientWhenNoExtensionsExist.getExtensionClientForRegion("North").getExtensionByAlias("RS-PIE"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.nova.v1_1.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ExtensionClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "ExtensionClientLiveTest")
|
||||||
|
public class ExtensionClientLiveTest extends BaseNovaClientLiveTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the listing of Extensions (getExtension() is tested too!)
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testListExtensions() throws Exception {
|
||||||
|
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||||
|
ExtensionClient client = context.getApi().getExtensionClientForRegion(regionId);
|
||||||
|
Set<Extension> response = client.listExtensions();
|
||||||
|
assert null != response;
|
||||||
|
assertTrue(response.size() >= 0);
|
||||||
|
for (Extension extension : response) {
|
||||||
|
Extension newDetails = client.getExtensionByAlias(extension.getId());
|
||||||
|
assertEquals(newDetails.getId(), extension.getId());
|
||||||
|
assertEquals(newDetails.getName(), extension.getName());
|
||||||
|
assertEquals(newDetails.getDescription(), extension.getDescription());
|
||||||
|
assertEquals(newDetails.getNamespace(), extension.getNamespace());
|
||||||
|
assertEquals(newDetails.getUpdated(), extension.getUpdated());
|
||||||
|
assertEquals(newDetails.getLinks(), extension.getLinks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.parse;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.json.BaseSetParserTest;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ParseExtensionListNormalTest")
|
||||||
|
public class ParseExtensionListNormalTest extends BaseSetParserTest<Extension> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/extension_list_normal.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("extensions")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Set<Extension> expected() {
|
||||||
|
return ImmutableSet
|
||||||
|
.of(Extension
|
||||||
|
.builder()
|
||||||
|
.alias("os-keypairs")
|
||||||
|
.name("Keypairs")
|
||||||
|
.namespace(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-08-08T00:00:00+00:00"))
|
||||||
|
.description("Keypair Support")
|
||||||
|
.build(),
|
||||||
|
Extension
|
||||||
|
.builder()
|
||||||
|
.alias("os-volumes")
|
||||||
|
.name("Volumes")
|
||||||
|
.namespace(URI.create("http://docs.openstack.org/ext/volumes/api/v1.1"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-03-25T00:00:00+00:00"))
|
||||||
|
.description("Volumes support")
|
||||||
|
.build(),
|
||||||
|
Extension
|
||||||
|
.builder()
|
||||||
|
.alias("security_groups")
|
||||||
|
.name("SecurityGroups")
|
||||||
|
.namespace(URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-07-21T00:00:00+00:00"))
|
||||||
|
.description("Security group support")
|
||||||
|
.build(),
|
||||||
|
Extension
|
||||||
|
.builder()
|
||||||
|
.alias("os-floating-ips")
|
||||||
|
.name("Floating_ips")
|
||||||
|
.namespace(URI.create("http://docs.openstack.org/ext/floating_ips/api/v1.1"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-06-16T00:00:00+00:00"))
|
||||||
|
.description("Floating IPs support")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.json.BaseSetParserTest;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Link.Relation;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ParseExtensionListTest")
|
||||||
|
public class ParseExtensionListTest extends BaseSetParserTest<Extension> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/extension_list.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("extensions")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Set<Extension> expected() {
|
||||||
|
return ImmutableSet
|
||||||
|
.of(Extension
|
||||||
|
.builder()
|
||||||
|
.alias("RAX-PIE")
|
||||||
|
.name("Public Image Extension")
|
||||||
|
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-01-22T13:25:27-06:00"))
|
||||||
|
.description("Adds the capability to share an image with other users.")
|
||||||
|
.links(
|
||||||
|
ImmutableSet.of(
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/pdf",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf")),
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/vnd.sun.wadl+xml",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"))))
|
||||||
|
.build(),
|
||||||
|
Extension
|
||||||
|
.builder()
|
||||||
|
.alias("RAX-CBS")
|
||||||
|
.name("Cloud Block Storage")
|
||||||
|
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/cbs/v1.0"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-01-12T11:22:33-06:00"))
|
||||||
|
.description("Allows mounting cloud block storage volumes.")
|
||||||
|
.links(
|
||||||
|
ImmutableSet.of(
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/pdf",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-cbs-20111201.pdf")),
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/vnd.sun.wadl+xml",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-cbs.wadl"))))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Link.Relation;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ParseExtensionTest")
|
||||||
|
public class ParseExtensionTest extends BaseItemParserTest<Extension> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/extension_details.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("extension")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Extension expected() {
|
||||||
|
return Extension
|
||||||
|
.builder()
|
||||||
|
.alias("RS-PIE")
|
||||||
|
.name("Public Image Extension")
|
||||||
|
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0"))
|
||||||
|
.updated(
|
||||||
|
new SimpleDateFormatDateService()
|
||||||
|
.iso8601SecondsDateParse("2011-01-22T13:25:27-06:00"))
|
||||||
|
.description("Adds the capability to share an image with other users.")
|
||||||
|
.links(
|
||||||
|
ImmutableSet.of(
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/pdf",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf")),
|
||||||
|
Link.create(
|
||||||
|
Relation.DESCRIBEDBY,
|
||||||
|
"application/vnd.sun.wadl+xml",
|
||||||
|
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"))))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* 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.predicates;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import static org.jclouds.openstack.nova.v1_1.predicates.ExtensionPredicates.*;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ExtensionPredicatesTest")
|
||||||
|
public class ExtensionPredicatesTest {
|
||||||
|
Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs").namespace(
|
||||||
|
URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).updated(
|
||||||
|
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
|
||||||
|
"Keypair Support").build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasEqualsWhenEqual() {
|
||||||
|
assert aliasEquals("os-keypairs").apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasEqualsWhenNotEqual() {
|
||||||
|
assert !aliasEquals("foo").apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNamespaceEqualsWhenEqual() {
|
||||||
|
assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNamespaceEqualsWhenNotEqual() {
|
||||||
|
assert !namespaceEquals(URI.create("foo")).apply(ref);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"extension" : {
|
||||||
|
"name" : "Public Image Extension",
|
||||||
|
"namespace" : "http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0",
|
||||||
|
"alias" : "RS-PIE",
|
||||||
|
"updated" : "2011-01-22T13:25:27-06:00",
|
||||||
|
"description" : "Adds the capability to share an image with other users.",
|
||||||
|
"links" : [
|
||||||
|
{
|
||||||
|
"rel" : "describedby",
|
||||||
|
"type" : "application/pdf",
|
||||||
|
"href" : "http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel" : "describedby",
|
||||||
|
"type" : "application/vnd.sun.wadl+xml",
|
||||||
|
"href" : "http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"extensions": [
|
||||||
|
{
|
||||||
|
"name": "Public Image Extension",
|
||||||
|
"namespace": "http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0",
|
||||||
|
"alias": "RAX-PIE",
|
||||||
|
"updated": "2011-01-22T13:25:27-06:00",
|
||||||
|
"description": "Adds the capability to share an image with other users.",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application/pdf",
|
||||||
|
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application/vnd.sun.wadl+xml",
|
||||||
|
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cloud Block Storage",
|
||||||
|
"namespace": "http://docs.rackspacecloud.com/servers/api/ext/cbs/v1.0",
|
||||||
|
"alias": "RAX-CBS",
|
||||||
|
"updated": "2011-01-12T11:22:33-06:00",
|
||||||
|
"description": "Allows mounting cloud block storage volumes.",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application/pdf",
|
||||||
|
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-cbs-20111201.pdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application/vnd.sun.wadl+xml",
|
||||||
|
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-cbs.wadl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"extensions": [{
|
||||||
|
"updated": "2011-08-08T00:00:00+00:00",
|
||||||
|
"name": "Keypairs",
|
||||||
|
"links": [],
|
||||||
|
"namespace": "http://docs.openstack.org/ext/keypairs/api/v1.1",
|
||||||
|
"alias": "os-keypairs",
|
||||||
|
"description": "Keypair Support"
|
||||||
|
}, {
|
||||||
|
"updated": "2011-03-25T00:00:00+00:00",
|
||||||
|
"name": "Volumes",
|
||||||
|
"links": [],
|
||||||
|
"namespace": "http://docs.openstack.org/ext/volumes/api/v1.1",
|
||||||
|
"alias": "os-volumes",
|
||||||
|
"description": "Volumes support"
|
||||||
|
}, {
|
||||||
|
"updated": "2011-07-21T00:00:00+00:00",
|
||||||
|
"name": "SecurityGroups",
|
||||||
|
"links": [],
|
||||||
|
"namespace": "http://docs.openstack.org/ext/securitygroups/api/v1.1",
|
||||||
|
"alias": "security_groups",
|
||||||
|
"description": "Security group support"
|
||||||
|
}, {
|
||||||
|
"updated": "2011-06-16T00:00:00+00:00",
|
||||||
|
"name": "Floating_ips",
|
||||||
|
"links": [],
|
||||||
|
"namespace": "http://docs.openstack.org/ext/floating_ips/api/v1.1",
|
||||||
|
"alias": "os-floating-ips",
|
||||||
|
"description": "Floating IPs support"
|
||||||
|
}]
|
||||||
|
}
|
Loading…
Reference in New Issue