mirror of https://github.com/apache/jclouds.git
Merge pull request #1065 from i11/master
Add flavor create and delete API calls for openstack-nova
This commit is contained in:
commit
6a6214d1c5
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
@ -34,7 +37,7 @@ import com.google.common.base.Optional;
|
|||
* A flavor is an available hardware configuration for a server. Each flavor has
|
||||
* a unique combination of disk space and memory capacity.
|
||||
*
|
||||
* @author Jeremy Daggett
|
||||
* @author Jeremy Daggett, Ilja Bobkevic
|
||||
* @see <a href=
|
||||
"http://docs.openstack.org/api/openstack-compute/2/content/List_Flavors-d1e4188.html"
|
||||
/>
|
||||
|
@ -139,9 +142,11 @@ public class Flavor extends Resource {
|
|||
@ConstructorProperties({
|
||||
"id", "name", "links", "ram", "disk", "vcpus", "swap", "rxtx_factor", "OS-FLV-EXT-DATA:ephemeral"
|
||||
})
|
||||
protected Flavor(String id, @Nullable String name, java.util.Set<Link> links, int ram, int disk, int vcpus,
|
||||
protected Flavor(String id, String name, java.util.Set<Link> links, int ram, int disk, int vcpus,
|
||||
@Nullable String swap, @Nullable Double rxtxFactor, @Nullable Integer ephemeral) {
|
||||
super(id, name, links);
|
||||
super(id, checkNotNull(name, "name"), links);
|
||||
checkArgument(ram > 0, "Value of ram has to greater than 0");
|
||||
checkArgument(vcpus > 0, "Value of vcpus has to greater than 0");
|
||||
this.ram = ram;
|
||||
this.disk = disk;
|
||||
this.vcpus = vcpus;
|
||||
|
@ -149,7 +154,7 @@ public class Flavor extends Resource {
|
|||
this.rxtxFactor = Optional.fromNullable(rxtxFactor);
|
||||
this.ephemeral = Optional.fromNullable(ephemeral);
|
||||
}
|
||||
|
||||
|
||||
public int getRam() {
|
||||
return this.ram;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.jclouds.openstack.v2_0.options.PaginationOptions;
|
|||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/List_Flavors-d1e4188.html"
|
||||
* />
|
||||
* @author Jeremy Daggett
|
||||
* @author Jeremy Daggett, Ilja Bobkevic
|
||||
*/
|
||||
public interface FlavorApi {
|
||||
|
||||
|
@ -63,4 +63,18 @@ public interface FlavorApi {
|
|||
*/
|
||||
Flavor get(String id);
|
||||
|
||||
/**
|
||||
* Create flavor according to the provided object
|
||||
*
|
||||
* @param flavor - flavor object
|
||||
* @return newly created flavor
|
||||
*/
|
||||
Flavor create(Flavor flavor);
|
||||
|
||||
/**
|
||||
* Delete flavor with a given id
|
||||
*
|
||||
* @param id - flavor id
|
||||
*/
|
||||
void delete(String id);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,17 @@ package org.jclouds.openstack.nova.v2_0.features;
|
|||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||
|
@ -41,6 +45,8 @@ import org.jclouds.rest.annotations.RequestFilters;
|
|||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.annotations.Unwrap;
|
||||
import org.jclouds.rest.annotations.WrapWith;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
|
@ -54,6 +60,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* >docs</a>
|
||||
* @author Jeremy Daggett TODO: Need a ListFlavorOptions class minDisk=minDiskInGB&
|
||||
* minRam=minRamInMB& marker=markerID&limit=int
|
||||
* @author Ilja Bobkevic
|
||||
*/
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface FlavorAsyncApi {
|
||||
|
@ -115,4 +122,25 @@ public interface FlavorAsyncApi {
|
|||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Flavor> get(@PathParam("id") String id);
|
||||
|
||||
|
||||
/**
|
||||
* @see FlavorApi#create
|
||||
*/
|
||||
@Named("flavor:create")
|
||||
@POST
|
||||
@Unwrap
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/flavors")
|
||||
ListenableFuture<? extends Flavor> create(@WrapWith("flavor") Flavor flavor);
|
||||
|
||||
/**
|
||||
* @see FlavorApi#delete
|
||||
*/
|
||||
@Named("flavor:delete")
|
||||
@DELETE
|
||||
@Consumes
|
||||
@Path("/flavors/{id}")
|
||||
@Fallback(VoidOnNotFoundOr404.class)
|
||||
ListenableFuture<Void> delete(@PathParam("id") String id);
|
||||
}
|
||||
|
|
|
@ -22,10 +22,16 @@ import static org.testng.Assert.assertEquals;
|
|||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseCreateFlavorTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseFlavorListTest;
|
||||
import org.jclouds.openstack.nova.v2_0.parse.ParseFlavorTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -35,7 +41,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
/**
|
||||
* Tests annotation parsing of {@code FlavorAsyncApi}
|
||||
*
|
||||
* @author Jeremy Daggett
|
||||
* @author Jeremy Daggett, Ilja Bobkevic
|
||||
*/
|
||||
@Test(groups = "unit", testName = "FlavorApiExpectTest")
|
||||
public class FlavorApiExpectTest extends BaseNovaApiExpectTest {
|
||||
|
@ -114,5 +120,47 @@ public class FlavorApiExpectTest extends BaseNovaApiExpectTest {
|
|||
assertNull(apiWhenNoFlavorsExist.getFlavorApiForZone("az-1.region-a.geo-1").get("123"));
|
||||
|
||||
}
|
||||
|
||||
public void testCreateFlavor200() throws Exception {
|
||||
ParseCreateFlavorTest parser = new ParseCreateFlavorTest();
|
||||
HttpRequest listFlavors = HttpRequest
|
||||
.builder()
|
||||
.method(HttpMethod.POST)
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors")
|
||||
.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.payload(payloadFromResource(parser.resource())).build();
|
||||
|
||||
HttpResponse listFlavorsResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource(parser.resource())).build();
|
||||
|
||||
NovaApi api = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, listFlavors, listFlavorsResponse);
|
||||
|
||||
assertEquals(
|
||||
api.getFlavorApiForZone("az-1.region-a.geo-1").create(Flavor.builder()
|
||||
.id("1cb47a44-9b84-4da4-bf81-c1976e8414ab")
|
||||
.name("128 MB Server").ram(128).vcpus(1)
|
||||
.disk(10).build())
|
||||
.toString(), parser.expected().toString());
|
||||
}
|
||||
|
||||
public void testDeleteFlavor202() throws Exception {
|
||||
String flavorId = "1cb47a44-9b84-4da4-bf81-c1976e8414ab";
|
||||
|
||||
HttpRequest updateMetadata = HttpRequest
|
||||
.builder()
|
||||
.method(HttpMethod.DELETE)
|
||||
.endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors/" + flavorId)
|
||||
.addHeader(HttpHeaders.ACCEPT, MediaType.WILDCARD)
|
||||
.addHeader("X-Auth-Token", authToken)
|
||||
.build();
|
||||
|
||||
HttpResponse updateMetadataResponse = HttpResponse.builder().statusCode(204).build();
|
||||
|
||||
NovaApi api = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
|
||||
responseWithKeystoneAccess, updateMetadata, updateMetadataResponse);
|
||||
|
||||
api.getFlavorApiForZone("az-1.region-a.geo-1").delete(flavorId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.parse;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorApiExpectTest;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @see FlavorApiExpectTest
|
||||
* @author Ilja Bobkevic
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseCreateFlavorTest")
|
||||
public class ParseCreateFlavorTest extends BaseItemParserTest<Flavor> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/flavor_new.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("flavor")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Flavor expected() {
|
||||
return Flavor.builder()
|
||||
.id("1cb47a44-9b84-4da4-bf81-c1976e8414ab")
|
||||
.name("128 MB Server").ram(128).vcpus(1)
|
||||
.disk(10).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"flavor" : {
|
||||
"id" : "1cb47a44-9b84-4da4-bf81-c1976e8414ab",
|
||||
"name" : "128 MB Server",
|
||||
"ram" : 128,
|
||||
"disk" : 10,
|
||||
"vcpus" : 1,
|
||||
"links" : []
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue