mirror of https://github.com/apache/jclouds.git
pagination and consistency cleanup on openstack
This commit is contained in:
parent
dcca748a79
commit
b5f60f1e70
|
@ -21,8 +21,6 @@ package org.jclouds.openstack.keystone.v2_0;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.functions.ZoneToEndpoint;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
|
||||
|
@ -30,7 +28,6 @@ import org.jclouds.openstack.keystone.v2_0.features.TokenApi;
|
|||
import org.jclouds.openstack.keystone.v2_0.features.UserApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
|
|||
.build(CacheLoader.from(Suppliers.memoize(new Supplier<Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> get() {
|
||||
return keystoneApi.get().getExtensionApi().listExtensions();
|
||||
return keystoneApi.get().getExtensionApi().list();
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.beans.ConstructorProperties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -105,10 +107,10 @@ public class Access implements Comparable<Access> {
|
|||
@ConstructorProperties({
|
||||
"token", "user", "serviceCatalog"
|
||||
})
|
||||
protected Access(Token token, User user, Set<Service> serviceCatalog) {
|
||||
protected Access(Token token, User user, @Nullable Set<Service> serviceCatalog) {
|
||||
this.token = checkNotNull(token, "token");
|
||||
this.user = checkNotNull(user, "user");
|
||||
this.serviceCatalog = ImmutableSet.copyOf(checkNotNull(serviceCatalog, "serviceCatalog"));
|
||||
this.serviceCatalog = serviceCatalog == null ? ImmutableSet.<Service>of() : ImmutableSet.copyOf(serviceCatalog);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.keystone.v2_0.domain;
|
||||
|
||||
import static org.jclouds.http.utils.Queries.parseQueryToMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* base class for a paginated collection in openstack
|
||||
*
|
||||
* @see <a
|
||||
* href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html">
|
||||
* docs</a>
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
public class PaginatedCollection<T> extends IterableWithMarker<T> {
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static final PaginatedCollection EMPTY = new PaginatedCollection(ImmutableSet.of(), ImmutableSet.of());
|
||||
|
||||
private Iterable<T> resources;
|
||||
private Iterable<Link> links;
|
||||
|
||||
protected PaginatedCollection(Iterable<T> resources, Iterable<Link> links) {
|
||||
this.resources = resources != null ? resources : ImmutableSet.<T> of();
|
||||
this.links = links != null ? links : ImmutableSet.<Link> of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return resources.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* links that relate to this collection
|
||||
*/
|
||||
public Iterable<Link> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> nextMarker() {
|
||||
return FluentIterable.from(getLinks()).filter(new Predicate<Link>() {
|
||||
@Override
|
||||
public boolean apply(Link link) {
|
||||
return Link.Relation.NEXT == link.getRelation();
|
||||
}
|
||||
}).transform(new Function<Link, Optional<Object>>() {
|
||||
@Override
|
||||
public Optional<Object> apply(Link link) {
|
||||
Collection<String> markers = parseQueryToMap(link.getHref().getRawQuery()).get("marker");
|
||||
return Optional.<Object> fromNullable(markers == null ? null : Iterables.get(markers, 0));
|
||||
}
|
||||
}).first().or(Optional.absent());
|
||||
}
|
||||
|
||||
}
|
|
@ -18,11 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.openstack.keystone.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to the KeyStone Tenant API.
|
||||
|
@ -40,7 +42,9 @@ public interface TenantApi {
|
|||
/**
|
||||
* The operation returns a list of tenants which the current token provides access to.
|
||||
*/
|
||||
Set<? extends Tenant> list();
|
||||
PagedIterable<? extends Tenant> list();
|
||||
|
||||
PaginatedCollection<? extends Tenant> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* Retrieve information about a tenant, by tenant ID
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.keystone.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -27,14 +25,22 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants.ToPagedIterable;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.openstack.v2_0.services.Identity;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -57,12 +63,22 @@ public interface TenantAsyncApi {
|
|||
* @see TenantApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("tenants")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/tenants")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Tenant>> list();
|
||||
@ResponseParser(ParseTenants.class)
|
||||
@Transform(ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Tenant>> list();
|
||||
|
||||
/** @see TenantApi#list(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/tenants")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseTenants.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Tenant>> list(PaginationOptions options);
|
||||
|
||||
/** @see TenantApi#get(String) */
|
||||
@GET
|
||||
|
|
|
@ -21,9 +21,12 @@ package org.jclouds.openstack.keystone.v2_0.features;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
|
@ -48,7 +51,9 @@ public interface UserApi {
|
|||
*
|
||||
* @return the list of users
|
||||
*/
|
||||
Set<? extends User> list();
|
||||
PagedIterable<? extends User> list();
|
||||
|
||||
PaginatedCollection<? extends User> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* Retrieve information about a user, by user ID
|
||||
|
|
|
@ -27,14 +27,23 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers.ToPagedIterable;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.openstack.v2_0.services.Identity;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
|
@ -43,10 +52,10 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
/**
|
||||
* Provides asynchronous access to User via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
*
|
||||
* @see UserApi
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
|
||||
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
|
||||
* />
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
|
@ -54,14 +63,26 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
@SkipEncoding({ '/', '=' })
|
||||
public interface UserAsyncApi {
|
||||
|
||||
/** @see UserApi#list() */
|
||||
/**
|
||||
* @see UserApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("users")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/users")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends User>> list();
|
||||
@ResponseParser(ParseUsers.class)
|
||||
@Transform(ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends User>> list();
|
||||
|
||||
/** @see UserApi#list(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/users")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseUsers.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends User>> list(PaginationOptions options);
|
||||
|
||||
/** @see UserApi#get(String) */
|
||||
@GET
|
||||
|
@ -71,7 +92,7 @@ public interface UserAsyncApi {
|
|||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends User> get(@PathParam("userId") String userId);
|
||||
|
||||
|
||||
/** @see UserApi#getByName(String) */
|
||||
@GET
|
||||
@SelectJson("user")
|
||||
|
@ -80,7 +101,7 @@ public interface UserAsyncApi {
|
|||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends User> getByName(@QueryParam("name") String userName);
|
||||
|
||||
|
||||
/** @see UserApi#listRolesOfUser(String) */
|
||||
@GET
|
||||
@SelectJson("roles")
|
||||
|
@ -97,5 +118,6 @@ public interface UserAsyncApi {
|
|||
@Path("/tenants/{tenantId}/users/{userId}/roles")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
|
||||
ListenableFuture<? extends Set<? extends Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId,
|
||||
@PathParam("tenantId") String tenantId);
|
||||
}
|
||||
|
|
|
@ -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.keystone.v2_0.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ReturnEmptyPaginatedCollectionOnNotFoundOr404 implements Function<Exception, Object> {
|
||||
private final ReturnTrueOn404 rto404;
|
||||
|
||||
@Inject
|
||||
private ReturnEmptyPaginatedCollectionOnNotFoundOr404(ReturnTrueOn404 rto404) {
|
||||
this.rto404 = checkNotNull(rto404, "rto404");
|
||||
}
|
||||
|
||||
public Object apply(Exception from) {
|
||||
Iterable<ResourceNotFoundException> throwables = Iterables.filter(Throwables.getCausalChain(from),
|
||||
ResourceNotFoundException.class);
|
||||
if (Iterables.size(throwables) >= 1) {
|
||||
return PaginatedCollection.EMPTY;
|
||||
} else if (rto404.apply(from)) {
|
||||
return PaginatedCollection.EMPTY;
|
||||
}
|
||||
throw Throwables.propagate(from);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.keystone.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants.Tenants;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseTenants extends ParseJson<Tenants<? extends Tenant>> {
|
||||
static class Tenants<T extends Tenant> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "tenants", "tenants_links" })
|
||||
protected Tenants(Iterable<T> tenants, Iterable<Link> tenants_links) {
|
||||
super(tenants, tenants_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseTenants(Json json) {
|
||||
super(json, new TypeLiteral<Tenants<? extends Tenant>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Tenant, ToPagedIterable> {
|
||||
|
||||
private final KeystoneApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(KeystoneApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Tenant>> markerToNextForCallingArg0(final String ignored) {
|
||||
final TenantApi tenantApi = api.getTenantApi().get();
|
||||
return new Function<Object, IterableWithMarker<Tenant>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Tenant> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(tenantApi.list(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listTenants()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.keystone.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.UserApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers.Users;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseUsers extends ParseJson<Users<? extends User>> {
|
||||
static class Users<T extends User> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "users", "users_links" })
|
||||
protected Users(Iterable<T> users, Iterable<Link> users_links) {
|
||||
super(users, users_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseUsers(Json json) {
|
||||
super(json, new TypeLiteral<Users<? extends User>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<User, ToPagedIterable> {
|
||||
|
||||
private final KeystoneApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(KeystoneApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<User>> markerToNextForCallingArg0(final String ignored) {
|
||||
final UserApi userApi = api.getUserApi().get();
|
||||
return new Function<Object, IterableWithMarker<User>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<User> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(userApi.list(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listUsers()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -25,18 +25,17 @@ import java.net.URI;
|
|||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* For convenience, resources contain links to themselves. This allows a api to easily obtain a
|
||||
* resource URIs rather than to construct them.
|
||||
*
|
||||
*
|
||||
* @author AdrianCole
|
||||
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/LinksReferences.html"
|
||||
/>
|
||||
* />
|
||||
*/
|
||||
public class Link {
|
||||
/**
|
||||
|
@ -57,9 +56,17 @@ public class Link {
|
|||
*/
|
||||
DESCRIBEDBY,
|
||||
/**
|
||||
* an alternate representation of the resource. For example, an OpenStack Compute image may
|
||||
* have an alternate representation in the OpenStack Image service.
|
||||
* Indicates that the link's context is a part of a series, and that the next in the series is
|
||||
* the link target.
|
||||
*/
|
||||
NEXT,
|
||||
|
||||
/**
|
||||
* Indicates that the link's context is a part of a series, and that the previous in the
|
||||
* series is the link target.
|
||||
*/
|
||||
PREVIOUS,
|
||||
|
||||
ALTERNATE,
|
||||
/**
|
||||
* the value returned by the OpenStack service was not recognized.
|
||||
|
@ -83,80 +90,67 @@ public class Link {
|
|||
return new Link(relation, null, href);
|
||||
}
|
||||
|
||||
public static Link create(Relation relation,String type, URI href) {
|
||||
return new Link(relation, type, href);
|
||||
public static Link create(Relation relation, String type, URI href) {
|
||||
return new Link(relation, Optional.fromNullable(type), href);
|
||||
}
|
||||
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder<?> toBuilder() {
|
||||
return new ConcreteBuilder().fromLink(this);
|
||||
public Builder toBuilder() {
|
||||
return builder().fromLink(this);
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends Builder<T>> {
|
||||
protected abstract T self();
|
||||
public static class Builder {
|
||||
|
||||
protected Link.Relation relation;
|
||||
protected String type;
|
||||
protected Optional<String> type = Optional.absent();
|
||||
protected URI href;
|
||||
|
||||
/**
|
||||
* @see Link#getRelation()
|
||||
*/
|
||||
public T relation(Link.Relation relation) {
|
||||
public Builder relation(Link.Relation relation) {
|
||||
this.relation = relation;
|
||||
return self();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Link#getType()
|
||||
*/
|
||||
public T type(String type) {
|
||||
this.type = type;
|
||||
return self();
|
||||
public Builder type(String type) {
|
||||
this.type = Optional.fromNullable(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Link#getHref()
|
||||
*/
|
||||
public T href(URI href) {
|
||||
public Builder href(URI href) {
|
||||
this.href = href;
|
||||
return self();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Link build() {
|
||||
return new Link(relation, type, href);
|
||||
}
|
||||
|
||||
public T fromLink(Link in) {
|
||||
return this
|
||||
.relation(in.getRelation())
|
||||
.type(in.getType())
|
||||
.href(in.getHref());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
||||
@Override
|
||||
protected ConcreteBuilder self() {
|
||||
return this;
|
||||
public Builder fromLink(Link in) {
|
||||
return this.relation(in.getRelation()).type(in.getType().orNull()).href(in.getHref());
|
||||
}
|
||||
}
|
||||
|
||||
@Named("rel")
|
||||
private final Link.Relation relation;
|
||||
private final String type;
|
||||
private final Optional<String> type;
|
||||
private final URI href;
|
||||
|
||||
@ConstructorProperties({
|
||||
"rel", "type", "href"
|
||||
})
|
||||
protected Link(Link.Relation relation, @Nullable String type, URI href) {
|
||||
this.relation = checkNotNull(relation, "relation");
|
||||
this.type = type;
|
||||
@ConstructorProperties({ "rel", "type", "href" })
|
||||
protected Link(Link.Relation relation, Optional<String> type, URI href) {
|
||||
this.href = checkNotNull(href, "href");
|
||||
this.relation = checkNotNull(relation, "relation of %s", href);
|
||||
this.type = (type == null) ? Optional.<String> absent() : type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,7 +161,7 @@ public class Link {
|
|||
* of the resource. For example, an OpenStack Compute image may have an alternate representation
|
||||
* in the OpenStack Image service. Note that the type attribute here is used to provide a hint as
|
||||
* to the type of representation to expect when following the link.
|
||||
*
|
||||
*
|
||||
* @return the relation of the resource in the current OpenStack deployment
|
||||
*/
|
||||
public Link.Relation getRelation() {
|
||||
|
@ -177,8 +171,7 @@ public class Link {
|
|||
/**
|
||||
* @return the type of the resource or null if not specified
|
||||
*/
|
||||
@Nullable
|
||||
public String getType() {
|
||||
public Optional<String> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
|
@ -196,17 +189,18 @@ public class Link {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
Link that = Link.class.cast(obj);
|
||||
return Objects.equal(this.relation, that.relation)
|
||||
&& Objects.equal(this.type, that.type)
|
||||
&& Objects.equal(this.href, that.href);
|
||||
return Objects.equal(this.relation, that.relation) && Objects.equal(this.type, that.type)
|
||||
&& Objects.equal(this.href, that.href);
|
||||
}
|
||||
|
||||
protected ToStringHelper string() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("relation", relation).add("type", type).add("href", href);
|
||||
return Objects.toStringHelper(this).omitNullValues().add("relation", relation).add("type", type.orNull())
|
||||
.add("href", href);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.jclouds.openstack.v2_0.domain.Extension;
|
|||
* Provides asynchronous access to Extensions via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ExtensionApi
|
||||
* @see ExtensionAsyncApi
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
|
@ -42,7 +42,7 @@ public interface ExtensionApi {
|
|||
*
|
||||
* @return all extensions
|
||||
*/
|
||||
Set<? extends Extension> listExtensions();
|
||||
Set<? extends Extension> list();
|
||||
|
||||
/**
|
||||
* Extensions may also be queried individually by their unique alias.
|
||||
|
@ -51,6 +51,6 @@ public interface ExtensionApi {
|
|||
* id of the extension
|
||||
* @return extension or null if not found
|
||||
*/
|
||||
Extension getExtensionByAlias(String alias);
|
||||
Extension get(String alias);
|
||||
|
||||
}
|
||||
|
|
|
@ -52,23 +52,23 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface ExtensionAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ExtensionApi#listExtensions
|
||||
* @see ExtensionApi#list
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extensions")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/extensions")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Extension>> listExtensions();
|
||||
ListenableFuture<? extends Set<? extends Extension>> list();
|
||||
|
||||
/**
|
||||
* @see ExtensionApi#getExtensionByAlias
|
||||
* @see ExtensionApi#get
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extension")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/extensions/{alias}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Extension> getExtensionByAlias(@PathParam("alias") String id);
|
||||
ListenableFuture<? extends Extension> get(@PathParam("alias") String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -28,30 +28,26 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
|||
/**
|
||||
* Options used to control paginated results (aka list commands).
|
||||
*
|
||||
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/Paginated_Collections-d1e664.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseListOptions extends BaseHttpRequestOptions {
|
||||
public static final BaseListOptions NONE = new BaseListOptions();
|
||||
|
||||
public class PaginationOptions extends BaseHttpRequestOptions {
|
||||
/**
|
||||
* Only return objects changed since this time.
|
||||
*/
|
||||
public BaseListOptions changesSince(Date ifModifiedSince) {
|
||||
this.queryParameters.put("changes-since", checkNotNull(ifModifiedSince, "ifModifiedSince")
|
||||
.getTime()
|
||||
/ 1000 + "");
|
||||
public PaginationOptions changesSince(Date ifModifiedSince) {
|
||||
this.queryParameters.put("changes-since", checkNotNull(ifModifiedSince, "ifModifiedSince").getTime() / 1000 + "");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates where to begin listing. The list will only include objects that occur after the
|
||||
* offset. This is convenient for pagination: To get the next page of results use the last result
|
||||
* number of the current page + current page offset as the offset.
|
||||
* The marker parameter is the ID of the last item in the previous list. Items are sorted by
|
||||
* create time in descending order. When a create time is not available they are sorted by ID.
|
||||
*/
|
||||
public BaseListOptions startAt(long offset) {
|
||||
checkState(offset >= 0, "offset must be >= 0");
|
||||
queryParameters.put("offset", Long.toString(checkNotNull(offset, "offset")));
|
||||
public PaginationOptions marker(String marker) {
|
||||
queryParameters.put("marker", checkNotNull(marker, "marker"));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -63,7 +59,7 @@ public class BaseListOptions extends BaseHttpRequestOptions {
|
|||
* <p/>
|
||||
* Note that list operations never return itemNotFound (404) faults.
|
||||
*/
|
||||
public BaseListOptions maxResults(int limit) {
|
||||
public PaginationOptions limit(int limit) {
|
||||
checkState(limit >= 0, "limit must be >= 0");
|
||||
checkState(limit <= 10000, "limit must be <= 10000");
|
||||
queryParameters.put("limit", Integer.toString(limit));
|
||||
|
@ -73,26 +69,26 @@ public class BaseListOptions extends BaseHttpRequestOptions {
|
|||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#startAt(long)
|
||||
* @see PaginationOptions#marker(String)
|
||||
*/
|
||||
public static BaseListOptions startAt(long prefix) {
|
||||
BaseListOptions options = new BaseListOptions();
|
||||
return options.startAt(prefix);
|
||||
public static PaginationOptions marker(String marker) {
|
||||
PaginationOptions options = new PaginationOptions();
|
||||
return options.marker(marker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#maxResults
|
||||
* @see PaginationOptions#limit
|
||||
*/
|
||||
public static BaseListOptions maxResults(int maxKeys) {
|
||||
BaseListOptions options = new BaseListOptions();
|
||||
return options.maxResults(maxKeys);
|
||||
public static PaginationOptions limit(int limit) {
|
||||
PaginationOptions options = new PaginationOptions();
|
||||
return options.limit(limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#changesSince(Date)
|
||||
* @see PaginationOptions#changesSince(Date)
|
||||
*/
|
||||
public static BaseListOptions changesSince(Date since) {
|
||||
BaseListOptions options = new BaseListOptions();
|
||||
public static PaginationOptions changesSince(Date since) {
|
||||
PaginationOptions options = new PaginationOptions();
|
||||
return options.changesSince(since);
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ public class LinkPredicates {
|
|||
return new Predicate<Link>() {
|
||||
@Override
|
||||
public boolean apply(Link link) {
|
||||
return type.equals(link.getType());
|
||||
return type.equals(link.getType().orNull());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jclouds.http.HttpResponse;
|
|||
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -47,7 +48,10 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
|
|||
public TenantApiExpectTest(){
|
||||
endpoint = "https://csnode.jclouds.org:35357";
|
||||
}
|
||||
|
||||
|
||||
Set<Tenant> expectedTenants = ImmutableSet.of(Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0")
|
||||
.build(), Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build());
|
||||
|
||||
public void testListTenants() {
|
||||
TenantApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword,
|
||||
|
@ -56,16 +60,28 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
|
|||
HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
||||
.getTenantApi().get();
|
||||
Set<? extends Tenant> tenants = api.list();
|
||||
|
||||
assertEquals(api.list().concat().toImmutableSet(), expectedTenants);
|
||||
}
|
||||
|
||||
public void testListTenantsPage() {
|
||||
TenantApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword,
|
||||
responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/tenants").build(),
|
||||
HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
||||
.getTenantApi().get();
|
||||
Set<? extends Tenant> tenants = api.list(new PaginationOptions()).toImmutableSet();
|
||||
assertNotNull(tenants);
|
||||
assertFalse(tenants.isEmpty());
|
||||
|
||||
Set<Tenant> expected = ImmutableSet.of(Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0")
|
||||
.build(), Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build());
|
||||
|
||||
assertEquals(tenants, expected);
|
||||
assertEquals(tenants, expectedTenants);
|
||||
}
|
||||
|
||||
// this is not a compatible format of json per:
|
||||
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html
|
||||
@Test(enabled = false)
|
||||
public void testListTenantsATT() {
|
||||
TenantApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword,
|
||||
|
@ -74,15 +90,15 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
|
|||
HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResourceWithContentType("/tenant_list_att.json", APPLICATION_JSON)).build())
|
||||
.getTenantApi().get();
|
||||
Set<? extends Tenant> tenants = api.list();
|
||||
assertNotNull(tenants);
|
||||
assertFalse(tenants.isEmpty());
|
||||
|
||||
Set<Tenant> expected = ImmutableSet.of(Tenant.builder().name("this-is-a-test").id("14").description("None").build());
|
||||
|
||||
assertEquals(tenants, expected);
|
||||
assertEquals(api.list().concat().toImmutableSet(), expected);
|
||||
}
|
||||
|
||||
// this is not a compatible format of json per:
|
||||
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Paginated_Collections-d1e325.html
|
||||
@Test(enabled = false)
|
||||
public void testListTenantsFailNotFound() {
|
||||
TenantApi api = requestsSendResponses(keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/tenants").build(), HttpResponse.builder().statusCode(404).build())
|
||||
|
|
|
@ -38,7 +38,7 @@ public class TenantApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
|
||||
public void testTenants() {
|
||||
TenantApi api = keystoneContext.getApi().getTenantApi().get();
|
||||
Set<? extends Tenant> result = api.list();
|
||||
Set<? extends Tenant> result = api.list().concat().toImmutableSet();
|
||||
assertNotNull(result);
|
||||
assertFalse(result.isEmpty());
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class TenantApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
|
||||
TenantApi api = keystoneContext.getApi().getTenantApi().get();
|
||||
|
||||
for (Tenant tenant : api.list()) {
|
||||
for (Tenant tenant : api.list().concat()) {
|
||||
Tenant aTenant = api.getByName(tenant.getName());
|
||||
assertNotNull(aTenant, "get returned null for tenant: " + tenant);
|
||||
|
||||
|
|
|
@ -30,9 +30,11 @@ import java.util.Set;
|
|||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -43,31 +45,50 @@ import com.google.common.collect.ImmutableSet;
|
|||
*
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Test(testName = "UserApiExpectTest")
|
||||
@Test(singleThreaded = true, testName = "UserApiExpectTest")
|
||||
public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi> {
|
||||
|
||||
public UserApiExpectTest(){
|
||||
endpoint = "https://csnode.jclouds.org:35357";
|
||||
}
|
||||
|
||||
|
||||
Set<User> expectedUsers = ImmutableSet.of(
|
||||
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
|
||||
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
|
||||
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
|
||||
);
|
||||
|
||||
public void testListUsers() {
|
||||
UserApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
|
||||
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
|
||||
.getUserApi().get();
|
||||
Set<? extends User> users = api.list();
|
||||
|
||||
assertEquals(api.list().concat().toImmutableSet(), expectedUsers);
|
||||
}
|
||||
|
||||
public void testListUsersPage() {
|
||||
UserApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
|
||||
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
|
||||
.getUserApi().get();
|
||||
PaginatedCollection<? extends User> users = api.list(new PaginationOptions());
|
||||
assertNotNull(users);
|
||||
assertFalse(users.isEmpty());
|
||||
|
||||
Set<User> expected = ImmutableSet.of(
|
||||
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
|
||||
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
|
||||
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
|
||||
);
|
||||
|
||||
assertEquals(users, expected);
|
||||
assertEquals(users.toImmutableSet(), expectedUsers);
|
||||
}
|
||||
|
||||
public void testListUsersNotFound() {
|
||||
UserApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
|
||||
HttpResponse.builder().statusCode(404).build()).getUserApi().get();
|
||||
assertEquals( api.list(new PaginationOptions()).size(), 0);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AuthorizationException.class)
|
||||
|
@ -76,7 +97,7 @@ public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi
|
|||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
|
||||
HttpResponse.builder().statusCode(401).build()).getUserApi().get();
|
||||
api.list();
|
||||
api.list(new PaginationOptions());
|
||||
}
|
||||
|
||||
public void testGetUser() {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
public void testUsers() {
|
||||
|
||||
UserApi api = keystoneContext.getApi().getUserApi().get();
|
||||
Set<? extends User> users = api.list();
|
||||
Set<? extends User> users = api.list().concat().toImmutableSet();
|
||||
assertNotNull(users);
|
||||
assertFalse(users.isEmpty());
|
||||
for (User user : users) {
|
||||
|
@ -54,10 +54,9 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
public void testUserRolesOnTenant() {
|
||||
|
||||
UserApi api = keystoneContext.getApi().getUserApi().get();
|
||||
Set<? extends User> users = api.list();
|
||||
Set<? extends Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list();
|
||||
Set<? extends Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list().concat().toImmutableSet();
|
||||
|
||||
for (User user : users) {
|
||||
for (User user : api.list().concat()) {
|
||||
for (Tenant tenant : tenants) {
|
||||
Set<? extends Role> roles = api.listRolesOfUserOnTenant(user.getId(), tenant.getId());
|
||||
for (Role role : roles) {
|
||||
|
@ -71,7 +70,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
public void testListRolesOfUser() {
|
||||
|
||||
UserApi api = keystoneContext.getApi().getUserApi().get();
|
||||
for (User user : api.list()) {
|
||||
for (User user : api.list().concat()) {
|
||||
Set<? extends Role> roles = api.listRolesOfUser(user.getId());
|
||||
for (Role role : roles) {
|
||||
assertNotNull(role.getId());
|
||||
|
@ -83,7 +82,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
|
|||
public void testUsersByName() {
|
||||
|
||||
UserApi api = keystoneContext.getApi().getUserApi().get();
|
||||
for (User user : api.list()) {
|
||||
for (User user : api.list().concat()) {
|
||||
User aUser = api.getByName(user.getName());
|
||||
assertEquals(aUser, user);
|
||||
}
|
||||
|
|
|
@ -5,13 +5,10 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.openstack.v2_0.options;
|
||||
|
||||
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.changesSince;
|
||||
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.maxResults;
|
||||
import static org.jclouds.openstack.v2_0.options.BaseListOptions.Builder.startAt;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.changesSince;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.limit;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -34,44 +34,44 @@ import com.google.common.collect.ImmutableList;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class BaseListOptionsTest {
|
||||
@Test(groups = "unit", testName = "PaginationOptionsTest")
|
||||
public class PaginationOptionsTest {
|
||||
|
||||
public void testChangesSince() {
|
||||
Date ifModifiedSince = new Date();
|
||||
BaseListOptions options = new BaseListOptions().changesSince(ifModifiedSince);
|
||||
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
|
||||
.buildQueryParameters().get("changes-since"));
|
||||
PaginationOptions options = new PaginationOptions().changesSince(ifModifiedSince);
|
||||
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""),
|
||||
options.buildQueryParameters().get("changes-since"));
|
||||
}
|
||||
|
||||
public void testStartAt() {
|
||||
long offset = 1;
|
||||
BaseListOptions options = new BaseListOptions().startAt(offset);
|
||||
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||
public void testMarker() {
|
||||
String marker = "52415800-8b69-11e0-9b19-734f6f006e54";
|
||||
PaginationOptions options = new PaginationOptions().marker(marker);
|
||||
assertEquals(ImmutableList.of(marker), options.buildQueryParameters().get("marker"));
|
||||
}
|
||||
|
||||
public void testMaxResults() {
|
||||
int limit = 1;
|
||||
BaseListOptions options = new BaseListOptions().maxResults(limit);
|
||||
PaginationOptions options = new PaginationOptions().limit(limit);
|
||||
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||
}
|
||||
|
||||
public void testChangesSinceStatic() {
|
||||
Date ifModifiedSince = new Date();
|
||||
BaseListOptions options = changesSince(ifModifiedSince);
|
||||
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
|
||||
.buildQueryParameters().get("changes-since"));
|
||||
PaginationOptions options = changesSince(ifModifiedSince);
|
||||
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""),
|
||||
options.buildQueryParameters().get("changes-since"));
|
||||
}
|
||||
|
||||
public void testStartAtStatic() {
|
||||
long offset = 1;
|
||||
BaseListOptions options = startAt(offset);
|
||||
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||
public void testMarkerStatic() {
|
||||
String marker = "52415800-8b69-11e0-9b19-734f6f006e54";
|
||||
PaginationOptions options = marker(marker);
|
||||
assertEquals(ImmutableList.of(marker), options.buildQueryParameters().get("marker"));
|
||||
}
|
||||
|
||||
public void testMaxResultsStatic() {
|
||||
int limit = 1;
|
||||
BaseListOptions options = maxResults(limit);
|
||||
PaginationOptions options = limit(limit);
|
||||
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ import org.jclouds.concurrent.Timeout;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Zone;
|
||||
import org.jclouds.location.functions.ZoneToEndpoint;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi;
|
||||
|
@ -156,7 +156,7 @@ public interface NovaApi {
|
|||
* Provides synchronous access to Server Admin Actions features.
|
||||
*/
|
||||
@Delegate
|
||||
Optional<? extends AdminActionsApi> getAdminActionsExtensionForZone(
|
||||
Optional<? extends ServerAdminApi> getAdminActionsExtensionForZone(
|
||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Set;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Zone;
|
||||
import org.jclouds.location.functions.ZoneToEndpoint;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi;
|
||||
|
@ -155,7 +155,7 @@ public interface NovaAsyncApi {
|
|||
* Provides asynchronous access to Server Admin Actions features.
|
||||
*/
|
||||
@Delegate
|
||||
Optional<? extends AdminActionsAsyncApi> getAdminActionsExtensionForZone(
|
||||
Optional<? extends ServerAdminAsyncApi> getAdminActionsExtensionForZone(
|
||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.KeyPairPredicates.nameMatches;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -65,7 +66,6 @@ import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
|
|||
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
|
||||
import org.jclouds.openstack.nova.v2_0.predicates.KeyPairPredicates;
|
||||
import org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates;
|
||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||
|
||||
|
@ -138,11 +138,11 @@ public class NovaComputeService extends BaseComputeService {
|
|||
Optional<? extends SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupExtensionForZone(zoneId);
|
||||
if (securityGroupApi.isPresent()) {
|
||||
for (String group : groups) {
|
||||
for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().listSecurityGroups(),
|
||||
for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().list(),
|
||||
SecurityGroupPredicates.nameMatches(namingConvention.create().containsGroup(group)))) {
|
||||
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, securityGroup.getName());
|
||||
logger.debug(">> deleting securityGroup(%s)", zoneAndName);
|
||||
securityGroupApi.get().deleteSecurityGroup(securityGroup.getId());
|
||||
securityGroupApi.get().delete(securityGroup.getId());
|
||||
// TODO: test this clear happens
|
||||
securityGroupMap.invalidate(zoneAndName);
|
||||
logger.debug("<< deleted securityGroup(%s)", zoneAndName);
|
||||
|
@ -155,16 +155,13 @@ public class NovaComputeService extends BaseComputeService {
|
|||
Optional<? extends KeyPairApi> keyPairApi = novaApi.getKeyPairExtensionForZone(zoneId);
|
||||
if (keyPairApi.isPresent()) {
|
||||
for (String group : groups) {
|
||||
for (Map<String, ? extends KeyPair> view : keyPairApi.get().listKeyPairs()) {
|
||||
for (KeyPair pair : Iterables.filter(view.values(),
|
||||
KeyPairPredicates.nameMatches(namingConvention.create().containsGroup(group)))) {
|
||||
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName());
|
||||
logger.debug(">> deleting keypair(%s)", zoneAndName);
|
||||
keyPairApi.get().deleteKeyPair(pair.getName());
|
||||
// TODO: test this clear happens
|
||||
keyPairCache.invalidate(zoneAndName);
|
||||
logger.debug("<< deleted keypair(%s)", zoneAndName);
|
||||
}
|
||||
for (KeyPair pair : keyPairApi.get().list().filter(nameMatches(namingConvention.create().containsGroup(group)))) {
|
||||
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName());
|
||||
logger.debug(">> deleting keypair(%s)", zoneAndName);
|
||||
keyPairApi.get().delete(pair.getName());
|
||||
// TODO: test this clear happens
|
||||
keyPairCache.invalidate(zoneAndName);
|
||||
logger.debug("<< deleted keypair(%s)", zoneAndName);
|
||||
}
|
||||
keyPairCache.invalidate(ZoneAndName.fromZoneAndName(zoneId,
|
||||
namingConvention.create().sharedNameForGroup(group)));
|
||||
|
|
|
@ -124,8 +124,8 @@ public class NovaComputeServiceAdapter implements
|
|||
String flavorId = template.getHardware().getProviderId();
|
||||
|
||||
logger.debug(">> creating new server zone(%s) name(%s) image(%s) flavor(%s) options(%s)", zoneId, name, imageId, flavorId, options);
|
||||
ServerCreated lightweightServer = novaApi.getServerApiForZone(zoneId).createServer(name, imageId, flavorId, options);
|
||||
Server server = novaApi.getServerApiForZone(zoneId).getServer(lightweightServer.getId());
|
||||
ServerCreated lightweightServer = novaApi.getServerApiForZone(zoneId).create(name, imageId, flavorId, options);
|
||||
Server server = novaApi.getServerApiForZone(zoneId).get(lightweightServer.getId());
|
||||
|
||||
logger.trace("<< server(%s)", server.getId());
|
||||
|
||||
|
@ -140,7 +140,7 @@ public class NovaComputeServiceAdapter implements
|
|||
public Iterable<FlavorInZone> listHardwareProfiles() {
|
||||
Builder<FlavorInZone> builder = ImmutableSet.builder();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
builder.addAll(transform(novaApi.getFlavorApiForZone(zoneId).listFlavorsInDetail(),
|
||||
builder.addAll(transform(novaApi.getFlavorApiForZone(zoneId).listInDetail().concat(),
|
||||
new Function<Flavor, FlavorInZone>() {
|
||||
|
||||
@Override
|
||||
|
@ -159,7 +159,7 @@ public class NovaComputeServiceAdapter implements
|
|||
Set<String> zones = zoneIds.get();
|
||||
checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds);
|
||||
for (final String zoneId : zones) {
|
||||
Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listImagesInDetail();
|
||||
Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listInDetail().concat().toImmutableSet();
|
||||
if (images.size() == 0) {
|
||||
logger.debug("no images found in zone %s", zoneId);
|
||||
continue;
|
||||
|
@ -194,8 +194,8 @@ public class NovaComputeServiceAdapter implements
|
|||
public Iterable<ServerInZone> listNodes() {
|
||||
Builder<ServerInZone> builder = ImmutableSet.builder();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
builder.addAll(transform(novaApi.getServerApiForZone(zoneId).listServersInDetail(),
|
||||
new Function<Server, ServerInZone>() {
|
||||
builder.addAll(novaApi.getServerApiForZone(zoneId).listInDetail().concat()
|
||||
.transform(new Function<Server, ServerInZone>() {
|
||||
|
||||
@Override
|
||||
public ServerInZone apply(Server arg0) {
|
||||
|
@ -216,14 +216,14 @@ public class NovaComputeServiceAdapter implements
|
|||
@Override
|
||||
public ServerInZone getNode(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).getServer(zoneAndId.getId());
|
||||
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
|
||||
return server == null ? null : new ServerInZone(server, zoneAndId.getZone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageInZone getImage(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
Image image = novaApi.getImageApiForZone(zoneAndId.getZone()).getImage(zoneAndId.getId());
|
||||
Image image = novaApi.getImageApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
|
||||
return image == null ? null : new ImageInZone(image, zoneAndId.getZone());
|
||||
}
|
||||
|
||||
|
@ -237,20 +237,20 @@ public class NovaComputeServiceAdapter implements
|
|||
logger.warn(e, "<< error removing and deallocating ip from node(%s): %s", id, e.getMessage());
|
||||
}
|
||||
}
|
||||
novaApi.getServerApiForZone(zoneAndId.getZone()).deleteServer(zoneAndId.getId());
|
||||
novaApi.getServerApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebootNode(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
novaApi.getServerApiForZone(zoneAndId.getZone()).rebootServer(zoneAndId.getId(), RebootType.HARD);
|
||||
novaApi.getServerApiForZone(zoneAndId.getZone()).reboot(zoneAndId.getId(), RebootType.HARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeNode(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
|
||||
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().resumeServer(zoneAndId.getId());
|
||||
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().resume(zoneAndId.getId());
|
||||
}
|
||||
throw new UnsupportedOperationException("resume requires installation of the Admin Actions extension");
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ public class NovaComputeServiceAdapter implements
|
|||
public void suspendNode(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
|
||||
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().suspendServer(zoneAndId.getId());
|
||||
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().suspend(zoneAndId.getId());
|
||||
}
|
||||
throw new UnsupportedOperationException("suspend requires installation of the Admin Actions extension");
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class NovaImageExtension implements ImageExtension {
|
|||
@Override
|
||||
public ImageTemplate buildImageTemplateFromNode(String name, final String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).getServer(zoneAndId.getId());
|
||||
Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
|
||||
if (server == null)
|
||||
throw new NoSuchElementException("Cannot find server with id: " + zoneAndId);
|
||||
CloneImageTemplate template = new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
|
||||
|
@ -119,7 +119,7 @@ public class NovaImageExtension implements ImageExtension {
|
|||
public boolean deleteImage(String id) {
|
||||
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
|
||||
try {
|
||||
this.novaApi.getImageApiForZone(zoneAndId.getZone()).deleteImage(zoneAndId.getId());
|
||||
this.novaApi.getImageApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class AllocateAndAddFloatingIpToNode implements
|
|||
} catch (InsufficientResourcesException e) {
|
||||
logger.trace("<< [%s] allocating a new floating ip for node(%s)", e.getMessage(), node.getId());
|
||||
logger.trace(">> searching for existing, unassigned floating ip for node(%s)", node.getId());
|
||||
ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.listFloatingIPs(),
|
||||
ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
|
||||
new Predicate<FloatingIP>() {
|
||||
|
||||
@Override
|
||||
|
@ -101,7 +101,7 @@ public class AllocateAndAddFloatingIpToNode implements
|
|||
}
|
||||
logger.debug(">> adding floatingIp(%s) to node(%s)", ip.getIp(), node.getId());
|
||||
|
||||
floatingIpApi.addFloatingIPToServer(ip.getIp(), node.getProviderId());
|
||||
floatingIpApi.addToServer(ip.getIp(), node.getProviderId());
|
||||
input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
|
||||
floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
|
||||
return input;
|
||||
|
|
|
@ -67,17 +67,17 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
|
|||
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
|
||||
try {
|
||||
|
||||
SecurityGroup securityGroup = api.get().createSecurityGroupWithNameAndDescription(
|
||||
SecurityGroup securityGroup = api.get().createWithDescription(
|
||||
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
|
||||
|
||||
logger.debug("<< created securityGroup(%s)", securityGroup);
|
||||
for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
|
||||
authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), securityGroup, port);
|
||||
}
|
||||
return new SecurityGroupInZone(api.get().getSecurityGroup(securityGroup.getId()), zoneId);
|
||||
return new SecurityGroupInZone(api.get().get(securityGroup.getId()), zoneId);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.trace("<< trying to find securityGroup(%s): %s", zoneSecurityGroupNameAndPorts, e.getMessage());
|
||||
SecurityGroup group = find(api.get().listSecurityGroups(), nameEquals(zoneSecurityGroupNameAndPorts
|
||||
SecurityGroup group = find(api.get().list(), nameEquals(zoneSecurityGroupNameAndPorts
|
||||
.getName()));
|
||||
logger.debug("<< reused securityGroup(%s)", group.getId());
|
||||
return new SecurityGroupInZone(group, zoneId);
|
||||
|
@ -88,7 +88,7 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
|
|||
SecurityGroup securityGroup, int port) {
|
||||
// NOTE that permission to itself isn't supported on trystack!
|
||||
logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
securityGroupApi.createSecurityGroupRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
|
||||
securityGroupApi.createRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
|
||||
IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
|
||||
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public class RemoveFloatingIpFromNodeAndDeallocate implements Function<ZoneAndId
|
|||
FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(id.getZone()).get();
|
||||
for (FloatingIP ip : floatingIpCache.getUnchecked(id)) {
|
||||
logger.debug(">> removing floatingIp(%s) from node(%s)", ip, id);
|
||||
floatingIpApi.removeFloatingIPFromServer(ip.getIp(), id.getId());
|
||||
floatingIpApi.removeFromServer(ip.getIp(), id.getId());
|
||||
logger.debug(">> deallocating floatingIp(%s)", ip);
|
||||
floatingIpApi.deallocate(ip.getId());
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class CreateUniqueKeyPair extends CacheLoader<ZoneAndName, KeyPair> {
|
|||
KeyPair keyPair = null;
|
||||
while (keyPair == null) {
|
||||
try {
|
||||
keyPair = api.get().createKeyPair(namingConvention.createWithoutPrefix().uniqueNameForGroup(prefix));
|
||||
keyPair = api.get().create(namingConvention.createWithoutPrefix().uniqueNameForGroup(prefix));
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.google.common.base.Optional;
|
|||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Each zone may or may not have the floating ip function present. In order to safely proceed, we
|
||||
|
@ -53,7 +52,7 @@ public class LoadFloatingIpsForInstance extends CacheLoader<ZoneAndId, Iterable<
|
|||
String zone = key.getZone();
|
||||
Optional<? extends FloatingIPApi> ipApiOptional = api.getFloatingIPExtensionForZone(zone);
|
||||
if (ipApiOptional.isPresent()) {
|
||||
return Iterables.filter(ipApiOptional.get().listFloatingIPs(),
|
||||
return ipApiOptional.get().list().filter(
|
||||
new Predicate<FloatingIP>() {
|
||||
@Override
|
||||
public boolean apply(FloatingIP input) {
|
||||
|
|
|
@ -162,7 +162,7 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
/**
|
||||
* <h3>Note</h3>
|
||||
*
|
||||
* This requires that {@link NovaApi#getFloatingIPExtensionForZone(String)} to return
|
||||
* This requires that {@link NovaApi#getExtensionForZone(String)} to return
|
||||
* {@link Optional#isPresent present}
|
||||
*
|
||||
* @return true if auto assignment of a floating ip to each vm is enabled
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.jclouds.predicates.PredicateWithResult;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
|
@ -89,7 +88,7 @@ public final class GetImageWhenImageInZoneHasActiveStatusPredicateWithResult imp
|
|||
}
|
||||
|
||||
public org.jclouds.openstack.nova.v2_0.domain.Image findImage(final ZoneAndId zoneAndId) {
|
||||
return Iterables.tryFind(api.getImageApiForZone(zoneAndId.getZone()).listImagesInDetail(),
|
||||
return api.getImageApiForZone(zoneAndId.getZone()).listInDetail().concat().firstMatch(
|
||||
new Predicate<org.jclouds.openstack.nova.v2_0.domain.Image>() {
|
||||
@Override
|
||||
public boolean apply(org.jclouds.openstack.nova.v2_0.domain.Image input) {
|
||||
|
|
|
@ -32,8 +32,8 @@ import org.jclouds.http.annotation.Redirection;
|
|||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerAdminAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
|
||||
|
@ -106,7 +106,7 @@ public class NovaRestClientModule<S extends NovaApi, A extends NovaAsyncApi> ext
|
|||
.put(VolumeApi.class, VolumeAsyncApi.class)
|
||||
.put(VirtualInterfaceApi.class, VirtualInterfaceAsyncApi.class)
|
||||
.put(ServerWithSecurityGroupsApi.class, ServerWithSecurityGroupsAsyncApi.class)
|
||||
.put(AdminActionsApi.class, AdminActionsAsyncApi.class)
|
||||
.put(ServerAdminApi.class, ServerAdminAsyncApi.class)
|
||||
.put(HostAggregateApi.class, HostAggregateAsyncApi.class)
|
||||
.put(FlavorExtraSpecsApi.class, FlavorExtraSpecsAsyncApi.class)
|
||||
.put(QuotaApi.class, QuotaAsyncApi.class)
|
||||
|
@ -114,6 +114,7 @@ public class NovaRestClientModule<S extends NovaApi, A extends NovaAsyncApi> ext
|
|||
.put(VolumeTypeApi.class, VolumeTypeAsyncApi.class)
|
||||
.build();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public NovaRestClientModule() {
|
||||
super(TypeToken.class.cast(TypeToken.of(NovaApi.class)), TypeToken.class.cast(TypeToken.of(NovaAsyncApi.class)), DELEGATE_MAP);
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ public class NovaRestClientModule<S extends NovaApi, A extends NovaAsyncApi> ext
|
|||
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> load(String key) throws Exception {
|
||||
return novaApi.get().getExtensionApiForZone(key).listExtensions();
|
||||
return novaApi.get().getExtensionApiForZone(key).list();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import com.google.common.base.Optional;
|
|||
*
|
||||
* @author Jeremy Daggett
|
||||
* @see <a href=
|
||||
"http://docs.openstack.org/api/openstack-compute/1.1/content/Flavors-d1e4180.html"
|
||||
"http://docs.openstack.org/api/openstack-compute/2/content/List_Flavors-d1e4188.html"
|
||||
/>
|
||||
*/
|
||||
public class Flavor extends Resource {
|
||||
|
|
|
@ -32,7 +32,7 @@ import com.google.common.base.Objects.ToStringHelper;
|
|||
*
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.QuotaApi
|
||||
*/
|
||||
public class Quotas {
|
||||
public class Quota {
|
||||
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
|
@ -60,7 +60,7 @@ public class Quotas {
|
|||
protected int keyPairs;
|
||||
|
||||
/**
|
||||
* @see Quotas#getId()
|
||||
* @see Quota#getId()
|
||||
*/
|
||||
public T id(String id) {
|
||||
this.id = id;
|
||||
|
@ -68,7 +68,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getMetadataItems()
|
||||
* @see Quota#getMetadataItems()
|
||||
*/
|
||||
public T metadataItems(int metadataItems) {
|
||||
this.metadataItems = metadataItems;
|
||||
|
@ -76,7 +76,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getInjectedFileContentBytes()
|
||||
* @see Quota#getInjectedFileContentBytes()
|
||||
*/
|
||||
public T injectedFileContentBytes(int injectedFileContentBytes) {
|
||||
this.injectedFileContentBytes = injectedFileContentBytes;
|
||||
|
@ -84,7 +84,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getVolumes()
|
||||
* @see Quota#getVolumes()
|
||||
*/
|
||||
public T volumes(int volumes) {
|
||||
this.volumes = volumes;
|
||||
|
@ -92,7 +92,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getGigabytes()
|
||||
* @see Quota#getGigabytes()
|
||||
*/
|
||||
public T gigabytes(int gigabytes) {
|
||||
this.gigabytes = gigabytes;
|
||||
|
@ -100,7 +100,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getRam()
|
||||
* @see Quota#getRam()
|
||||
*/
|
||||
public T ram(int ram) {
|
||||
this.ram = ram;
|
||||
|
@ -108,7 +108,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getFloatingIps()
|
||||
* @see Quota#getFloatingIps()
|
||||
*/
|
||||
public T floatingIps(int floatingIps) {
|
||||
this.floatingIps = floatingIps;
|
||||
|
@ -116,7 +116,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getInstances()
|
||||
* @see Quota#getInstances()
|
||||
*/
|
||||
public T instances(int instances) {
|
||||
this.instances = instances;
|
||||
|
@ -124,7 +124,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getInjectedFiles()
|
||||
* @see Quota#getInjectedFiles()
|
||||
*/
|
||||
public T injectedFiles(int injectedFiles) {
|
||||
this.injectedFiles = injectedFiles;
|
||||
|
@ -132,7 +132,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getCores()
|
||||
* @see Quota#getCores()
|
||||
*/
|
||||
public T cores(int cores) {
|
||||
this.cores = cores;
|
||||
|
@ -140,7 +140,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getSecurityGroups()
|
||||
* @see Quota#getSecurityGroups()
|
||||
*/
|
||||
public T securityGroups(int securityGroups) {
|
||||
this.securityGroups = securityGroups;
|
||||
|
@ -148,7 +148,7 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getSecurityGroupRules()
|
||||
* @see Quota#getSecurityGroupRules()
|
||||
*/
|
||||
public T securityGroupRules(int securityGroupRules) {
|
||||
this.securityGroupRules = securityGroupRules;
|
||||
|
@ -156,18 +156,18 @@ public class Quotas {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Quotas#getKeyPairs()
|
||||
* @see Quota#getKeyPairs()
|
||||
*/
|
||||
public T keyPairs(int keyPairs) {
|
||||
this.keyPairs = keyPairs;
|
||||
return self();
|
||||
}
|
||||
|
||||
public Quotas build() {
|
||||
return new Quotas(id, metadataItems, injectedFileContentBytes, volumes, gigabytes, ram, floatingIps, instances, injectedFiles, cores, securityGroups, securityGroupRules, keyPairs);
|
||||
public Quota build() {
|
||||
return new Quota(id, metadataItems, injectedFileContentBytes, volumes, gigabytes, ram, floatingIps, instances, injectedFiles, cores, securityGroups, securityGroupRules, keyPairs);
|
||||
}
|
||||
|
||||
public T fromQuotas(Quotas in) {
|
||||
public T fromQuotas(Quota in) {
|
||||
return this
|
||||
.id(in.getId())
|
||||
.metadataItems(in.getMetadataItems())
|
||||
|
@ -216,7 +216,7 @@ public class Quotas {
|
|||
@ConstructorProperties({
|
||||
"id", "metadata_items", "injected_file_content_bytes", "volumes", "gigabytes", "ram", "floating_ips", "instances", "injected_files", "cores", "security_groups", "security_group_rules", "key_pairs"
|
||||
})
|
||||
protected Quotas(String id, int metadataItems, int injectedFileContentBytes, int volumes, int gigabytes, int ram, int floatingIps, int instances, int injectedFiles, int cores, int securityGroups, int securityGroupRules, int keyPairs) {
|
||||
protected Quota(String id, int metadataItems, int injectedFileContentBytes, int volumes, int gigabytes, int ram, int floatingIps, int instances, int injectedFiles, int cores, int securityGroups, int securityGroupRules, int keyPairs) {
|
||||
this.id = checkNotNull(id, "id");
|
||||
this.metadataItems = metadataItems;
|
||||
this.injectedFileContentBytes = injectedFileContentBytes;
|
||||
|
@ -329,7 +329,7 @@ public class Quotas {
|
|||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Quotas that = Quotas.class.cast(obj);
|
||||
Quota that = Quota.class.cast(obj);
|
||||
return Objects.equal(this.id, that.id)
|
||||
&& Objects.equal(this.metadataItems, that.metadataItems)
|
||||
&& Objects.equal(this.injectedFileContentBytes, that.injectedFileContentBytes)
|
|
@ -25,7 +25,7 @@ import java.beans.ConstructorProperties;
|
|||
*
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.QuotaClassApi
|
||||
*/
|
||||
public class QuotaClass extends Quotas {
|
||||
public class QuotaClass extends Quota {
|
||||
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
|
@ -35,7 +35,7 @@ public class QuotaClass extends Quotas {
|
|||
return new ConcreteBuilder().fromQuotaClass(this);
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends Builder<T>> extends Quotas.Builder<T> {
|
||||
public static abstract class Builder<T extends Builder<T>> extends Quota.Builder<T> {
|
||||
|
||||
public QuotaClass build() {
|
||||
return new QuotaClass(id, metadataItems, injectedFileContentBytes, volumes, gigabytes, ram, floatingIps, instances, injectedFiles, cores, securityGroups, securityGroupRules, keyPairs);
|
||||
|
|
|
@ -22,10 +22,10 @@ import java.util.Map;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Provide access to extra metadata for Nova flavors.
|
||||
|
@ -35,9 +35,9 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
* @see org.jclouds.openstack.nova.v2_0.features.FlavorApi
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLAVOR_EXTRA_SPECS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface FlavorExtraSpecsApi {
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ public interface FlavorExtraSpecsApi {
|
|||
*
|
||||
* @return the set of extra metadata for the flavor
|
||||
*/
|
||||
Map<String, String> getAllExtraSpecs(String flavorId);
|
||||
Map<String, String> getMetadata(String flavorId);
|
||||
|
||||
/**
|
||||
* Creates or updates the extra specs for a given flavor
|
||||
|
@ -53,7 +53,7 @@ public interface FlavorExtraSpecsApi {
|
|||
* @param flavorId the id of the flavor to modify
|
||||
* @param specs the extra specs to apply
|
||||
*/
|
||||
Boolean setAllExtraSpecs(String flavorId, Map<String, String> specs);
|
||||
Boolean updateMetadata(String flavorId, Map<String, String> specs);
|
||||
|
||||
/**
|
||||
* Return a single extra spec value
|
||||
|
@ -61,7 +61,7 @@ public interface FlavorExtraSpecsApi {
|
|||
* @param flavorId the id of the flavor to modify
|
||||
* @param key the extra spec key to retrieve
|
||||
*/
|
||||
String getExtraSpec(String flavorId, String key);
|
||||
String getMetadataKey(String flavorId, String key);
|
||||
|
||||
/**
|
||||
* Creates or updates a single extra spec value
|
||||
|
@ -70,7 +70,7 @@ public interface FlavorExtraSpecsApi {
|
|||
* @param key the extra spec key (when creating ensure this does not include whitespace or other difficult characters)
|
||||
* @param value the value to associate with the key
|
||||
*/
|
||||
Boolean setExtraSpec(String flavorId, String key, String value);
|
||||
Boolean updateMetadataEntry(String flavorId, String key, String value);
|
||||
|
||||
/**
|
||||
* Deletes an extra spec
|
||||
|
@ -78,6 +78,6 @@ public interface FlavorExtraSpecsApi {
|
|||
* @param flavorId the id of the flavor to modify
|
||||
* @param key the extra spec key to delete
|
||||
*/
|
||||
Boolean deleteExtraSpec(String flavorId, String key);
|
||||
Boolean deleteMetadataKey(String flavorId, String key);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -31,7 +30,6 @@ 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.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
@ -47,6 +45,7 @@ import org.jclouds.rest.functions.ReturnEmptyMapOnNotFoundOr404;
|
|||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -57,59 +56,59 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see org.jclouds.openstack.nova.v2_0.features.FlavorApi
|
||||
* @see FlavorExtraSpecsApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLAVOR_EXTRA_SPECS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface FlavorExtraSpecsAsyncApi {
|
||||
|
||||
/**
|
||||
* @see FlavorExtraSpecsApi#getAllExtraSpecs(String)
|
||||
* @see FlavorExtraSpecsApi#getMetadata(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extra_specs")
|
||||
@Path("/flavors/{flavor_id}/os-extra_specs")
|
||||
@ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class)
|
||||
ListenableFuture<Map<String, String>> getAllExtraSpecs(@PathParam("flavor_id") String flavorId);
|
||||
ListenableFuture<Map<String, String>> getMetadata(@PathParam("flavor_id") String flavorId);
|
||||
|
||||
/**
|
||||
* @see FlavorExtraSpecsApi#setExtraSpec(String, String, String)
|
||||
* @see FlavorExtraSpecsApi#updateMetadataEntry(String, String, String)
|
||||
*/
|
||||
@POST
|
||||
@Path("/flavors/{flavor_id}/os-extra_specs")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ListenableFuture<Boolean> setAllExtraSpecs(@PathParam("flavor_id") String flavorId, @PayloadParam("extra_specs") Map<String, String> specs);
|
||||
ListenableFuture<Boolean> updateMetadata(@PathParam("flavor_id") String flavorId, @PayloadParam("extra_specs") Map<String, String> specs);
|
||||
|
||||
/**
|
||||
* @see FlavorExtraSpecsApi#getExtraSpec(String, String)
|
||||
* @see FlavorExtraSpecsApi#getMetadataKey(String, String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/flavors/{flavor_id}/os-extra_specs/{key}")
|
||||
@Unwrap
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<String> getExtraSpec(@PathParam("flavor_id") String flavorId, @PathParam("key") String key);
|
||||
ListenableFuture<String> getMetadataKey(@PathParam("flavor_id") String flavorId, @PathParam("key") String key);
|
||||
|
||||
/**
|
||||
* @see FlavorExtraSpecsApi#setExtraSpec(String, String, String)
|
||||
* @see FlavorExtraSpecsApi#updateMetadataEntry(String, String, String)
|
||||
*/
|
||||
@PUT
|
||||
@Path("/flavors/{flavor_id}/os-extra_specs/{key}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@Payload("%7B\"{key}\":\"{value}\"%7D")
|
||||
ListenableFuture<Boolean> setExtraSpec(@PathParam("flavor_id") String flavorId,
|
||||
ListenableFuture<Boolean> updateMetadataEntry(@PathParam("flavor_id") String flavorId,
|
||||
@PathParam("key") @PayloadParam("key") String key,
|
||||
@PayloadParam("value") String value);
|
||||
|
||||
/**
|
||||
* @see FlavorExtraSpecsApi#deleteExtraSpec(String, String)
|
||||
* @see FlavorExtraSpecsApi#deleteMetadataKey(String, String)
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/flavors/{flavor_id}/os-extra_specs/{key}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> deleteExtraSpec(@PathParam("flavor_id") String flavorId,
|
||||
ListenableFuture<Boolean> deleteMetadataKey(@PathParam("flavor_id") String flavorId,
|
||||
@PathParam("key") String key);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -26,6 +25,9 @@ import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Floating IPs.
|
||||
* <p/>
|
||||
|
@ -33,6 +35,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @see FloatingIPAsyncApi
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface FloatingIPApi {
|
||||
|
@ -42,14 +45,14 @@ public interface FloatingIPApi {
|
|||
*
|
||||
* @return all Floating IPs
|
||||
*/
|
||||
Set<? extends FloatingIP> listFloatingIPs();
|
||||
FluentIterable<? extends FloatingIP> list();
|
||||
|
||||
/**
|
||||
* Get a specific Floating IP address
|
||||
*
|
||||
* @return all Floating IPs
|
||||
*/
|
||||
FloatingIP getFloatingIP(String id);
|
||||
FloatingIP get(String id);
|
||||
|
||||
/**
|
||||
* Allocate a Floating IP address
|
||||
|
@ -76,7 +79,7 @@ public interface FloatingIPApi {
|
|||
*
|
||||
* NOTE: Possibly move this to ServerApi?
|
||||
*/
|
||||
void addFloatingIPToServer(String address, String serverId);
|
||||
void addToServer(String address, String serverId);
|
||||
|
||||
/**
|
||||
* Remove a Floating IP address from a Server
|
||||
|
@ -88,5 +91,5 @@ public interface FloatingIPApi {
|
|||
*
|
||||
* NOTE: Possibly move this to ServerApi?
|
||||
*/
|
||||
void removeFloatingIPFromServer(String address, String serverId);
|
||||
void removeFromServer(String address, String serverId);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -40,9 +38,11 @@ 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.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -57,30 +57,31 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os_api_floating_ip"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS)
|
||||
@SkipEncoding( { '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface FloatingIPAsyncApi {
|
||||
|
||||
/**
|
||||
* @see FloatingIPApi#listFloatingIPs
|
||||
* @see FloatingIPApi#list
|
||||
*/
|
||||
@GET
|
||||
@Path("/os-floating-ips")
|
||||
@SelectJson("floating_ips")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends FloatingIP>> listFloatingIPs();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends FloatingIP>> list();
|
||||
|
||||
/**
|
||||
* @see FloatingIPApi#getFloatingIP
|
||||
* @see FloatingIPApi#get
|
||||
*/
|
||||
@GET
|
||||
@Path("/os-floating-ips/{id}")
|
||||
@SelectJson("floating_ip")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FloatingIP> getFloatingIP(@PathParam("id") String id);
|
||||
ListenableFuture<? extends FloatingIP> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see FloatingIPApi#allocate
|
||||
|
@ -104,25 +105,25 @@ public interface FloatingIPAsyncApi {
|
|||
ListenableFuture<Void> deallocate(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see FloatingIPApi#addFloatingIPToServer
|
||||
* @see FloatingIPApi#addToServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{server}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"addFloatingIp\":%7B\"address\":\"{address}\"%7D%7D")
|
||||
ListenableFuture<Void> addFloatingIPToServer(@PayloadParam("address") String address,
|
||||
ListenableFuture<Void> addToServer(@PayloadParam("address") String address,
|
||||
@PathParam("server") String serverId);
|
||||
|
||||
/**
|
||||
* @see FloatingIPApi#removeFloatingIPFromServer
|
||||
* @see FloatingIPApi#removeFromServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{server}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"removeFloatingIp\":%7B\"address\":\"{address}\"%7D%7D")
|
||||
ListenableFuture<Void> removeFloatingIPFromServer(@PayloadParam("address") String address,
|
||||
ListenableFuture<Void> removeFromServer(@PayloadParam("address") String address,
|
||||
@PathParam("server") String serverId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -27,6 +26,9 @@ import org.jclouds.openstack.nova.v2_0.domain.HostResourceUsage;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Host Administration features via the REST API.
|
||||
* <p/>
|
||||
|
@ -34,6 +36,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @author Adam Lowe
|
||||
* @see HostAdministrationAsyncApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HOSTS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface HostAdministrationApi {
|
||||
|
@ -43,28 +46,28 @@ public interface HostAdministrationApi {
|
|||
*
|
||||
* @return the usage information
|
||||
*/
|
||||
Set<? extends Host> listHosts();
|
||||
FluentIterable<? extends Host> list();
|
||||
|
||||
/**
|
||||
* Retrieves the physical/usage resource on a specific host
|
||||
*
|
||||
* @return the usage information
|
||||
*/
|
||||
Set<? extends HostResourceUsage> getHostResourceUsage(String hostId);
|
||||
FluentIterable<? extends HostResourceUsage> listResourceUsage(String hostId);
|
||||
|
||||
/**
|
||||
* Allow the specified host to accept new instances.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean enableHost(String hostId);
|
||||
boolean enable(String hostId);
|
||||
|
||||
/**
|
||||
* Prevent the specified host from accepting new instances.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean disableHost(String hostId);
|
||||
boolean disable(String hostId);
|
||||
|
||||
/**
|
||||
* Start host maintenance window.
|
||||
|
@ -73,34 +76,34 @@ public interface HostAdministrationApi {
|
|||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean startHostMaintenance(String hostId);
|
||||
boolean startMaintenance(String hostId);
|
||||
|
||||
/**
|
||||
* Stop host maintenance window.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean stopHostMaintenance(String hostId);
|
||||
boolean stopMaintenance(String hostId);
|
||||
|
||||
/**
|
||||
* Startup a host.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean startupHost(String hostId);
|
||||
boolean startup(String hostId);
|
||||
|
||||
/**
|
||||
* Shutdown a host.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean shutdownHost(String hostId);
|
||||
boolean shutdown(String hostId);
|
||||
|
||||
/**
|
||||
* Reboot a host.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean rebootHost(String hostId);
|
||||
boolean reboot(String hostId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
|
@ -46,8 +44,10 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -60,6 +60,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.hosts.html" />
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HOSTS)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
|
@ -68,83 +69,83 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface HostAdministrationAsyncApi {
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#listHosts()
|
||||
* @see HostAdministrationApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("hosts")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Host>> listHosts();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends Host>> list();
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#getHostResourceUsage(String)
|
||||
* @see HostAdministrationApi#listResourceUsage(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@SelectJson("host")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends HostResourceUsage>> getHostResourceUsage(@PathParam("id") String hostId);
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends HostResourceUsage>> listResourceUsage(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#enableHost(String)
|
||||
* @see HostAdministrationApi#enable(String)
|
||||
*/
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{id}")
|
||||
@Payload("{\"status\":\"enable\"}")
|
||||
@ResponseParser(StatusEnabledResponseParser.class)
|
||||
ListenableFuture<Boolean> enableHost(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> enable(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#disableHost(String)
|
||||
* @see HostAdministrationApi#disable(String)
|
||||
*/
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{id}")
|
||||
@Payload("{\"status\":\"disable\"}")
|
||||
@ResponseParser(StatusDisabledResponseParser.class)
|
||||
ListenableFuture<Boolean> disableHost(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> disable(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#startHostMaintenance(String)
|
||||
* @see HostAdministrationApi#startMaintenance(String)
|
||||
*/
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{id}")
|
||||
@Payload("{\"maintenance_mode\":\"enable\"}")
|
||||
@ResponseParser(MaintenanceModeEnabledResponseParser.class)
|
||||
ListenableFuture<Boolean> startHostMaintenance(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> startMaintenance(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#stopHostMaintenance(String)
|
||||
* @see HostAdministrationApi#stopMaintenance(String)
|
||||
*/
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{id}")
|
||||
@Payload("{\"maintenance_mode\":\"disable\"}")
|
||||
@ResponseParser(MaintenanceModeDisabledResponseParser.class)
|
||||
ListenableFuture<Boolean> stopHostMaintenance(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> stopMaintenance(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#startupHost(String)
|
||||
* @see HostAdministrationApi#startup(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}/startup")
|
||||
@ResponseParser(PowerIsStartupResponseParser.class)
|
||||
ListenableFuture<Boolean> startupHost(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> startup(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#shutdownHost(String)
|
||||
* @see HostAdministrationApi#shutdown(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}/shutdown")
|
||||
@ResponseParser(PowerIsShutdownResponseParser.class)
|
||||
ListenableFuture<Boolean> shutdownHost(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> shutdown(@PathParam("id") String hostId);
|
||||
|
||||
/**
|
||||
* @see HostAdministrationApi#rebootHost(String)
|
||||
* @see HostAdministrationApi#reboot(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}/reboot")
|
||||
@ResponseParser(PowerIsRebootResponseParser.class)
|
||||
ListenableFuture<Boolean> rebootHost(@PathParam("id") String hostId);
|
||||
ListenableFuture<Boolean> reboot(@PathParam("id") String hostId);
|
||||
}
|
||||
|
|
|
@ -19,15 +19,15 @@
|
|||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provide access to Host Aggregates in Nova (alias "OS-AGGREGATES")
|
||||
|
@ -37,29 +37,29 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
* @see <a href="http://nova.openstack.org/api_ext/ext_aggregates.html"/>
|
||||
* @see <a href="http://wiki.openstack.org/host-aggregates"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.AGGREGATES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface HostAggregateApi {
|
||||
|
||||
/**
|
||||
* @return the set of host aggregates.
|
||||
*/
|
||||
Set<? extends HostAggregate> listAggregates();
|
||||
FluentIterable<? extends HostAggregate> list();
|
||||
|
||||
/**
|
||||
* Retrieves the details of an aggregate, hosts and metadata included.
|
||||
*
|
||||
* @return the details of the aggregate requested.
|
||||
*/
|
||||
HostAggregate getAggregate(String id);
|
||||
HostAggregate get(String id);
|
||||
|
||||
/**
|
||||
* Creates an aggregate, given its name and availability zone.
|
||||
*
|
||||
* @return the newly created Aggregate
|
||||
*/
|
||||
HostAggregate createAggregate(String name, String availabilityZone);
|
||||
HostAggregate createInAvailabilityZone(String name, String availabilityZone);
|
||||
|
||||
/**
|
||||
* Updates the name of an aggregate.
|
||||
|
@ -74,7 +74,7 @@ public interface HostAggregateApi {
|
|||
/**
|
||||
* Removes an aggregate.
|
||||
*/
|
||||
Boolean deleteAggregate(String id);
|
||||
Boolean delete(String id);
|
||||
|
||||
/**
|
||||
* Adds a host to an aggregate
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -31,7 +29,6 @@ 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.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
|
@ -41,10 +38,12 @@ import org.jclouds.rest.annotations.PayloadParam;
|
|||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.WrapWith;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -53,40 +52,40 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adam Lowe
|
||||
* @see HostAggregateApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.AGGREGATES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Path("/os-aggregates")
|
||||
public interface HostAggregateAsyncApi {
|
||||
|
||||
/**
|
||||
* @see HostAggregateApi#listAggregates()
|
||||
* @see HostAggregateApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("aggregates")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends HostAggregate>> listAggregates();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends HostAggregate>> list();
|
||||
|
||||
/**
|
||||
* @see HostAggregateApi#getAggregate(String)
|
||||
* @see HostAggregateApi#get(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@SelectJson("aggregate")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends HostAggregate> getAggregate(@PathParam("id") String id);
|
||||
ListenableFuture<? extends HostAggregate> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see HostAggregateApi#createAggregate(String, String)
|
||||
* @see HostAggregateApi#createInAvailabilityZone(String, String)
|
||||
*/
|
||||
@POST
|
||||
@SelectJson("aggregate")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@WrapWith("aggregate")
|
||||
ListenableFuture<? extends HostAggregate> createAggregate(@PayloadParam("name") String name,
|
||||
ListenableFuture<? extends HostAggregate> createInAvailabilityZone(@PayloadParam("name") String name,
|
||||
@PayloadParam("availability_zone") String availabilityZone);
|
||||
|
||||
/**
|
||||
|
@ -110,13 +109,13 @@ public interface HostAggregateAsyncApi {
|
|||
ListenableFuture<? extends HostAggregate> updateAvailabilityZone(@PathParam("id") String id, @PayloadParam("availability_zone") String availabilityZone);
|
||||
|
||||
/**
|
||||
* @see HostAggregateApi#deleteAggregate(String)
|
||||
* @see HostAggregateApi#delete(String)
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> deleteAggregate(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> delete(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see HostAggregateApi#addHost(String,String)
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -27,6 +25,9 @@ import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Security Groups.
|
||||
* <p/>
|
||||
|
@ -34,6 +35,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @see KeyPairAsyncApi
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface KeyPairApi {
|
||||
|
@ -43,27 +45,27 @@ public interface KeyPairApi {
|
|||
*
|
||||
* @return all Key Pairs
|
||||
*/
|
||||
Set<? extends Map<String, ? extends KeyPair>> listKeyPairs();
|
||||
FluentIterable<? extends KeyPair> list();
|
||||
|
||||
/**
|
||||
* Create a Key Pair.
|
||||
*
|
||||
* @return a Key Pair
|
||||
*/
|
||||
KeyPair createKeyPair(String name);
|
||||
KeyPair create(String name);
|
||||
|
||||
/**
|
||||
* Create a Key Pair with a public key.
|
||||
*
|
||||
* @return a Key Pair with a public key.
|
||||
*/
|
||||
KeyPair createKeyPairWithPublicKey(String name, String publicKey);
|
||||
KeyPair createWithPublicKey(String name, String publicKey);
|
||||
|
||||
/**
|
||||
* Delete a Key Pairs.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean deleteKeyPair(String name);
|
||||
boolean delete(String name);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -32,6 +29,7 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseKeyPairs;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
@ -39,11 +37,14 @@ import org.jclouds.rest.annotations.ExceptionParser;
|
|||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +60,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
|
@ -66,10 +68,10 @@ public interface KeyPairAsyncApi {
|
|||
|
||||
@GET
|
||||
@Path("/os-keypairs")
|
||||
@SelectJson("keypairs")
|
||||
@ResponseParser(ParseKeyPairs.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Map<String, ? extends KeyPair>>> listKeyPairs();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends KeyPair>> list();
|
||||
|
||||
@POST
|
||||
@Path("/os-keypairs")
|
||||
|
@ -77,7 +79,7 @@ public interface KeyPairAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"keypair\":%7B\"name\":\"{name}\"%7D%7D")
|
||||
ListenableFuture<? extends KeyPair> createKeyPair(@PayloadParam("name") String name);
|
||||
ListenableFuture<? extends KeyPair> create(@PayloadParam("name") String name);
|
||||
|
||||
@POST
|
||||
@Path("/os-keypairs")
|
||||
|
@ -85,13 +87,13 @@ public interface KeyPairAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"keypair\":%7B\"name\":\"{name}\",\"public_key\":\"{publicKey}\"%7D%7D")
|
||||
ListenableFuture<? extends KeyPair> createKeyPairWithPublicKey(@PayloadParam("name") String name,
|
||||
ListenableFuture<? extends KeyPair> createWithPublicKey(@PayloadParam("name") String name,
|
||||
@PayloadParam("publicKey") String publicKey);
|
||||
|
||||
@DELETE
|
||||
@Path("/os-keypairs/{name}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@Consumes
|
||||
ListenableFuture<Boolean> deleteKeyPair(@PathParam("name") String name);
|
||||
ListenableFuture<Boolean> delete(@PathParam("name") String name);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ package org.jclouds.openstack.nova.v2_0.extensions;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Quotas;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Quota;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* The quotas extension enables limiters placed on the resources used per tenant (project) for virtual instances. It is
|
||||
|
@ -38,26 +38,26 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
* @see QuotaAsyncApi
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_quotas.html"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTAS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface QuotaApi {
|
||||
|
||||
/**
|
||||
* @return the quota settings for the tenant
|
||||
*/
|
||||
Quotas getQuotasForTenant(String tenantId);
|
||||
Quota getByTenant(String tenantId);
|
||||
|
||||
/**
|
||||
* Update the quotas for a given tenant
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean updateQuotasForTenant(String tenantId, Quotas quotas);
|
||||
boolean updateQuotaOfTenant(Quota quota, String tenantId);
|
||||
|
||||
/**
|
||||
* @return the set of default quotas for the tenant
|
||||
*/
|
||||
Quotas getDefaultQuotasForTenant(String tenantId);
|
||||
Quota getDefaultsForTenant(String tenantId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
|
@ -28,9 +26,8 @@ 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.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Quotas;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Quota;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
|
@ -41,48 +38,50 @@ import org.jclouds.rest.annotations.SelectJson;
|
|||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provide access to Quota information for Nova tenants.
|
||||
*
|
||||
*
|
||||
* @author Adam Lowe
|
||||
* @see QuotaApi
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_quotas.html"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTAS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Path("/os-quota-sets")
|
||||
public interface QuotaAsyncApi {
|
||||
|
||||
/**
|
||||
* @see QuotaApi#getDefaultQuotasForTenant(String)
|
||||
* @see QuotaApi#getDefaultsForTenant(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("quota_set")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/{tenant_id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Quotas> getQuotasForTenant(@PathParam("tenant_id") String tenantId);
|
||||
ListenableFuture<? extends Quota> getByTenant(@PathParam("tenant_id") String tenantId);
|
||||
|
||||
/**
|
||||
* @see QuotaApi#updateQuotasForTenant(String, org.jclouds.openstack.nova.v2_0.domain.Quotas)
|
||||
* @see QuotaApi#updateQuotaOfTenant
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{tenant_id}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ListenableFuture<Boolean> updateQuotasForTenant(@PathParam("tenant_id") String tenantId, @PayloadParam("quota_set") Quotas quotas);
|
||||
ListenableFuture<Boolean> updateQuotaOfTenant(@PayloadParam("quota_set") Quota quota,
|
||||
@PathParam("tenant_id") String tenantId);
|
||||
|
||||
/**
|
||||
* @see QuotaApi#getDefaultQuotasForTenant(String)
|
||||
* @see QuotaApi#getDefaultsForTenant(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("quota_set")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/{tenant_id}/defaults")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Quotas> getDefaultQuotasForTenant(@PathParam("tenant_id") String tenantId);
|
||||
ListenableFuture<? extends Quota> getDefaultsForTenant(@PathParam("tenant_id") String tenantId);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ package org.jclouds.openstack.nova.v2_0.extensions;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.QuotaClass;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Quota Classes via the REST API.
|
||||
|
@ -37,21 +37,21 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.quota_classes.html"/>
|
||||
* @see <a href="http://wiki.openstack.org/QuotaClass"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTA_CLASSES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface QuotaClassApi {
|
||||
|
||||
/**
|
||||
* @return the quota settings for the tenant
|
||||
*/
|
||||
QuotaClass getQuotaClass(String id);
|
||||
QuotaClass get(String id);
|
||||
|
||||
/**
|
||||
* Update the quotas for a given tenant
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean updateQuotaClass(String id, QuotaClass quotas);
|
||||
boolean update(String id, QuotaClass quotas);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
|
@ -28,7 +26,6 @@ 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.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.QuotaClass;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
|
@ -41,6 +38,7 @@ import org.jclouds.rest.annotations.SelectJson;
|
|||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -51,29 +49,29 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.quota_classes.html"/>
|
||||
* @see <a href="http://wiki.openstack.org/QuotaClass"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTA_CLASSES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Path("/os-quota-class-sets")
|
||||
public interface QuotaClassAsyncApi {
|
||||
|
||||
/**
|
||||
* @see QuotaClassApi#getQuotaClass
|
||||
* @see QuotaClassApi#get
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("quota_class_set")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends QuotaClass> getQuotaClass(@PathParam("id") String id);
|
||||
ListenableFuture<? extends QuotaClass> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see QuotaClassApi#updateQuotaClass
|
||||
* @see QuotaClassApi#update
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ListenableFuture<Boolean> updateQuotaClass(@PathParam("id") String id, @PayloadParam("quota_class_set") QuotaClass quotas);
|
||||
ListenableFuture<Boolean> update(@PathParam("id") String id, @PayloadParam("quota_class_set") QuotaClass quotas);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -28,6 +27,9 @@ import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Security Groups.
|
||||
* <p/>
|
||||
|
@ -35,6 +37,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @see SecurityGroupAsyncApi
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface SecurityGroupApi {
|
||||
|
@ -42,44 +45,44 @@ public interface SecurityGroupApi {
|
|||
/**
|
||||
* List all Security Groups.
|
||||
*
|
||||
* @return all Floating IPs
|
||||
* @return all Security Groups
|
||||
*/
|
||||
Set<? extends SecurityGroup> listSecurityGroups();
|
||||
FluentIterable<? extends SecurityGroup> list();
|
||||
|
||||
/**
|
||||
* Get a specific Security Group
|
||||
*
|
||||
* @return a specific Security Group
|
||||
*/
|
||||
SecurityGroup getSecurityGroup(String id);
|
||||
SecurityGroup get(String id);
|
||||
|
||||
/**
|
||||
* Create a Security Group
|
||||
*
|
||||
* @return a new Security Group
|
||||
*/
|
||||
SecurityGroup createSecurityGroupWithNameAndDescription(String name, String description);
|
||||
SecurityGroup createWithDescription(String name, String description);
|
||||
|
||||
/**
|
||||
* Delete a Security Group.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean deleteSecurityGroup(String id);
|
||||
boolean delete(String id);
|
||||
|
||||
/**
|
||||
* Create a Security Group Rule.
|
||||
*
|
||||
* @return a new Security Group Rule
|
||||
*/
|
||||
SecurityGroupRule createSecurityGroupRuleAllowingCidrBlock(String parentGroup, Ingress ingress, String sourceCidr);
|
||||
SecurityGroupRule createRuleAllowingCidrBlock(String parentGroup, Ingress ingress, String sourceCidr);
|
||||
|
||||
/**
|
||||
* Create a Security Group Rule.
|
||||
*
|
||||
* @return a new Security Group Rule
|
||||
*/
|
||||
SecurityGroupRule createSecurityGroupRuleAllowingSecurityGroupId(String parentGroup, Ingress ingress,
|
||||
SecurityGroupRule createRuleAllowingSecurityGroupId(String parentGroup, Ingress ingress,
|
||||
String sourceCidr);
|
||||
|
||||
/**
|
||||
|
@ -87,6 +90,6 @@ public interface SecurityGroupApi {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
Boolean deleteSecurityGroupRule(String id);
|
||||
Boolean deleteRule(String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -43,10 +41,12 @@ 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.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -60,33 +60,34 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os-security-groups" />
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
|
||||
@SkipEncoding( { '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface SecurityGroupAsyncApi {
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#listSecurityGroups
|
||||
* @see SecurityGroupApi#list
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("security_groups")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/os-security-groups")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends SecurityGroup>> listSecurityGroups();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends SecurityGroup>> list();
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#getSecurityGroup
|
||||
* @see SecurityGroupApi#get
|
||||
*/
|
||||
@GET
|
||||
@Path("/os-security-groups/{id}")
|
||||
@SelectJson("security_group")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends SecurityGroup> getSecurityGroup(@PathParam("id") String id);
|
||||
ListenableFuture<? extends SecurityGroup> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#createSecurityGroupWithNameAndDescription
|
||||
* @see SecurityGroupApi#createWithDescription
|
||||
*/
|
||||
@POST
|
||||
@Path("/os-security-groups")
|
||||
|
@ -95,20 +96,20 @@ public interface SecurityGroupAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"security_group\":%7B\"name\":\"{name}\",\"description\":\"{description}\"%7D%7D")
|
||||
ListenableFuture<? extends SecurityGroup> createSecurityGroupWithNameAndDescription(@PayloadParam("name") String name,
|
||||
ListenableFuture<? extends SecurityGroup> createWithDescription(@PayloadParam("name") String name,
|
||||
@PayloadParam("description") String description);
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#deleteSecurityGroup
|
||||
* @see SecurityGroupApi#delete
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/os-security-groups/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ListenableFuture<Boolean> deleteSecurityGroup(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> delete(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#createSecurityGroupRuleAllowingCidrBlock
|
||||
* @see SecurityGroupApi#createRuleAllowingCidrBlock
|
||||
*/
|
||||
@POST
|
||||
@Path("/os-security-group-rules")
|
||||
|
@ -117,7 +118,7 @@ public interface SecurityGroupAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(BindSecurityGroupRuleToJsonPayload.class)
|
||||
ListenableFuture<? extends SecurityGroupRule> createSecurityGroupRuleAllowingCidrBlock(
|
||||
ListenableFuture<? extends SecurityGroupRule> createRuleAllowingCidrBlock(
|
||||
@PayloadParam("parent_group_id") String parent_group_id, Ingress ip_protocol,
|
||||
@PayloadParam("cidr") String cidr);
|
||||
|
||||
|
@ -131,17 +132,17 @@ public interface SecurityGroupAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(BindSecurityGroupRuleToJsonPayload.class)
|
||||
ListenableFuture<? extends SecurityGroupRule> createSecurityGroupRuleAllowingSecurityGroupId(
|
||||
ListenableFuture<? extends SecurityGroupRule> createRuleAllowingSecurityGroupId(
|
||||
@PayloadParam("parent_group_id") String parent_group_id, Ingress ip_protocol,
|
||||
@PayloadParam("group_id") String group_id);
|
||||
|
||||
/**
|
||||
* @see SecurityGroupApi#deleteSecurityGroupRule
|
||||
* @see SecurityGroupApi#deleteRule
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/os-security-group-rules/{security_group_rule_ID}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@Consumes
|
||||
ListenableFuture<Boolean> deleteSecurityGroupRule(@PathParam("security_group_rule_ID") String security_group_rule_ID);
|
||||
ListenableFuture<Boolean> deleteRule(@PathParam("security_group_rule_ID") String security_group_rule_ID);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,59 +26,62 @@ import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Provide additional actions for servers:
|
||||
* 'suspend', 'resume', 'migrate', 'lock', 'unlock', 'resetNetwork', 'createBackup', 'pause', 'migrateLive',
|
||||
* 'injectNetworkInfo', 'unpause'
|
||||
*
|
||||
* @author Adam Lowe
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.ServerAdminAsyncApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.ADMIN_ACTIONS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface AdminActionsApi {
|
||||
public interface ServerAdminApi {
|
||||
|
||||
/**
|
||||
* Suspend a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean suspendServer(String id);
|
||||
Boolean suspend(String id);
|
||||
|
||||
/**
|
||||
* Resume a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean resumeServer(String id);
|
||||
Boolean resume(String id);
|
||||
|
||||
/**
|
||||
* Migrate a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean migrateServer(String id);
|
||||
Boolean migrate(String id);
|
||||
|
||||
/**
|
||||
* Lock a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean lockServer(String id);
|
||||
Boolean lock(String id);
|
||||
|
||||
/**
|
||||
* Unlock a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean unlockServer(String id);
|
||||
Boolean unlock(String id);
|
||||
|
||||
/**
|
||||
* Reset network of a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean resetNetworkOfServer(String id);
|
||||
Boolean resetNetwork(String id);
|
||||
|
||||
/**
|
||||
* Create backup of a server.
|
||||
|
@ -90,21 +93,21 @@ public interface AdminActionsApi {
|
|||
* @param options optional rotation and/or metadata parameters
|
||||
* @return the id of the newly created image
|
||||
*/
|
||||
String createBackupOfServer(String id, String imageName, BackupType backupType, int rotation, CreateBackupOfServerOptions... options);
|
||||
String createBackup(String id, String imageName, BackupType backupType, int rotation, CreateBackupOfServerOptions... options);
|
||||
|
||||
/**
|
||||
* Pause a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean pauseServer(String id);
|
||||
Boolean pause(String id);
|
||||
|
||||
/**
|
||||
* Unpause a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean unpauseServer(String id);
|
||||
Boolean unpause(String id);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -112,12 +115,12 @@ public interface AdminActionsApi {
|
|||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean liveMigrateServer(String id, String host, boolean blockMigration, boolean diskOverCommit);
|
||||
Boolean liveMigrate(String id, String host, boolean blockMigration, boolean diskOverCommit);
|
||||
|
||||
/**
|
||||
* Inject network info into a server.
|
||||
*
|
||||
* @param id id of the server
|
||||
*/
|
||||
Boolean injectNetworkInfoIntoServer(String id);
|
||||
Boolean injectNetworkInfo(String id);
|
||||
}
|
|
@ -41,76 +41,78 @@ import org.jclouds.rest.annotations.WrapWith;
|
|||
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provide access to Admin Server Actions via REST API
|
||||
*
|
||||
* @author Adam Lowe
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.ServerAdminApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.ADMIN_ACTIONS)
|
||||
@SkipEncoding( { '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Path("/servers/{id}/action")
|
||||
public interface AdminActionsAsyncApi {
|
||||
public interface ServerAdminAsyncApi {
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#suspendServer(String)
|
||||
* @see ServerAdminApi#suspend(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"suspend\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> suspendServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> suspend(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#resumeServer(String)
|
||||
* @see ServerAdminApi#resume(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"resume\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> resumeServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> resume(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#migrateServer(String)
|
||||
* @see ServerAdminApi#migrate(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"migrate\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> migrateServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> migrate(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#suspendServer(String)
|
||||
* @see ServerAdminApi#lock(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"lock\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> lockServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> lock(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#unlockServer(String)
|
||||
* @see ServerAdminApi#unlock(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"unlock\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> unlockServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> unlock(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#resetNetworkOfServer(String)
|
||||
* @see ServerAdminApi#resetNetwork(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"resetNetwork\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> resetNetworkOfServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> resetNetwork(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#createBackupOfServer
|
||||
* @see ServerAdminApi#createBackup
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
|
@ -118,47 +120,47 @@ public interface AdminActionsAsyncApi {
|
|||
@WrapWith("createBackup")
|
||||
@ExceptionParser(MapHttp4xxCodesToExceptions.class)
|
||||
@ResponseParser(ParseImageIdFromLocationHeader.class)
|
||||
ListenableFuture<String> createBackupOfServer(@PathParam("id") String id,
|
||||
ListenableFuture<String> createBackup(@PathParam("id") String id,
|
||||
@PayloadParam("name") String imageName,
|
||||
@PayloadParam("backup_type") BackupType backupType,
|
||||
@PayloadParam("rotation") int rotation,
|
||||
CreateBackupOfServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#pauseServer(String)
|
||||
* @see ServerAdminApi#pause(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"pause\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> pauseServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> pause(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#unpauseServer(String)
|
||||
* @see ServerAdminApi#unpause(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"unpause\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> unpauseServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> unpause(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#suspendServer(String)
|
||||
* @see ServerAdminApi#injectNetworkInfo(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"injectNetworkInfo\":null}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> injectNetworkInfoIntoServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> injectNetworkInfo(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see AdminActionsApi#migrateServer(String)
|
||||
* @see ServerAdminApi#liveMigrate(String)
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@WrapWith("os-migrateLive")
|
||||
ListenableFuture<Boolean> liveMigrateServer(@PathParam("id") String id,
|
||||
ListenableFuture<Boolean> liveMigrate(@PathParam("id") String id,
|
||||
@PayloadParam("host") String host,
|
||||
@PayloadParam("block_migration") boolean blockMigration,
|
||||
@PayloadParam("disk_over_commit") boolean diskOverCommit);
|
|
@ -25,6 +25,8 @@ import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Server details including security group, referred to as the CREATESERVEREXT extension
|
||||
* in the nova documentation
|
||||
|
@ -37,6 +39,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @see ServerWithSecurityGroupsAsyncApi
|
||||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.createserverext.html"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface ServerWithSecurityGroupsApi {
|
||||
|
@ -47,6 +50,6 @@ public interface ServerWithSecurityGroupsApi {
|
|||
* @param id id of the server
|
||||
* @return server or null if not found
|
||||
*/
|
||||
ServerWithSecurityGroups getServer(String id);
|
||||
ServerWithSecurityGroups get(String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jclouds.rest.annotations.SelectJson;
|
|||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -44,19 +45,20 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see ServerWithSecurityGroupsApi
|
||||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.createserverext.html"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface ServerWithSecurityGroupsAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ServerWithSecurityGroupsApi#getServer(String)
|
||||
* @see ServerWithSecurityGroupsApi#get(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("server")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/os-create-server-ext/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends ServerWithSecurityGroups> getServer(@PathParam("id") String id);
|
||||
ListenableFuture<? extends ServerWithSecurityGroups> get(@PathParam("id") String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -26,6 +25,9 @@ import org.jclouds.openstack.nova.v2_0.domain.SimpleTenantUsage;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Simple Tenant Usage via the REST API.
|
||||
* <p/>
|
||||
|
@ -33,6 +35,7 @@ import org.jclouds.openstack.v2_0.services.Extension;
|
|||
* @author Adam Lowe
|
||||
* @see SimpleTenantUsageAsyncApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface SimpleTenantUsageApi {
|
||||
|
@ -42,12 +45,12 @@ public interface SimpleTenantUsageApi {
|
|||
*
|
||||
* @return the set of TenantUsage reports
|
||||
*/
|
||||
Set<? extends SimpleTenantUsage> listTenantUsages();
|
||||
FluentIterable<? extends SimpleTenantUsage> list();
|
||||
|
||||
/**
|
||||
* Retrieve tenant_usage for a specified tenant
|
||||
*
|
||||
* @return the requested tenant usage
|
||||
*/
|
||||
SimpleTenantUsage getTenantUsage(String tenantId);
|
||||
SimpleTenantUsage get(String tenantId);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -34,9 +32,11 @@ 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.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -49,29 +49,30 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.simple_tenant_usage.html" />
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface SimpleTenantUsageAsyncApi {
|
||||
|
||||
/**
|
||||
* @see SimpleTenantUsageApi#listTenantUsages()
|
||||
* @see SimpleTenantUsageApi#list()
|
||||
*/
|
||||
@GET
|
||||
@Path("/os-simple-tenant-usage")
|
||||
@SelectJson("tenant_usages")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends SimpleTenantUsage>> listTenantUsages();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends SimpleTenantUsage>> list();
|
||||
|
||||
/**
|
||||
* @see SimpleTenantUsageApi#getTenantUsage(String)
|
||||
* @see SimpleTenantUsageApi#get(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/os-simple-tenant-usage/{id}")
|
||||
@SelectJson("tenant_usage")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends SimpleTenantUsage> getTenantUsage(@PathParam("id") String tenantId);
|
||||
ListenableFuture<? extends SimpleTenantUsage> get(@PathParam("id") String tenantId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -26,12 +25,16 @@ import org.jclouds.openstack.nova.v2_0.domain.VirtualInterface;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Virtual Interface features (VIFs).
|
||||
*
|
||||
* @see VirtualInterfaceAsyncApi
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VIRTUAL_INTERFACES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface VirtualInterfaceApi {
|
||||
|
@ -41,6 +44,6 @@ public interface VirtualInterfaceApi {
|
|||
*
|
||||
* @return the list of snapshots
|
||||
*/
|
||||
Set<? extends VirtualInterface> listVirtualInterfacesForServer(String serverId);
|
||||
FluentIterable<? extends VirtualInterface> listOnServer(String serverId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -34,8 +32,10 @@ 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.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -44,17 +44,18 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see VirtualInterfaceApi
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VIRTUAL_INTERFACES)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface VirtualInterfaceAsyncApi {
|
||||
/**
|
||||
* @see VirtualInterfaceApi#listVirtualInterfacesForServer(String)
|
||||
* @see VirtualInterfaceApi#listOnServer(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("virtual_interfaces")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers/{server_id}/os-virtual-interfaces")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends VirtualInterface>> listVirtualInterfacesForServer(@PathParam("server_id") String serverId);
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends VirtualInterface>> listOnServer(@PathParam("server_id") String serverId);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -30,13 +29,18 @@ import org.jclouds.openstack.nova.v2_0.options.CreateVolumeSnapshotOptions;
|
|||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Volumes.
|
||||
* <p/>
|
||||
*
|
||||
* @see VolumeAsyncApi
|
||||
* @see org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUMES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface VolumeApi {
|
||||
|
@ -45,42 +49,42 @@ public interface VolumeApi {
|
|||
*
|
||||
* @return the list of snapshots
|
||||
*/
|
||||
Set<? extends Volume> listVolumes();
|
||||
FluentIterable<? extends Volume> list();
|
||||
|
||||
/**
|
||||
* Returns a detailed list of volumes.
|
||||
*
|
||||
* @return the list of volumes.
|
||||
*/
|
||||
Set<? extends Volume> listVolumesInDetail();
|
||||
FluentIterable<? extends Volume> listInDetail();
|
||||
|
||||
/**
|
||||
* Return data about the given volume.
|
||||
*
|
||||
* @return details of a specific snapshot.
|
||||
*/
|
||||
Volume getVolume(String volumeId);
|
||||
Volume get(String volumeId);
|
||||
|
||||
/**
|
||||
* Creates a new Snapshot
|
||||
*
|
||||
* @return the new Snapshot
|
||||
*/
|
||||
Volume createVolume(int sizeGB, CreateVolumeOptions... options);
|
||||
Volume create(int sizeGB, CreateVolumeOptions... options);
|
||||
|
||||
/**
|
||||
* Delete a snapshot.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean deleteVolume(String volumeId);
|
||||
boolean delete(String volumeId);
|
||||
|
||||
/**
|
||||
* List volume attachments for a given instance.
|
||||
*
|
||||
* @return all Floating IPs
|
||||
*/
|
||||
Set<? extends VolumeAttachment> listAttachmentsOnServer(String serverId);
|
||||
FluentIterable<? extends VolumeAttachment> listAttachmentsOnServer(String serverId);
|
||||
|
||||
/**
|
||||
* Get a specific attached volume.
|
||||
|
@ -108,14 +112,14 @@ public interface VolumeApi {
|
|||
*
|
||||
* @return the list of snapshots
|
||||
*/
|
||||
Set<? extends VolumeSnapshot> listSnapshots();
|
||||
FluentIterable<? extends VolumeSnapshot> listSnapshots();
|
||||
|
||||
/**
|
||||
* Returns a summary list of snapshots.
|
||||
*
|
||||
* @return the list of snapshots
|
||||
*/
|
||||
Set<? extends VolumeSnapshot> listSnapshotsInDetail();
|
||||
FluentIterable<? extends VolumeSnapshot> listSnapshotsInDetail();
|
||||
|
||||
/**
|
||||
* Return data about the given snapshot.
|
||||
|
@ -136,6 +140,6 @@ public interface VolumeApi {
|
|||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
Boolean deleteSnapshot(String snapshotId);
|
||||
boolean deleteSnapshot(String snapshotId);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -44,10 +42,12 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.annotations.WrapWith;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUMES)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
|
@ -70,8 +71,8 @@ public interface VolumeAsyncApi {
|
|||
@Path("/os-volumes")
|
||||
@SelectJson("volumes")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Volume>> listVolumes();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends Volume>> list();
|
||||
|
||||
/**
|
||||
* Returns a detailed list of volumes.
|
||||
|
@ -82,8 +83,8 @@ public interface VolumeAsyncApi {
|
|||
@Path("/os-volumes/detail")
|
||||
@SelectJson("volumes")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Volume>> listVolumesInDetail();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends Volume>> listInDetail();
|
||||
|
||||
/**
|
||||
* Return data about the given volume.
|
||||
|
@ -95,7 +96,7 @@ public interface VolumeAsyncApi {
|
|||
@SelectJson("volume")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Volume> getVolume(@PathParam("id") String volumeId);
|
||||
ListenableFuture<? extends Volume> get(@PathParam("id") String volumeId);
|
||||
|
||||
/**
|
||||
* Creates a new volume
|
||||
|
@ -108,7 +109,7 @@ public interface VolumeAsyncApi {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(CreateVolumeOptions.class)
|
||||
ListenableFuture<? extends Volume> createVolume(@PayloadParam("size") int sizeGB, CreateVolumeOptions... options);
|
||||
ListenableFuture<? extends Volume> create(@PayloadParam("size") int sizeGB, CreateVolumeOptions... options);
|
||||
|
||||
/**
|
||||
* Delete a volume.
|
||||
|
@ -119,7 +120,7 @@ public interface VolumeAsyncApi {
|
|||
@Path("/os-volumes/{id}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> deleteVolume(@PathParam("id") String volumeId);
|
||||
ListenableFuture<Boolean> delete(@PathParam("id") String volumeId);
|
||||
|
||||
/**
|
||||
* List volume attachments for a given instance.
|
||||
|
@ -130,8 +131,8 @@ public interface VolumeAsyncApi {
|
|||
@Path("/servers/{server_id}/os-volume_attachments")
|
||||
@SelectJson("volumeAttachments")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends VolumeAttachment>> listAttachmentsOnServer(@PathParam("server_id") String serverId);
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends VolumeAttachment>> listAttachmentsOnServer(@PathParam("server_id") String serverId);
|
||||
|
||||
/**
|
||||
* Get a specific attached volume.
|
||||
|
@ -180,8 +181,8 @@ public interface VolumeAsyncApi {
|
|||
@Path("/os-snapshots")
|
||||
@SelectJson("snapshots")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends VolumeSnapshot>> listSnapshots();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends VolumeSnapshot>> listSnapshots();
|
||||
|
||||
/**
|
||||
* Returns a summary list of snapshots.
|
||||
|
@ -192,8 +193,8 @@ public interface VolumeAsyncApi {
|
|||
@Path("/os-snapshots/detail")
|
||||
@SelectJson("snapshots")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends VolumeSnapshot>> listSnapshotsInDetail();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends VolumeSnapshot>> listSnapshotsInDetail();
|
||||
|
||||
/**
|
||||
* Return data about the given snapshot.
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.VolumeType;
|
||||
import org.jclouds.openstack.nova.v2_0.options.CreateVolumeTypeOptions;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Volume Type features
|
||||
|
@ -39,21 +39,21 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
* @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"/>
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUME_TYPES)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface VolumeTypeApi {
|
||||
|
||||
/**
|
||||
* @return set of all volume types
|
||||
*/
|
||||
Set<? extends VolumeType> listVolumeTypes();
|
||||
FluentIterable<? extends VolumeType> list();
|
||||
|
||||
/**
|
||||
* @param id the id of the volume type to retrieve
|
||||
* @return the requested volume type
|
||||
*/
|
||||
VolumeType getVolumeType(String id);
|
||||
VolumeType get(String id);
|
||||
|
||||
/**
|
||||
* Creates a new volume type
|
||||
|
@ -62,23 +62,23 @@ public interface VolumeTypeApi {
|
|||
* @param options optional settings for the new volume type
|
||||
* @return the new volume type
|
||||
*/
|
||||
VolumeType createVolumeType(String name, CreateVolumeTypeOptions... options);
|
||||
VolumeType create(String name, CreateVolumeTypeOptions... options);
|
||||
|
||||
/**
|
||||
* Deletes a volume type
|
||||
*/
|
||||
Boolean deleteVolumeType(String id);
|
||||
boolean delete(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);
|
||||
Map<String, String> getExtraSpecs(String id);
|
||||
|
||||
/**
|
||||
* Creates or updates the extra metadata for a given flavor
|
||||
*/
|
||||
Boolean setAllExtraSpecs(String id, Map<String, String> specs);
|
||||
boolean updateExtraSpecs(String id, Map<String, String> specs);
|
||||
|
||||
/**
|
||||
* Retrieve a single extra spec value
|
||||
|
@ -95,7 +95,7 @@ public interface VolumeTypeApi {
|
|||
* @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);
|
||||
boolean updateExtraSpec(String id, String key, String value);
|
||||
|
||||
/**
|
||||
* Deletes an existing extra spec
|
||||
|
@ -103,5 +103,5 @@ public interface VolumeTypeApi {
|
|||
* @param id the id of the volume type
|
||||
* @param key the key of the extra spec to delete
|
||||
*/
|
||||
Boolean deleteExtraSpec(String id, String key);
|
||||
boolean deleteExtraSpec(String id, String key);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -46,11 +45,13 @@ import org.jclouds.rest.annotations.SkipEncoding;
|
|||
import org.jclouds.rest.annotations.Unwrap;
|
||||
import org.jclouds.rest.annotations.WrapWith;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
import org.jclouds.rest.functions.ReturnEmptyFluentIterableOnNotFoundOr404;
|
||||
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.annotations.Beta;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +60,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adam Lowe
|
||||
* @see VolumeTypeApi
|
||||
*/
|
||||
@Beta
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUME_TYPES)
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
|
@ -67,58 +69,58 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface VolumeTypeAsyncApi {
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#listVolumeTypes
|
||||
* @see VolumeTypeApi#list
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("volume_types")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends VolumeType>> listVolumeTypes();
|
||||
@ExceptionParser(ReturnEmptyFluentIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends FluentIterable<? extends VolumeType>> list();
|
||||
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#getVolumeType
|
||||
* @see VolumeTypeApi#get
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@SelectJson("volume_type")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends VolumeType> getVolumeType(@PathParam("id") String id);
|
||||
ListenableFuture<? extends VolumeType> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#createVolumeType
|
||||
* @see VolumeTypeApi#create
|
||||
*/
|
||||
@POST
|
||||
@SelectJson("volume_type")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@WrapWith("volume_type")
|
||||
ListenableFuture<? extends VolumeType> createVolumeType(@PayloadParam("name") String name, CreateVolumeTypeOptions... options);
|
||||
ListenableFuture<? extends VolumeType> create(@PayloadParam("name") String name, CreateVolumeTypeOptions... options);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#deleteVolumeType
|
||||
* @see VolumeTypeApi#delete
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
ListenableFuture<Boolean> deleteVolumeType(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> delete(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#getAllExtraSpecs(String)
|
||||
* @see VolumeTypeApi#getExtraSpecs(String)
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extra_specs")
|
||||
@Path("/{id}/extra_specs")
|
||||
@ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class)
|
||||
ListenableFuture<Map<String, String>> getAllExtraSpecs(@PathParam("id") String id);
|
||||
ListenableFuture<Map<String, String>> getExtraSpecs(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#setAllExtraSpecs(String, java.util.Map)
|
||||
* @see VolumeTypeApi#updateExtraSpecs(String, java.util.Map)
|
||||
*/
|
||||
@POST
|
||||
@Path("/{id}/extra_specs")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ListenableFuture<Boolean> setAllExtraSpecs(@PathParam("id") String id, @PayloadParam("extra_specs") Map<String, String> specs);
|
||||
ListenableFuture<Boolean> updateExtraSpecs(@PathParam("id") String id, @PayloadParam("extra_specs") Map<String, String> specs);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#getExtraSpec(String, String)
|
||||
|
@ -130,14 +132,14 @@ public interface VolumeTypeAsyncApi {
|
|||
ListenableFuture<String> getExtraSpec(@PathParam("id") String id, @PathParam("key") String key);
|
||||
|
||||
/**
|
||||
* @see VolumeTypeApi#setExtraSpec(String, String, String)
|
||||
* @see VolumeTypeApi#updateExtraSpec(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,
|
||||
ListenableFuture<Boolean> updateExtraSpec(@PathParam("id") String id,
|
||||
@PathParam("key") @PayloadParam("key") String key,
|
||||
@PayloadParam("value") String value);
|
||||
|
||||
|
|
|
@ -18,20 +18,22 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Flavors via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see FlavorApi
|
||||
* @see FlavorAsyncApi
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Flavors-d1e4180.html"
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/List_Flavors-d1e4188.html"
|
||||
* />
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
|
@ -43,14 +45,18 @@ public interface FlavorApi {
|
|||
*
|
||||
* @return all flavors (IDs, names, links)
|
||||
*/
|
||||
Set<? extends Resource> listFlavors();
|
||||
PagedIterable<? extends Resource> list();
|
||||
|
||||
PaginatedCollection<? extends Resource> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List all flavors (all details)
|
||||
*
|
||||
* @return all flavors (all details)
|
||||
*/
|
||||
Set<? extends Flavor> listFlavorsInDetail();
|
||||
PagedIterable<? extends Flavor> listInDetail();
|
||||
|
||||
PaginatedCollection<? extends Flavor> listInDetail(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List details of the specified flavor
|
||||
|
@ -59,6 +65,6 @@ public interface FlavorApi {
|
|||
* id of the flavor
|
||||
* @return flavor or null if not found
|
||||
*/
|
||||
Flavor getFlavor(String id);
|
||||
Flavor get(String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,22 +18,28 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.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.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavorDetails;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavors;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -44,43 +50,65 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*
|
||||
* @see FlavorApi
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Flavors-d1e4180.html"
|
||||
* />
|
||||
* @author Jeremy Daggett TODO: Need a ListFlavorOptions class
|
||||
* minDisk=minDiskInGB& minRam=minRamInMB& marker=markerID&limit=int
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/List_Flavors-d1e4188.html"
|
||||
* >docs</a>
|
||||
* @author Jeremy Daggett TODO: Need a ListFlavorOptions class minDisk=minDiskInGB&
|
||||
* minRam=minRamInMB& marker=markerID&limit=int
|
||||
*/
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface FlavorAsyncApi {
|
||||
|
||||
/**
|
||||
* @see FlavorApi#listFlavors
|
||||
* @see FlavorApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("flavors")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Resource>> listFlavors();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseFlavors.class)
|
||||
@Transform(ParseFlavors.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Resource>> list();
|
||||
|
||||
/** @see FlavorApi#list(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseFlavors.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Resource>> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* @see FlavorApi#listFlavorsInDetail
|
||||
* @see FlavorApi#listInDetail()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("flavors")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors/detail")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Flavor>> listFlavorsInDetail();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseFlavorDetails.class)
|
||||
@Transform(ParseFlavorDetails.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Flavor>> listInDetail();
|
||||
|
||||
/** @see FlavorApi#listInDetail(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors/detail")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseFlavorDetails.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Flavor>> listInDetail(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* @see FlavorApi#getFlavor
|
||||
* @see FlavorApi#get
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("flavor")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Flavor> getFlavor(@PathParam("id") String id);
|
||||
ListenableFuture<? extends Flavor> get(@PathParam("id") String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,14 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Image;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Images.
|
||||
|
@ -43,14 +45,18 @@ public interface ImageApi {
|
|||
*
|
||||
* @return all images (IDs, names, links)
|
||||
*/
|
||||
Set<? extends Resource> listImages();
|
||||
PagedIterable<? extends Resource> list();
|
||||
|
||||
PaginatedCollection<? extends Resource> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List all images (all details)
|
||||
*
|
||||
* @return all images (all details)
|
||||
*/
|
||||
Set<? extends Image> listImagesInDetail();
|
||||
PagedIterable<? extends Image> listInDetail();
|
||||
|
||||
PaginatedCollection<? extends Image> listInDetail(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List details of the specified image
|
||||
|
@ -59,7 +65,7 @@ public interface ImageApi {
|
|||
* id of the server
|
||||
* @return server or null if not found
|
||||
*/
|
||||
Image getImage(String id);
|
||||
Image get(String id);
|
||||
|
||||
/**
|
||||
* Delete the specified image
|
||||
|
@ -68,6 +74,6 @@ public interface ImageApi {
|
|||
* id of the image
|
||||
* @return server or null if not found
|
||||
*/
|
||||
void deleteImage(String id);
|
||||
void delete(String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -27,14 +25,22 @@ import javax.ws.rs.Path;
|
|||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Image;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseImageDetails;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseImages;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
||||
|
@ -52,42 +58,64 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface ImageAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ImageApi#listImages
|
||||
* @see ImageApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("images")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Resource>> listImages();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Transform(ParseImages.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Resource>> list();
|
||||
|
||||
/** @see ImageApi#list(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Resource>> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* @see ImageApi#listImagesInDetail
|
||||
* @see ImageApi#listInDetail()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("images")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/detail")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Image>> listImagesInDetail();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseImageDetails.class)
|
||||
@Transform(ParseImageDetails.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Image>> listInDetail();
|
||||
|
||||
/** @see ImageApi#listInDetail(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/detail")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseImageDetails.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Image>> listInDetail(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* @see ImageApi#getImage
|
||||
* @see ImageApi#get
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("image")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Image> getImage(@PathParam("id") String id);
|
||||
ListenableFuture<? extends Image> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ImageApi#deleteImage
|
||||
* @see ImageApi#delete
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/{id}")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> deleteImage(@PathParam("id") String id);
|
||||
ListenableFuture<Void> delete(@PathParam("id") String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,16 +18,18 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.RebootType;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.ServerCreated;
|
||||
import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions;
|
||||
import org.jclouds.openstack.nova.v2_0.options.RebuildServerOptions;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Server.
|
||||
|
@ -47,14 +49,18 @@ public interface ServerApi {
|
|||
*
|
||||
* @return all servers (IDs, names, links)
|
||||
*/
|
||||
Set<? extends Resource> listServers();
|
||||
PagedIterable<? extends Resource> list();
|
||||
|
||||
PaginatedCollection<? extends Resource> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List all servers (all details)
|
||||
*
|
||||
* @return all servers (all details)
|
||||
*/
|
||||
Set<? extends Server> listServersInDetail();
|
||||
PagedIterable<? extends Server> listInDetail();
|
||||
|
||||
PaginatedCollection<? extends Server> listInDetail(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* List details of the specified server
|
||||
|
@ -63,7 +69,7 @@ public interface ServerApi {
|
|||
* id of the server
|
||||
* @return server or null if not found
|
||||
*/
|
||||
Server getServer(String id);
|
||||
Server get(String id);
|
||||
|
||||
/**
|
||||
* Create a new server
|
||||
|
@ -81,7 +87,7 @@ public interface ServerApi {
|
|||
*/
|
||||
// blocking call
|
||||
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
|
||||
ServerCreated createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
|
||||
ServerCreated create(String name, String imageRef, String flavorRef, CreateServerOptions... options);
|
||||
|
||||
/**
|
||||
* Terminate and delete a server.
|
||||
|
@ -90,7 +96,7 @@ public interface ServerApi {
|
|||
* id of the server
|
||||
* @return True if successful, False otherwise
|
||||
*/
|
||||
Boolean deleteServer(String id);
|
||||
Boolean delete(String id);
|
||||
|
||||
/**
|
||||
* Start a server
|
||||
|
@ -98,7 +104,7 @@ public interface ServerApi {
|
|||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void startServer(String id);
|
||||
void start(String id);
|
||||
|
||||
/**
|
||||
* Stop a server
|
||||
|
@ -106,7 +112,7 @@ public interface ServerApi {
|
|||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void stopServer(String id);
|
||||
void stop(String id);
|
||||
|
||||
/**
|
||||
* Reboot a server.
|
||||
|
@ -116,7 +122,7 @@ public interface ServerApi {
|
|||
* @param rebootType
|
||||
* The type of reboot to perform (Hard/Soft)
|
||||
*/
|
||||
void rebootServer(String id, RebootType rebootType);
|
||||
void reboot(String id, RebootType rebootType);
|
||||
|
||||
/**
|
||||
* Resize a server to a new flavor size.
|
||||
|
@ -126,7 +132,7 @@ public interface ServerApi {
|
|||
* @param flavorId
|
||||
* id of the new flavor to use
|
||||
*/
|
||||
void resizeServer(String id, String flavorId);
|
||||
void resize(String id, String flavorId);
|
||||
|
||||
/**
|
||||
* Confirm a resize operation.
|
||||
|
@ -134,7 +140,7 @@ public interface ServerApi {
|
|||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void confirmResizeServer(String id);
|
||||
void confirmResize(String id);
|
||||
|
||||
/**
|
||||
* Revert a resize operation.
|
||||
|
@ -142,7 +148,7 @@ public interface ServerApi {
|
|||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void revertResizeServer(String id);
|
||||
void revertResize(String id);
|
||||
|
||||
/**
|
||||
* Rebuild a server.
|
||||
|
@ -152,7 +158,7 @@ public interface ServerApi {
|
|||
* @param options
|
||||
* Optional parameters to the rebuilding operation.
|
||||
*/
|
||||
void rebuildServer(String id, RebuildServerOptions... options);
|
||||
void rebuild(String id, RebuildServerOptions... options);
|
||||
|
||||
/**
|
||||
* Change the administrative password to a server.
|
||||
|
@ -172,7 +178,7 @@ public interface ServerApi {
|
|||
* @param newName
|
||||
* The new name for the server
|
||||
*/
|
||||
void renameServer(String id, String newName);
|
||||
void rename(String id, String newName);
|
||||
|
||||
/**
|
||||
* Create an image from a server.
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -30,14 +28,20 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.keystone.v2_0.functions.ReturnEmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.RebootType;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.ServerCreated;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.ParseImageIdFromLocationHeader;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseServerDetails;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseServers;
|
||||
import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions;
|
||||
import org.jclouds.openstack.nova.v2_0.options.RebuildServerOptions;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
|
@ -46,9 +50,10 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.annotations.Unwrap;
|
||||
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
|
@ -69,123 +74,146 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
public interface ServerAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ServerApi#listServers
|
||||
* @see ServerApi#list()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("servers")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Resource>> listServers();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseServers.class)
|
||||
@Transform(ParseServers.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Resource>> list();
|
||||
|
||||
/** @see ServerApi#list(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseServers.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Resource>> list(PaginationOptions options);
|
||||
|
||||
/**
|
||||
* @see ServerApi#listServersInDetail
|
||||
* @see ServerApi#listInDetail()
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("servers")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers/detail")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Set<? extends Server>> listServersInDetail();
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseServerDetails.class)
|
||||
@Transform(ParseServerDetails.ToPagedIterable.class)
|
||||
@ExceptionParser(ReturnEmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<? extends Server>> listInDetail();
|
||||
|
||||
/** @see ServerApi#listInDetail(PaginationOptions) */
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers/detail")
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@ResponseParser(ParseServerDetails.class)
|
||||
@ExceptionParser(ReturnEmptyPaginatedCollectionOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PaginatedCollection<? extends Server>> listInDetail(PaginationOptions options);
|
||||
|
||||
|
||||
/**
|
||||
* @see ServerApi#getServer
|
||||
* @see ServerApi#get
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("server")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Server> getServer(@PathParam("id") String id);
|
||||
ListenableFuture<? extends Server> get(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#deleteServer
|
||||
* @see ServerApi#delete
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes
|
||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||
@Path("/servers/{id}")
|
||||
ListenableFuture<Boolean> deleteServer(@PathParam("id") String id);
|
||||
ListenableFuture<Boolean> delete(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#startServer
|
||||
* @see ServerApi#start
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"os-start\":null}")
|
||||
ListenableFuture<Void> startServer(@PathParam("id") String id);
|
||||
ListenableFuture<Void> start(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#stopServer
|
||||
* @see ServerApi#stop
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"os-stop\":null}")
|
||||
ListenableFuture<Void> stopServer(@PathParam("id") String id);
|
||||
ListenableFuture<Void> stop(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#rebootServer
|
||||
* @see ServerApi#reboot
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D")
|
||||
ListenableFuture<Void> rebootServer(@PathParam("id") String id, @PayloadParam("type") RebootType rebootType);
|
||||
ListenableFuture<Void> reboot(@PathParam("id") String id, @PayloadParam("type") RebootType rebootType);
|
||||
|
||||
/**
|
||||
* @see ServerApi#resizeServer
|
||||
* @see ServerApi#resize
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"resize\":%7B\"flavorRef\":{flavorId}%7D%7D")
|
||||
ListenableFuture<Void> resizeServer(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId);
|
||||
ListenableFuture<Void> resize(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId);
|
||||
|
||||
/**
|
||||
* @see ServerApi#confirmResizeServer
|
||||
* @see ServerApi#confirmResize
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"confirmResize\":null}")
|
||||
ListenableFuture<Void> confirmResizeServer(@PathParam("id") String id);
|
||||
ListenableFuture<Void> confirmResize(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#revertResizeServer
|
||||
* @see ServerApi#revertResize
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("{\"revertResize\":null}")
|
||||
ListenableFuture<Void> revertResizeServer(@PathParam("id") String id);
|
||||
ListenableFuture<Void> revertResize(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see ServerApi#createServer
|
||||
* @see ServerApi#create
|
||||
*/
|
||||
@POST
|
||||
@Unwrap
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/servers")
|
||||
@MapBinder(CreateServerOptions.class)
|
||||
ListenableFuture<ServerCreated> createServer(@PayloadParam("name") String name, @PayloadParam("imageRef") String imageRef,
|
||||
ListenableFuture<ServerCreated> create(@PayloadParam("name") String name, @PayloadParam("imageRef") String imageRef,
|
||||
@PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see ServerApi#rebuildServer
|
||||
* @see ServerApi#rebuild
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
@Consumes
|
||||
@MapBinder(RebuildServerOptions.class)
|
||||
ListenableFuture<Void> rebuildServer(@PathParam("id") String id, RebuildServerOptions... options);
|
||||
ListenableFuture<Void> rebuild(@PathParam("id") String id, RebuildServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see ServerApi#changeAdminPass
|
||||
|
@ -198,14 +226,14 @@ public interface ServerAsyncApi {
|
|||
ListenableFuture<Void> changeAdminPass(@PathParam("id") String id, @PayloadParam("adminPass") String adminPass);
|
||||
|
||||
/**
|
||||
* @see ServerApi#renameServer
|
||||
* @see ServerApi#rename
|
||||
*/
|
||||
@PUT
|
||||
@Path("/servers/{id}")
|
||||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D")
|
||||
ListenableFuture<Void> renameServer(@PathParam("id") String id, @PayloadParam("name") String newName);
|
||||
ListenableFuture<Void> rename(@PathParam("id") String id, @PayloadParam("name") String newName);
|
||||
|
||||
/**
|
||||
* @see ServerApi#createImageFromServer
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavorDetails.Flavors;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseFlavorDetails extends ParseJson<Flavors<? extends Flavor>> {
|
||||
static class Flavors<T extends Flavor> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "flavors", "flavors_links" })
|
||||
protected Flavors(Iterable<T> flavors, Iterable<Link> flavors_links) {
|
||||
super(flavors, flavors_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseFlavorDetails(Json json) {
|
||||
super(json, new TypeLiteral<Flavors<? extends Flavor>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Flavor, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Flavor>> markerToNextForCallingArg0(final String zone) {
|
||||
final FlavorApi flavorApi = api.getFlavorApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Flavor>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Flavor> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(flavorApi.listInDetail(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listFlavorsInDetail()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavors.Flavors;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseFlavors extends ParseJson<Flavors<? extends Resource>> {
|
||||
static class Flavors<T extends Resource> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "flavors", "flavors_links" })
|
||||
protected Flavors(Iterable<T> flavors, Iterable<Link> flavors_links) {
|
||||
super(flavors, flavors_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseFlavors(Json json) {
|
||||
super(json, new TypeLiteral<Flavors<? extends Resource>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Resource, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Resource>> markerToNextForCallingArg0(final String zone) {
|
||||
final FlavorApi flavorApi = api.getFlavorApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Resource>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Resource> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(flavorApi.list(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listFlavors()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Image;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseImageDetails.Images;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseImageDetails extends ParseJson<Images<? extends Image>> {
|
||||
static class Images<T extends Image> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "images", "images_links" })
|
||||
protected Images(Iterable<T> images, Iterable<Link> images_links) {
|
||||
super(images, images_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseImageDetails(Json json) {
|
||||
super(json, new TypeLiteral<Images<? extends Image>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Image, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Image>> markerToNextForCallingArg0(final String zone) {
|
||||
final ImageApi imageApi = api.getImageApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Image>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Image> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(imageApi.listInDetail(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listInDetail()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseImages.Images;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseImages extends ParseJson<Images<? extends Resource>> {
|
||||
static class Images<T extends Resource> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "images", "images_links" })
|
||||
protected Images(Iterable<T> images, Iterable<Link> images_links) {
|
||||
super(images, images_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseImages(Json json) {
|
||||
super(json, new TypeLiteral<Images<? extends Resource>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Resource, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Resource>> markerToNextForCallingArg0(final String zone) {
|
||||
final ImageApi imageApi = api.getImageApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Resource>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Resource> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(imageApi.list(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "list()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
|
||||
import org.jclouds.json.internal.GsonWrapper;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ParseKeyPairs implements Function<HttpResponse, FluentIterable<? extends KeyPair>> {
|
||||
private final ParseFirstJsonValueNamed<FluentIterable<Wrapper>> parser;
|
||||
|
||||
private static class Wrapper implements Supplier<KeyPair> {
|
||||
private KeyPair keypair;
|
||||
|
||||
@Override
|
||||
public KeyPair get() {
|
||||
return keypair;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseKeyPairs(GsonWrapper gsonView) {
|
||||
this.parser = new ParseFirstJsonValueNamed<FluentIterable<Wrapper>>(checkNotNull(gsonView, "gsonView"),
|
||||
new TypeLiteral<FluentIterable<Wrapper>>() {
|
||||
}, "keypairs");
|
||||
}
|
||||
|
||||
public FluentIterable<? extends KeyPair> apply(HttpResponse response) {
|
||||
checkNotNull(response, "response");
|
||||
return parser.apply(response).transform(Suppliers.<KeyPair> supplierFunction());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseServerDetails.Servers;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseServerDetails extends ParseJson<Servers<? extends Server>> {
|
||||
static class Servers<T extends Server> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "servers", "servers_links" })
|
||||
protected Servers(Iterable<T> servers, Iterable<Link> servers_links) {
|
||||
super(servers, servers_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseServerDetails(Json json) {
|
||||
super(json, new TypeLiteral<Servers<? extends Server>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Server, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Server>> markerToNextForCallingArg0(final String zone) {
|
||||
final ServerApi serverApi = api.getServerApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Server>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Server> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(serverApi.listInDetail(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "listInDetail()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.internal.ParseServers.Servers;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* boiler plate until we determine a better way
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class ParseServers extends ParseJson<Servers<? extends Resource>> {
|
||||
static class Servers<T extends Resource> extends PaginatedCollection<T> {
|
||||
|
||||
@ConstructorProperties({ "servers", "servers_links" })
|
||||
protected Servers(Iterable<T> servers, Iterable<Link> servers_links) {
|
||||
super(servers, servers_links);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseServers(Json json) {
|
||||
super(json, new TypeLiteral<Servers<? extends Resource>>() {
|
||||
});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Resource, ToPagedIterable> {
|
||||
|
||||
private final NovaApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(NovaApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Resource>> markerToNextForCallingArg0(final String zone) {
|
||||
final ServerApi serverApi = api.getServerApiForZone(zone);
|
||||
return new Function<Object, IterableWithMarker<Resource>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public IterableWithMarker<Resource> apply(Object input) {
|
||||
return IterableWithMarker.class.cast(serverApi.list(marker(input.toString())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "list()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,7 @@ public class CreateBackupOfServerOptions implements MapBinder {
|
|||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
|
||||
throw new IllegalStateException("createBackupOfServer is a POST operation");
|
||||
throw new IllegalStateException("createBackup is a POST operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -152,7 +152,7 @@ public class CreateServerOptions implements MapBinder {
|
|||
return string().toString();
|
||||
}
|
||||
|
||||
private class ServerRequest {
|
||||
static class ServerRequest {
|
||||
final String name;
|
||||
final String imageRef;
|
||||
final String flavorRef;
|
||||
|
|
|
@ -20,16 +20,16 @@ package org.jclouds.openstack.nova.v2_0.options;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.openstack.v2_0.options.BaseListOptions;
|
||||
import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
||||
|
||||
/**
|
||||
* Options used to control the amount of detail in the request.
|
||||
*
|
||||
* @see BaseListOptions
|
||||
* @see PaginationOptions
|
||||
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListOptions extends BaseListOptions {
|
||||
public class ListOptions extends PaginationOptions {
|
||||
|
||||
public static final ListOptions NONE = new ListOptions();
|
||||
|
||||
|
@ -56,8 +56,8 @@ public class ListOptions extends BaseListOptions {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ListOptions maxResults(int limit) {
|
||||
super.maxResults(limit);
|
||||
public ListOptions limit(int limit) {
|
||||
super.limit(limit);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
@ -66,8 +66,8 @@ public class ListOptions extends BaseListOptions {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ListOptions startAt(long offset) {
|
||||
super.startAt(offset);
|
||||
public ListOptions marker(String marker) {
|
||||
super.marker(marker);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -82,23 +82,23 @@ public class ListOptions extends BaseListOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#startAt(long)
|
||||
* @see PaginationOptions#marker(String)
|
||||
*/
|
||||
public static ListOptions startAt(long prefix) {
|
||||
public static ListOptions marker(String marker) {
|
||||
ListOptions options = new ListOptions();
|
||||
return options.startAt(prefix);
|
||||
return options.marker(marker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#maxResults(long)
|
||||
* @see PaginationOptions#limit(long)
|
||||
*/
|
||||
public static ListOptions maxResults(int maxKeys) {
|
||||
ListOptions options = new ListOptions();
|
||||
return options.maxResults(maxKeys);
|
||||
return options.limit(maxKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BaseListOptions#changesSince(Date)
|
||||
* @see PaginationOptions#changesSince(Date)
|
||||
*/
|
||||
public static ListOptions changesSince(Date since) {
|
||||
ListOptions options = new ListOptions();
|
||||
|
|
|
@ -67,7 +67,7 @@ public class FindSecurityGroupWithNameAndReturnTrue implements Predicate<AtomicR
|
|||
|
||||
logger.trace("looking for security group %s", securityGroupInZone.slashEncode());
|
||||
try {
|
||||
SecurityGroup returnVal = Iterables.find(api.get().listSecurityGroups(), new Predicate<SecurityGroup>() {
|
||||
SecurityGroup returnVal = Iterables.find(api.get().list(), new Predicate<SecurityGroup>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(SecurityGroup input) {
|
||||
|
|
|
@ -70,7 +70,7 @@ public class AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest extends Ba
|
|||
|
||||
assertEquals(apiWhenServersExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").listServers().toString(),
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").list().concat().toString(),
|
||||
new ParseServerListTest().expected().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public class AccessKeyAndSecretKeyAndTenantNamePropertyAuthenticationExpectTest
|
|||
|
||||
assertEquals(apiWhenServersExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").listServers().toString(),
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").list().concat().toString(),
|
||||
new ParseServerListTest().expected().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public class AccessKeyAndSecretKeyAuthenticationExpectTest extends BaseNovaApiEx
|
|||
|
||||
assertEquals(apiWhenServersExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").listServers().toString(),
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").list().concat().toString(),
|
||||
new ParseServerListTest().expected().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class PasswordAuthenticationExpectTest extends BaseNovaApiExpectTest {
|
|||
|
||||
assertEquals(apiWhenServersExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").listServers().toString(),
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").list().concat().toString(),
|
||||
new ParseServerListTest().expected().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public class PasswordAuthenticationWithTenantNameExpectTest extends BaseNovaApiE
|
|||
|
||||
assertEquals(apiWhenServersExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").listServers().toString(),
|
||||
assertEquals(apiWhenServersExist.getServerApiForZone("az-1.region-a.geo-1").list().concat().toString(),
|
||||
new ParseServerListTest().expected().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
|||
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
|
||||
.put(listImagesDetail, listImagesDetailResponse)
|
||||
.put(listDetail, listDetailResponse)
|
||||
.put(listFlavorsDetail, listFlavorsDetailResponse)
|
||||
.put(createServer, createServerResponse)
|
||||
.put(serverDetail, serverDetailResponse).build();
|
||||
|
@ -131,7 +131,7 @@ public class NovaComputeServiceAdapterExpectTest extends BaseNovaComputeServiceC
|
|||
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||
.put(extensionsOfNovaRequest, extensionsOfNovaResponse)
|
||||
.put(listImagesDetail, listImagesDetailResponse)
|
||||
.put(listDetail, listDetailResponse)
|
||||
.put(listFlavorsDetail, listFlavorsDetailResponse)
|
||||
.put(createServer, createServerResponse)
|
||||
.put(serverDetail, serverDetailResponse).build();
|
||||
|
|
|
@ -57,7 +57,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
|
||||
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||
.put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(listImagesDetail, listImagesDetailResponse)
|
||||
.put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(listDetail, listDetailResponse)
|
||||
.put(listServers, listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).build();
|
||||
|
||||
ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
|
||||
|
@ -88,7 +88,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/extensions").build(),
|
||||
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/extension_list_trystack.json"))
|
||||
.build())
|
||||
.put(listImagesDetail.toBuilder()
|
||||
.put(listDetail.toBuilder()
|
||||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/images/detail").build(),
|
||||
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/image_list_detail_trystack.json"))
|
||||
.build())
|
||||
|
@ -135,7 +135,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
assertTrue(apiWhenNoServersExist.listNodes().isEmpty());
|
||||
}
|
||||
|
||||
HttpRequest listSecurityGroups = HttpRequest
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/os-security-groups")
|
||||
|
@ -144,7 +144,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
|
||||
HttpResponse notFound = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
HttpRequest createSecurityGroupWithPrefixOnGroup = HttpRequest
|
||||
HttpRequest createWithPrefixOnGroup = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/os-security-groups")
|
||||
|
@ -158,7 +158,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
HttpResponse securityGroupCreated = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/securitygroup_created.json")).build();
|
||||
|
||||
HttpRequest createSecurityGroupRuleForDefaultPort22 = HttpRequest
|
||||
HttpRequest createRuleForDefaultPort22 = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/os-security-group-rules")
|
||||
|
@ -182,7 +182,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
HttpResponse securityGroupWithPort22 = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/securitygroup_details_port22.json")).build();
|
||||
|
||||
HttpRequest createKeyPair = HttpRequest
|
||||
HttpRequest create = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://nova-api.trystack.org:9774/v1.1/3456/os-keypairs")
|
||||
|
@ -210,15 +210,15 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
public void testCreateNodeWithGeneratedKeyPair() throws Exception {
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.putAll(defaultTemplateTryStack);
|
||||
requestResponseMap.put(listSecurityGroups, notFound);
|
||||
requestResponseMap.put(list, notFound);
|
||||
|
||||
requestResponseMap.put(createSecurityGroupWithPrefixOnGroup, securityGroupCreated);
|
||||
requestResponseMap.put(createWithPrefixOnGroup, securityGroupCreated);
|
||||
|
||||
requestResponseMap.put(createSecurityGroupRuleForDefaultPort22, securityGroupRuleCreated);
|
||||
requestResponseMap.put(createRuleForDefaultPort22, securityGroupRuleCreated);
|
||||
|
||||
requestResponseMap.put(getSecurityGroup, securityGroupWithPort22);
|
||||
|
||||
requestResponseMap.put(createKeyPair, keyPairWithPrivateKey);
|
||||
requestResponseMap.put(create, keyPairWithPrivateKey);
|
||||
|
||||
requestResponseMap.put(serverDetail, serverDetailResponse);
|
||||
|
||||
|
@ -266,11 +266,11 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
|
|||
public void testCreateNodeWhileUserSpecifiesKeyPair() throws Exception {
|
||||
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.putAll(defaultTemplateTryStack);
|
||||
requestResponseMap.put(listSecurityGroups, notFound);
|
||||
requestResponseMap.put(list, notFound);
|
||||
|
||||
requestResponseMap.put(createSecurityGroupWithPrefixOnGroup, securityGroupCreated);
|
||||
requestResponseMap.put(createWithPrefixOnGroup, securityGroupCreated);
|
||||
|
||||
requestResponseMap.put(createSecurityGroupRuleForDefaultPort22, securityGroupRuleCreated);
|
||||
requestResponseMap.put(createRuleForDefaultPort22, securityGroupRuleCreated);
|
||||
|
||||
requestResponseMap.put(getSecurityGroup, securityGroupWithPort22);
|
||||
|
||||
|
|
|
@ -106,12 +106,12 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
|
|||
"{\"badRequest\": {\"message\": \"AddressLimitExceeded: Address quota exceeded. You cannot allocate any more addresses\", \"code\": 400}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpRequest listFloatingIPs = HttpRequest.builder().method("GET").endpoint(
|
||||
HttpRequest list = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips")).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse listFloatingIPsResponseForUnassigned = HttpResponse.builder().statusCode(200).payload(
|
||||
HttpResponse listResponseForUnassigned = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResource("/floatingip_list.json")).build();
|
||||
|
||||
HttpRequest addFloatingIPRequest = addFloatingIPForAddress("10.0.0.5");
|
||||
|
@ -120,8 +120,8 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
|
|||
ImmutableMap.<HttpRequest, HttpResponse> builder().put(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess).put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(
|
||||
allocateFloatingIP, allocateFloatingIPResponse)
|
||||
.put(addFloatingIPRequest, addFloatingIPResponse).put(listFloatingIPs,
|
||||
listFloatingIPsResponseForUnassigned).build()).getContext().utils().injector()
|
||||
.put(addFloatingIPRequest, addFloatingIPResponse).put(list,
|
||||
listResponseForUnassigned).build()).getContext().utils().injector()
|
||||
.getInstance(AllocateAndAddFloatingIpToNode.class);
|
||||
|
||||
AtomicReference<NodeMetadata> nodeRef = new AtomicReference<NodeMetadata>(node);
|
||||
|
|
|
@ -56,7 +56,7 @@ public class CreateUniqueKeyPairTest {
|
|||
|
||||
expect(api.getKeyPairExtensionForZone("zone")).andReturn(optKeyApi).atLeastOnce();
|
||||
|
||||
expect(keyApi.createKeyPair("group-1")).andReturn(pair);
|
||||
expect(keyApi.create("group-1")).andReturn(pair);
|
||||
|
||||
replay(api, keyApi);
|
||||
|
||||
|
@ -88,9 +88,9 @@ public class CreateUniqueKeyPairTest {
|
|||
expect(api.getKeyPairExtensionForZone("zone")).andReturn((Optional) Optional.of(keyApi)).atLeastOnce();
|
||||
|
||||
expect(uniqueIdSupplier.get()).andReturn("1");
|
||||
expect(keyApi.createKeyPair("group-1")).andThrow(new IllegalStateException());
|
||||
expect(keyApi.create("group-1")).andThrow(new IllegalStateException());
|
||||
expect(uniqueIdSupplier.get()).andReturn("2");
|
||||
expect(keyApi.createKeyPair("group-2")).andReturn(pair);
|
||||
expect(keyApi.create("group-2")).andReturn(pair);
|
||||
|
||||
replay(api, keyApi, uniqueIdSupplier);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
|
@ -49,7 +50,8 @@ public class LoadFloatingIpsForInstanceTest {
|
|||
FloatingIP testIp = FloatingIP.builder().id("1").ip("1.1.1.1").fixedIp("10.1.1.1").instanceId("i-blah").build();
|
||||
|
||||
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
|
||||
expect(ipApi.listFloatingIPs()).andReturn((Set) ImmutableSet.<FloatingIP>of(testIp)).atLeastOnce();
|
||||
expect(ipApi.list()).andReturn((FluentIterable) FluentIterable.from(ImmutableSet.<FloatingIP> of(testIp)))
|
||||
.atLeastOnce();
|
||||
|
||||
replay(api);
|
||||
replay(ipApi);
|
||||
|
@ -69,7 +71,8 @@ public class LoadFloatingIpsForInstanceTest {
|
|||
|
||||
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
|
||||
|
||||
expect(ipApi.listFloatingIPs()).andReturn((Set) ImmutableSet.<FloatingIP>of()).atLeastOnce();
|
||||
expect(ipApi.list()).andReturn((FluentIterable) FluentIterable.from(ImmutableSet.<FloatingIP> of()))
|
||||
.atLeastOnce();
|
||||
|
||||
replay(api);
|
||||
replay(ipApi);
|
||||
|
@ -90,9 +93,8 @@ public class LoadFloatingIpsForInstanceTest {
|
|||
|
||||
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
|
||||
|
||||
expect(ipApi.listFloatingIPs()).andReturn(
|
||||
(Set) ImmutableSet.<FloatingIP>of(FloatingIP.builder().id("1").ip("1.1.1.1").build()))
|
||||
.atLeastOnce();
|
||||
expect(ipApi.list()).andReturn((FluentIterable) FluentIterable.from(ImmutableSet.<FloatingIP> of(FloatingIP.builder().id("1").ip("1.1.1.1").build())))
|
||||
.atLeastOnce();
|
||||
|
||||
replay(api);
|
||||
replay(ipApi);
|
||||
|
|
|
@ -45,12 +45,12 @@ import com.google.inject.Injector;
|
|||
public class GetImageWhenImageInZoneHasActiveStatusPredicateWithResultExpectTest extends
|
||||
BaseNovaComputeServiceContextExpectTest<Injector> {
|
||||
|
||||
private final HttpResponse listImagesDetailImageExtensionResponse = HttpResponse.builder().statusCode(200)
|
||||
private final HttpResponse listDetailImageExtensionResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list_detail_imageextension.json")).build();
|
||||
|
||||
private Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
|
||||
.put(keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess)
|
||||
.put(listImagesDetail, listImagesDetailImageExtensionResponse).build();
|
||||
.put(listDetail, listDetailImageExtensionResponse).build();
|
||||
|
||||
public void testReturnsFalseOnImageStatusSavingAndTrueOnActive() {
|
||||
Injector injector = requestsSendResponses(requestResponseMap);
|
||||
|
|
|
@ -47,249 +47,249 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
|
||||
public void testSuspend() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.suspendServer("1"));
|
||||
assertTrue(api.suspend("1"));
|
||||
}
|
||||
|
||||
public void testSuspendFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.suspendServer("1"));
|
||||
assertFalse(api.suspend("1"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AuthorizationException.class)
|
||||
public void testSuspendFailsNotAuthorized() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
|
||||
HttpResponse.builder().statusCode(403).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
api.suspendServer("1");
|
||||
api.suspend("1");
|
||||
}
|
||||
|
||||
public void testResume() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.resumeServer("1"));
|
||||
assertTrue(api.resume("1"));
|
||||
}
|
||||
|
||||
public void testResumeFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.resumeServer("1"));
|
||||
assertFalse(api.resume("1"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AuthorizationException.class)
|
||||
public void testResumeFailsNotAuthorized() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
|
||||
HttpResponse.builder().statusCode(403).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
api.resumeServer("1");
|
||||
api.resume("1");
|
||||
}
|
||||
|
||||
public void testLock() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "lock").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.lockServer("1"));
|
||||
assertTrue(api.lock("1"));
|
||||
}
|
||||
|
||||
public void testLockFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "lock").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.lockServer("1"));
|
||||
assertFalse(api.lock("1"));
|
||||
}
|
||||
|
||||
public void testUnlock() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "unlock").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.unlockServer("1"));
|
||||
assertTrue(api.unlock("1"));
|
||||
}
|
||||
|
||||
public void testUnlockFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "unlock").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.unlockServer("1"));
|
||||
assertFalse(api.unlock("1"));
|
||||
}
|
||||
|
||||
public void testPause() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "pause").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.pauseServer("1"));
|
||||
assertTrue(api.pause("1"));
|
||||
}
|
||||
|
||||
public void testPauseFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "pause").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.pauseServer("1"));
|
||||
assertFalse(api.pause("1"));
|
||||
}
|
||||
|
||||
public void testUnpause() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "unpause").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.unpauseServer("1"));
|
||||
assertTrue(api.unpause("1"));
|
||||
}
|
||||
|
||||
public void testUnpauseFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "unpause").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.unpauseServer("1"));
|
||||
assertFalse(api.unpause("1"));
|
||||
}
|
||||
|
||||
public void testMigrateServer() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "migrate").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.migrateServer("1"));
|
||||
assertTrue(api.migrate("1"));
|
||||
}
|
||||
|
||||
|
||||
public void testMigrateServerFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "migrate").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.migrateServer("1"));
|
||||
assertFalse(api.migrate("1"));
|
||||
}
|
||||
|
||||
public void testResetNetworkOfServer() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "resetNetwork").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.resetNetworkOfServer("1"));
|
||||
assertTrue(api.resetNetwork("1"));
|
||||
}
|
||||
|
||||
public void testResetNetworkOfServerFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "resetNetwork").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.resetNetworkOfServer("1"));
|
||||
assertFalse(api.resetNetwork("1"));
|
||||
}
|
||||
|
||||
public void testInjectNetworkInfoIntoServer() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "injectNetworkInfo").build(),
|
||||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.injectNetworkInfoIntoServer("1"));
|
||||
assertTrue(api.injectNetworkInfo("1"));
|
||||
}
|
||||
|
||||
public void testInjectNetworkInfoIntoServerFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "injectNetworkInfo").build(),
|
||||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.injectNetworkInfoIntoServer("1"));
|
||||
assertFalse(api.injectNetworkInfo("1"));
|
||||
}
|
||||
|
||||
public void testBackupServer() {
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
authenticatedGET().endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action").method("POST")
|
||||
|
@ -297,14 +297,14 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(202).addHeader("Location", "http://172.16.89.149:8774/v2/images/1976b3b3-409a-468d-b16c-a9172c341b46").build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
String imageId = api.createBackupOfServer("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
|
||||
String imageId = api.createBackup("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
|
||||
assertEquals(imageId, "1976b3b3-409a-468d-b16c-a9172c341b46");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||
public void testBackupServerFailNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
authenticatedGET().endpoint(endpoint).method("POST")
|
||||
|
@ -312,12 +312,12 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
api.createBackupOfServer("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
|
||||
api.createBackup("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
|
||||
}
|
||||
|
||||
public void testLiveMigrateServer() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "GONNAOVERWRITE")
|
||||
|
@ -325,12 +325,12 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(202).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.liveMigrateServer("1", "bighost", true, false));
|
||||
assertTrue(api.liveMigrate("1", "bighost", true, false));
|
||||
}
|
||||
|
||||
public void testLiveMigrateServerFailsNotFound() {
|
||||
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action");
|
||||
AdminActionsApi api = requestsSendResponses(
|
||||
ServerAdminApi api = requestsSendResponses(
|
||||
keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||
standardActionRequestBuilderVoidResponse(endpoint, "GONNAOVERWRITE")
|
||||
|
@ -338,7 +338,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(404).build()
|
||||
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.liveMigrateServer("1", "bighost", true, false));
|
||||
assertFalse(api.liveMigrate("1", "bighost", true, false));
|
||||
}
|
||||
|
||||
protected HttpRequest.Builder<?> standardActionRequestBuilderVoidResponse(URI endpoint, String actionName) {
|
||||
|
|
|
@ -53,7 +53,7 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
private ImageApi imageApi;
|
||||
private ServerApi serverApi;
|
||||
private ExtensionApi extensionApi;
|
||||
private Optional<? extends AdminActionsApi> apiOption;
|
||||
private Optional<? extends ServerAdminApi> apiOption;
|
||||
private String zone;
|
||||
|
||||
private String testServerId;
|
||||
|
@ -78,10 +78,10 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
protected void tearDown() {
|
||||
if (apiOption.isPresent()) {
|
||||
if (testServerId != null) {
|
||||
assertTrue(novaContext.getApi().getServerApiForZone(zone).deleteServer(testServerId));
|
||||
assertTrue(novaContext.getApi().getServerApiForZone(zone).delete(testServerId));
|
||||
}
|
||||
if (backupImageId != null) {
|
||||
imageApi.deleteImage(backupImageId);
|
||||
imageApi.delete(backupImageId);
|
||||
}
|
||||
}
|
||||
super.tearDown();
|
||||
|
@ -94,25 +94,25 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
|
||||
public void testSuspendAndResume() {
|
||||
if (apiOption.isPresent()) {
|
||||
AdminActionsApi api = apiOption.get();
|
||||
ServerAdminApi api = apiOption.get();
|
||||
|
||||
// Suspend-resume
|
||||
try {
|
||||
api.resumeServer(testServerId);
|
||||
api.resume(testServerId);
|
||||
fail("Resumed an active server!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
assertTrue(api.suspendServer(testServerId));
|
||||
assertTrue(api.suspend(testServerId));
|
||||
blockUntilServerInState(testServerId, serverApi, Status.SUSPENDED);
|
||||
try {
|
||||
api.suspendServer(testServerId);
|
||||
api.suspend(testServerId);
|
||||
fail("Suspended an already suspended server!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
assertTrue(api.resumeServer(testServerId));
|
||||
assertTrue(api.resume(testServerId));
|
||||
blockUntilServerInState(testServerId, serverApi, Status.ACTIVE);
|
||||
try {
|
||||
api.resumeServer(testServerId);
|
||||
api.resume(testServerId);
|
||||
fail("Resumed an already resumed server!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
|
@ -121,48 +121,48 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
|
||||
public void testLockAndUnlock() {
|
||||
if (apiOption.isPresent()) {
|
||||
AdminActionsApi api = apiOption.get();
|
||||
ServerAdminApi api = apiOption.get();
|
||||
|
||||
// TODO should we be able to double-lock (as it were)
|
||||
assertTrue(api.unlockServer(testServerId));
|
||||
assertTrue(api.unlockServer(testServerId));
|
||||
assertTrue(api.lockServer(testServerId));
|
||||
assertTrue(api.lockServer(testServerId));
|
||||
assertTrue(api.unlockServer(testServerId));
|
||||
assertTrue(api.unlockServer(testServerId));
|
||||
assertTrue(api.unlock(testServerId));
|
||||
assertTrue(api.unlock(testServerId));
|
||||
assertTrue(api.lock(testServerId));
|
||||
assertTrue(api.lock(testServerId));
|
||||
assertTrue(api.unlock(testServerId));
|
||||
assertTrue(api.unlock(testServerId));
|
||||
}
|
||||
}
|
||||
|
||||
public void testResetNetworkAndInjectNetworkInfo() {
|
||||
if (apiOption.isPresent()) {
|
||||
AdminActionsApi api = apiOption.get();
|
||||
assertTrue(api.resetNetworkOfServer(testServerId));
|
||||
assertTrue(api.injectNetworkInfoIntoServer(testServerId));
|
||||
ServerAdminApi api = apiOption.get();
|
||||
assertTrue(api.resetNetwork(testServerId));
|
||||
assertTrue(api.injectNetworkInfo(testServerId));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPauseAndUnpause() {
|
||||
if (apiOption.isPresent()) {
|
||||
AdminActionsApi api = apiOption.get();
|
||||
ServerAdminApi api = apiOption.get();
|
||||
|
||||
// Unlock and lock (double-checking error contitions too)
|
||||
try {
|
||||
api.unpauseServer(testServerId);
|
||||
api.unpause(testServerId);
|
||||
fail("Unpaused active server!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
assertTrue(api.pauseServer(testServerId));
|
||||
assertTrue(api.pause(testServerId));
|
||||
blockUntilServerInState(testServerId, serverApi, Status.PAUSED);
|
||||
try {
|
||||
api.pauseServer(testServerId);
|
||||
api.pause(testServerId);
|
||||
fail("paused a paused server!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
assertTrue(api.unpauseServer(testServerId));
|
||||
assertTrue(api.unpause(testServerId));
|
||||
blockUntilServerInState(testServerId, serverApi, Status.ACTIVE);
|
||||
try {
|
||||
api.unpauseServer(testServerId);
|
||||
api.unpause(testServerId);
|
||||
fail("Unpaused a server we just unpaused!");
|
||||
} catch (HttpResponseException e) {
|
||||
}
|
||||
|
@ -172,19 +172,19 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
@Test
|
||||
public void testCreateBackupOfServer() throws InterruptedException {
|
||||
if (apiOption.isPresent()) {
|
||||
backupImageId = apiOption.get().createBackupOfServer(testServerId, "jclouds-test-backup", BackupType.DAILY, 0,
|
||||
backupImageId = apiOption.get().createBackup(testServerId, "jclouds-test-backup", BackupType.DAILY, 0,
|
||||
CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("test", "metadata")));
|
||||
|
||||
assertNotNull(backupImageId);
|
||||
|
||||
// If we don't have extended task status, we'll have to wait here!
|
||||
if (extensionApi.getExtensionByAlias("OS-EXT-STS") == null) {
|
||||
if (extensionApi.get("OS-EXT-STS") == null) {
|
||||
Thread.sleep(30000);
|
||||
}
|
||||
|
||||
blockUntilServerInState(testServerId, serverApi, Status.ACTIVE);
|
||||
|
||||
Image backupImage = imageApi.getImage(backupImageId);
|
||||
Image backupImage = imageApi.get(backupImageId);
|
||||
assertEquals(backupImage.getId(), backupImageId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type_extra_specs.json")).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertEquals(api.getAllExtraSpecs("9"), ImmutableMap.of("test", "value1"));
|
||||
assertEquals(api.getMetadata("9"), ImmutableMap.of("test", "value1"));
|
||||
}
|
||||
|
||||
public void testGetAllExtraSpecsFailNotFound() {
|
||||
|
@ -62,7 +62,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(404).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.getAllExtraSpecs("9").isEmpty());
|
||||
assertTrue(api.getMetadata("9").isEmpty());
|
||||
}
|
||||
|
||||
public void testSetAllExtraSpecs() {
|
||||
|
@ -76,7 +76,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(200).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.setAllExtraSpecs("9", ImmutableMap.of("test1", "somevalue")));
|
||||
assertTrue(api.updateMetadata("9", ImmutableMap.of("test1", "somevalue")));
|
||||
}
|
||||
|
||||
public void testSetExtraSpec() {
|
||||
|
@ -90,7 +90,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(200).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.setExtraSpec("5", "test1", "somevalue"));
|
||||
assertTrue(api.updateMetadataEntry("5", "test1", "somevalue"));
|
||||
}
|
||||
|
||||
public void testGetExtraSpec() {
|
||||
|
@ -102,7 +102,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(200).payload(payloadFromStringWithContentType("{\"test1\":\"another value\"}", MediaType.APPLICATION_JSON)).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertEquals(api.getExtraSpec("5", "test1"), "another value");
|
||||
assertEquals(api.getMetadataKey("5", "test1"), "another value");
|
||||
}
|
||||
|
||||
public void testGetExtraSpecFailNotFound() {
|
||||
|
@ -114,7 +114,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(404).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertNull(api.getExtraSpec("5", "test1"));
|
||||
assertNull(api.getMetadataKey("5", "test1"));
|
||||
}
|
||||
|
||||
public void testDeleteExtraSpec() {
|
||||
|
@ -126,7 +126,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(200).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertTrue(api.deleteExtraSpec("5", "test1"));
|
||||
assertTrue(api.deleteMetadataKey("5", "test1"));
|
||||
}
|
||||
|
||||
public void testDeleteExtraSpecFailNotFound() {
|
||||
|
@ -138,7 +138,7 @@ public class FlavorExtraSpecsApiExpectTest extends BaseNovaApiExpectTest {
|
|||
HttpResponse.builder().statusCode(404).build()
|
||||
).getFlavorExtraSpecsExtensionForZone("az-1.region-a.geo-1").get();
|
||||
|
||||
assertFalse(api.deleteExtraSpec("5", "test1"));
|
||||
assertFalse(api.deleteMetadataKey("5", "test1"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
public void tearDown() {
|
||||
if (apiOption.isPresent() && testFlavor != null) {
|
||||
for(String key : testSpecs.keySet()) {
|
||||
assertTrue(apiOption.get().deleteExtraSpec(testFlavor.getId(), key));
|
||||
assertTrue(apiOption.get().deleteMetadataKey(testFlavor.getId(), key));
|
||||
}
|
||||
}
|
||||
super.tearDown();
|
||||
|
@ -73,15 +73,15 @@ public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
public void testCreateExtraSpecs() {
|
||||
if (apiOption.isPresent()) {
|
||||
FlavorExtraSpecsApi api = apiOption.get();
|
||||
testFlavor = Iterables.getLast(flavorApi.listFlavors());
|
||||
Map<String, String> before = api.getAllExtraSpecs(testFlavor.getId());
|
||||
testFlavor = Iterables.getLast(flavorApi.list().concat());
|
||||
Map<String, String> before = api.getMetadata(testFlavor.getId());
|
||||
assertNotNull(before);
|
||||
Map<String, String> specs = Maps.newHashMap(before);
|
||||
specs.putAll(testSpecs);
|
||||
assertTrue(api.setAllExtraSpecs(testFlavor.getId(), specs));
|
||||
assertEquals(api.getAllExtraSpecs(testFlavor.getId()), specs);
|
||||
assertTrue(api.updateMetadata(testFlavor.getId(), specs));
|
||||
assertEquals(api.getMetadata(testFlavor.getId()), specs);
|
||||
for (Map.Entry<String, String> entry : specs.entrySet()) {
|
||||
assertEquals(api.getExtraSpec(testFlavor.getId(), entry.getKey()), entry.getValue());
|
||||
assertEquals(api.getMetadataKey(testFlavor.getId(), entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,13 +91,13 @@ public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
if (apiOption.isPresent()) {
|
||||
FlavorExtraSpecsApi api = apiOption.get();
|
||||
for (String key : testSpecs.keySet()) {
|
||||
assertTrue(api.getAllExtraSpecs(testFlavor.getId()).containsKey(key));
|
||||
assertTrue(api.getMetadata(testFlavor.getId()).containsKey(key));
|
||||
}
|
||||
for (Resource flavor : flavorApi.listFlavors()) {
|
||||
Map<String, String> specs = api.getAllExtraSpecs(flavor.getId());
|
||||
for (Resource flavor : flavorApi.list().concat()) {
|
||||
Map<String, String> specs = api.getMetadata(flavor.getId());
|
||||
assertNotNull(specs);
|
||||
for (Map.Entry<String, String> entry : specs.entrySet()) {
|
||||
assertEquals(api.getExtraSpec(flavor.getId(), entry.getKey()), entry.getValue());
|
||||
assertEquals(api.getMetadataKey(flavor.getId(), entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,16 +108,16 @@ public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest {
|
|||
if (apiOption.isPresent()) {
|
||||
FlavorExtraSpecsApi api = apiOption.get();
|
||||
for (String key : testSpecs.keySet()) {
|
||||
assertTrue(api.setExtraSpec(testFlavor.getId(), key, "new value"));
|
||||
assertTrue(api.updateMetadataEntry(testFlavor.getId(), key, "new value"));
|
||||
}
|
||||
for (String key : testSpecs.keySet()) {
|
||||
assertEquals(api.getExtraSpec(testFlavor.getId(), key), "new value");
|
||||
assertEquals(api.getMetadataKey(testFlavor.getId(), key), "new value");
|
||||
}
|
||||
for (Resource flavor : flavorApi.listFlavors()) {
|
||||
Map<String, String> specs = api.getAllExtraSpecs(flavor.getId());
|
||||
for (Resource flavor : flavorApi.list().concat()) {
|
||||
Map<String, String> specs = api.getMetadata(flavor.getId());
|
||||
assertNotNull(specs);
|
||||
for (Map.Entry<String, String> entry : specs.entrySet()) {
|
||||
assertEquals(api.getExtraSpec(flavor.getId(), entry.getKey()), entry.getValue());
|
||||
assertEquals(api.getMetadataKey(flavor.getId(), entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,73 +63,73 @@ public class FloatingIPApiExpectTest extends BaseNovaApiExpectTest {
|
|||
}
|
||||
|
||||
public void testListFloatingIPsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listFloatingIPs = HttpRequest
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken).build();
|
||||
|
||||
HttpResponse listFloatingIPsResponse = HttpResponse.builder().statusCode(200)
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/floatingip_list.json")).build();
|
||||
|
||||
NovaApi apiWhenFloatingIPsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, listFloatingIPs, listFloatingIPsResponse);
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, list, listResponse);
|
||||
|
||||
assertEquals(apiWhenFloatingIPsExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1"));
|
||||
|
||||
assertEquals(apiWhenFloatingIPsExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().listFloatingIPs()
|
||||
assertEquals(apiWhenFloatingIPsExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().list()
|
||||
.toString(), new ParseFloatingIPListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListFloatingIPsWhenResponseIs404() throws Exception {
|
||||
HttpRequest listFloatingIPs = HttpRequest
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken).build();
|
||||
|
||||
HttpResponse listFloatingIPsResponse = HttpResponse.builder().statusCode(404).build();
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaApi apiWhenNoServersExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, listFloatingIPs, listFloatingIPsResponse);
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, list, listResponse);
|
||||
|
||||
assertTrue(apiWhenNoServersExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().listFloatingIPs().isEmpty());
|
||||
assertTrue(apiWhenNoServersExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().list().isEmpty());
|
||||
}
|
||||
|
||||
public void testGetFloatingIPWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest getFloatingIP = HttpRequest
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips/1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken).build();
|
||||
|
||||
HttpResponse getFloatingIPResponse = HttpResponse.builder().statusCode(200)
|
||||
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/floatingip_details.json")).build();
|
||||
|
||||
NovaApi apiWhenFloatingIPsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, getFloatingIP, getFloatingIPResponse);
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, get, getResponse);
|
||||
|
||||
assertEquals(apiWhenFloatingIPsExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().getFloatingIP("1")
|
||||
assertEquals(apiWhenFloatingIPsExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().get("1")
|
||||
.toString(), new ParseFloatingIPTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testGetFloatingIPWhenResponseIs404() throws Exception {
|
||||
HttpRequest getFloatingIP = HttpRequest
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips/1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("X-Auth-Token", authToken).build();
|
||||
|
||||
HttpResponse getFloatingIPResponse = HttpResponse.builder().statusCode(404).build();
|
||||
HttpResponse getResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaApi apiWhenNoServersExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, getFloatingIP, getFloatingIPResponse);
|
||||
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, get, getResponse);
|
||||
|
||||
assertNull(apiWhenNoServersExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().getFloatingIP("1"));
|
||||
assertNull(apiWhenNoServersExist.getFloatingIPExtensionForZone("az-1.region-a.geo-1").get().get("1"));
|
||||
}
|
||||
|
||||
public void testAllocateWhenResponseIs2xx() throws Exception {
|
||||
|
|
|
@ -52,11 +52,11 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
|
|||
if (!apiOption.isPresent())
|
||||
continue;
|
||||
FloatingIPApi api = apiOption.get();
|
||||
Set<? extends FloatingIP> response = api.listFloatingIPs();
|
||||
Set<? extends FloatingIP> response = api.list().toImmutableSet();
|
||||
assert null != response;
|
||||
assertTrue(response.size() >= 0);
|
||||
for (FloatingIP ip : response) {
|
||||
FloatingIP newDetails = api.getFloatingIP(ip.getId());
|
||||
FloatingIP newDetails = api.get(ip.getId());
|
||||
|
||||
assertEquals(newDetails.getId(), ip.getId());
|
||||
assertEquals(newDetails.getIp(), ip.getIp());
|
||||
|
@ -77,7 +77,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
|
|||
FloatingIP floatingIP = api.allocate();
|
||||
assertNotNull(floatingIP);
|
||||
|
||||
Set<? extends FloatingIP> response = api.listFloatingIPs();
|
||||
Set<? extends FloatingIP> response = api.list().toImmutableSet();
|
||||
boolean ipInSet = false;
|
||||
for (FloatingIP ip : response) {
|
||||
if (ip.getId().equals(floatingIP.getId()))
|
||||
|
@ -87,7 +87,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
|
|||
|
||||
api.deallocate(floatingIP.getId());
|
||||
|
||||
response = api.listFloatingIPs();
|
||||
response = api.list().toImmutableSet();
|
||||
ipInSet = false;
|
||||
for (FloatingIP ip : response) {
|
||||
if (ip.getId().equals(floatingIP.getId())) {
|
||||
|
@ -110,11 +110,11 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
|
|||
FloatingIP floatingIP = api.allocate();
|
||||
assertNotNull(floatingIP);
|
||||
try {
|
||||
api.addFloatingIPToServer(floatingIP.getIp(), server.getId());
|
||||
api.addToServer(floatingIP.getIp(), server.getId());
|
||||
assertEventually(new ServerHasFloatingIP(serverApi, server.getId(), floatingIP.getIp()));
|
||||
} finally {
|
||||
api.removeFloatingIPFromServer(floatingIP.getIp(), server.getId());
|
||||
serverApi.deleteServer(server.getId());
|
||||
api.removeFromServer(floatingIP.getIp(), server.getId());
|
||||
serverApi.delete(server.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
|
|||
|
||||
public void run() {
|
||||
try {
|
||||
Server server = api.getServer(serverId);
|
||||
Server server = api.get(serverId);
|
||||
boolean ipInServerAddresses = false;
|
||||
Multimap<String, Address> addresses = server.getAddresses();
|
||||
for (Address address : addresses.values()) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue