Issue 814: changes needed to be compatible with trystack

This commit is contained in:
Adrian Cole 2012-03-22 21:37:21 -07:00
parent 4ccd20e660
commit 91661f4759
19 changed files with 746 additions and 47 deletions

View File

@ -0,0 +1,49 @@
{
"access": {
"token": {
"expires": "2012-03-23T21:44:09",
"id": "Auth_4f173437e4b013bee56d1007",
"tenant": {
"id": "3456",
"name": "508151008"
}
},
"serviceCatalog": [{
"endpoints": [{
"adminURL": "https://nova-api.trystack.org:9774/v1.1/3456",
"region": "RegionOne",
"internalURL": "https://nova-api.trystack.org:9774/v1.1/3456",
"publicURL": "https://nova-api.trystack.org:9774/v1.1/3456"
}],
"type": "compute",
"name": "nova"
}, {
"endpoints": [{
"adminURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456",
"region": "RegionOne",
"internalURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456",
"publicURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456"
}],
"type": "image",
"name": "glance"
}, {
"endpoints": [{
"adminURL": "https://nova-api.trystack.org:5443/v2.0",
"region": "RegionOne",
"internalURL": "https://keystone.thefreecloud.org:5000/v2.0",
"publicURL": "https://keystone.thefreecloud.org:5000/v2.0"
}],
"type": "identity",
"name": "keystone"
}],
"user": {
"id": "43",
"roles": [{
"tenantId": "3456",
"id": "2",
"name": "Member"
}],
"name": "508151008"
}
}
}

View File

@ -109,7 +109,7 @@ public class NovaComputeServiceContextModule
bind(new TypeLiteral<Function<ImageInZone, Image>>() {
}).to(ImageInZoneToImage.class);
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>() {
}).to(NovaImageToOperatingSystem.class);
}).to(ImageToOperatingSystem.class);
bind(new TypeLiteral<Function<FlavorInZone, Hardware>>() {
}).to(FlavorInZoneToHardware.class);

View File

@ -86,14 +86,11 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
private void authorizeGroupToItselfAndAllIPsToTCPPort(SecurityGroupClient securityGroupClient,
SecurityGroup securityGroup, int port) {
logger.debug(">> authorizing securityGroup(%s) permission to port %d", securityGroup, port);
logger.trace(">> authorizing securityGroup(%s) permission to itself on port %d", securityGroup, port);
securityGroupClient.createSecurityGroupRuleAllowingSecurityGroupId(securityGroup.getId(), Ingress.builder()
.ipProtocol(IpProtocol.TCP).fromPort(port).toPort(port).build(), securityGroup.getId());
logger.trace(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, 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);
securityGroupClient.createSecurityGroupRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
logger.debug("<< authorized securityGroup(%s) permission to port %d", securityGroup, port);
logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
}
}

View File

@ -18,8 +18,16 @@
*/
package org.jclouds.openstack.nova.v1_1.compute.functions;
import static com.google.common.base.Predicates.containsPattern;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -38,17 +46,14 @@ import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
/**
* A function for transforming a nova specific Image into a generic
* OperatingSystem object.
* A function for transforming a nova specific Image into a generic OperatingSystem object.
*
* @author Matt Stephenson
*/
public class NovaImageToOperatingSystem implements Function<Image, OperatingSystem> {
public class ImageToOperatingSystem implements Function<Image, OperatingSystem> {
public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
// Windows Server 2008 R2 x64
public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])");
@ -60,7 +65,7 @@ public class NovaImageToOperatingSystem implements Function<Image, OperatingSyst
private final Map<OsFamily, Map<String, String>> osVersionMap;
@Inject
public NovaImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap) {
public ImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap) {
this.osVersionMap = osVersionMap;
}
@ -85,15 +90,26 @@ public class NovaImageToOperatingSystem implements Function<Image, OperatingSyst
} else if (imageName.contains("Oracle EL")) {
osFamily = OsFamily.OEL;
} else {
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults()
.split(imageName.toLowerCase());
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split(
imageName.toLowerCase());
osFamily = Iterables.find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>() {
@Override
public boolean apply(@Nullable OsFamily osFamily) {
return Iterables.any(imageNameParts, Predicates.equalTo(osFamily.name().toLowerCase()));
try {
osFamily = find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>() {
@Override
public boolean apply(@Nullable OsFamily osFamily) {
return any(imageNameParts, equalTo(osFamily.name().toLowerCase()));
}
});
} catch (NoSuchElementException e) {
String ubuntuVersion = startsWithUbuntuVersion(imageNameParts);
if (ubuntuVersion != null) {
osFamily = OsFamily.UBUNTU;
osVersion = ubuntuVersion;
} else {
logger.trace("could not parse operating system family for image(%s): %s", imageNameParts);
osFamily = OsFamily.UNRECOGNIZED;
}
});
}
}
Matcher matcher = DEFAULT_PATTERN.matcher(imageName);
if (matcher.find() && matcher.groupCount() >= 3) {
@ -102,4 +118,14 @@ public class NovaImageToOperatingSystem implements Function<Image, OperatingSyst
}
return new OperatingSystem(osFamily, imageName, osVersion, null, imageName, is64Bit);
}
String startsWithUbuntuVersion(final Iterable<String> imageNameParts) {
Map<String, String> ubuntuVersions = osVersionMap.get(OsFamily.UBUNTU);
for (String ubuntuKey : filter(ubuntuVersions.keySet(), not(equalTo("")))) {
if (any(imageNameParts, containsPattern("^" + ubuntuKey + ".*"))) {
return ubuntuVersions.get(ubuntuKey);
}
}
return null;
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.v1_1.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.transform;
@ -97,7 +98,7 @@ public class ServerInZoneToNodeMetadata implements Function<ServerInZone, NodeMe
builder.operatingSystem(findOperatingSystemForServerOrNull(serverInZone));
builder.hardware(findHardwareForServerOrNull(serverInZone));
builder.state(from.getStatus().getNodeState());
builder.publicAddresses(filter(transform(from.getPublicAddresses(),
builder.publicAddresses(filter(transform(concat(from.getPublicAddresses(), from.getInternetAddresses()),
AddressToStringTransformationFunction.INSTANCE), isInet4Address));
builder.privateAddresses(filter(transform(from.getPrivateAddresses(),
AddressToStringTransformationFunction.INSTANCE), isInet4Address));

View File

@ -35,6 +35,10 @@ public class Address {
* Relations associated with resources.
*/
public static enum Type {
/**
* internet routable address
*/
INTERNET,
/**
* publically routable address
*/

View File

@ -254,7 +254,23 @@ public class Server extends Resource {
"privateAddresses")));
return this;
}
/**
* @see Server#getInternetAddresses()
*/
public Builder internetAddresses(Address... internetAddresses) {
return internetAddresses(ImmutableSet.copyOf(checkNotNull(internetAddresses, "internetAddresses")));
}
/**
* @see Server#getInternetAddresses()
*/
public Builder internetAddresses(Set<Address> internetAddresses) {
this.addresses.replaceValues(Address.Type.INTERNET, ImmutableSet.copyOf(checkNotNull(internetAddresses,
"internetAddresses")));
return this;
}
/**
* @see Server#getPublicAddresses()
*/
@ -466,6 +482,19 @@ public class Server extends Resource {
return ImmutableSet.copyOf(privateAddresses);
}
}
/**
* @return the internet ip addresses assigned to the server
* @since essex
*/
public Set<Address> getInternetAddresses() {
Collection<Address> internetAddrs = getAddresses().get(Address.Type.INTERNET);
if (internetAddrs == null) {
return ImmutableSet.<Address> of();
} else {
return ImmutableSet.copyOf(internetAddrs);
}
}
/**
* @return the public ip addresses assigned to the server

View File

@ -25,8 +25,65 @@ package org.jclouds.openstack.nova.v1_1.extensions;
* @see <a href= "http://nova.openstack.org/api_ext/" />
*/
public interface ExtensionNamespaces {
/**
* Keypair Support
*/
public static final String KEYPAIRS = "http://docs.openstack.org/ext/keypairs/api/v1.1";
/**
* Volumes support
*/
public static final String VOLUMES = "http://docs.openstack.org/ext/volumes/api/v1.1";
/**
* Volume types support
*/
public static final String VOLUME_TYPES = "http://docs.openstack.org/ext/volume_types/api/v1.1";
/**
* Security group support
*/
public static final String SECURITY_GROUPS = "http://docs.openstack.org/ext/securitygroups/api/v1.1";
/**
* Floating IPs support
*/
public static final String FLOATING_IPS = "http://docs.openstack.org/ext/floating_ips/api/v1.1";
/**
* Multiple network support
*/
public static final String MULTINIC = "http://docs.openstack.org/ext/multinic/api/v1.1";
/**
* Host administration
*/
public static final String HOSTS = "http://docs.openstack.org/ext/hosts/api/v1.1";
/**
* Quotas management support
*/
public static final String QUOTAS = "http://docs.openstack.org/ext/quotas-sets/api/v1.1";
/**
* Instance type (flavor) extra specs
*/
public static final String FLAVOR_EXTRA_SPECS = "http://docs.openstack.org/ext/flavor_extra_specs/api/v1.1";
/**
* Provide additional data for flavors
*/
public static final String FLAVOR_EXTRA_DATA = "http://docs.openstack.org/ext/flavor_extra_data/api/v1.1";
/**
* Virtual interface support
*/
public static final String VIRTUAL_INTERFACES = "http://docs.openstack.org/ext/virtual_interfaces/api/v1.1";
/**
* Extended support to the Create Server v1.1 API
*/
public static final String CREATESERVEREXT = "http://docs.openstack.org/ext/createserverext/api/v1.1";
/**
* Virtual Storage Arrays support
*/
public static final String VSA = "http://docs.openstack.org/ext/vsa/api/v1.1";
/**
* Simple tenant usage extension
*/
public static final String SIMPLE_TENANT_USAGE = "http://docs.openstack.org/ext/os-simple-tenant-usage/api/v1.1";
/**
* Instance rescue mode
*/
public static final String RESCUE = "http://docs.openstack.org/ext/rescue/api/v1.1";
}

View File

@ -20,7 +20,10 @@ package org.jclouds.openstack.nova.v1_1.functions;
import java.net.URI;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.openstack.nova.v1_1.domain.Extension;
@ -28,10 +31,16 @@ import com.google.common.base.Function;
@Singleton
public class ExtensionToNameSpace implements Function<Extension, URI> {
private final Provider<UriBuilder> uriBuilders;
@Inject
public ExtensionToNameSpace(Provider<UriBuilder> uriBuilders) {
this.uriBuilders = uriBuilders;
}
@Override
public URI apply(Extension input) {
return input.getNamespace();
return uriBuilders.get().uri(input.getNamespace()).scheme("http").build();
}
public String toString() {

View File

@ -47,7 +47,7 @@ public class ExtensionPredicates {
return new Predicate<Extension>() {
@Override
public boolean apply(Extension ext) {
return namespace.equals(ext.getNamespace());
return namespace.toASCIIString().equals(ext.getNamespace().toASCIIString().replace("https", "http"));
}
@Override

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.openstack.nova.v1_1.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@ -26,18 +27,18 @@ import java.net.URI;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Location;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
/**
* Tests the compute service abstraction of the nova client.
@ -46,14 +47,13 @@ import com.google.common.collect.ImmutableMultimap;
*/
@Test(groups = "unit", testName = "NovaComputeServiceExpectTest")
public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTest {
public void testListServersWhenResponseIs2xx() throws Exception {
public void testListLocationsWhenResponseIs2xx() throws Exception {
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder().put(
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess).put(extensionsOfNovaRequest,
extensionsOfNovaResponse).put(listImagesDetail, listImagesDetailResponse).put(listServers,
listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).put(listFloatingIps,
listFloatingIpsResponse).build();
listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).build();
ComputeService clientWhenServersExist = requestsSendResponses(requestResponseMap);
@ -69,6 +69,46 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
assertEquals(clientWhenServersExist.listNodes().iterator().next().getName(), "sample-server");
}
public void testDefaultTemplateTryStack() throws Exception {
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder().put(
keystoneAuthWithAccessKeyAndSecretKey,
HttpResponse.builder().statusCode(200).message("HTTP/1.1 200").payload(
payloadFromResourceWithContentType("/keystoneAuthResponse_trystack.json", "application/json"))
.build()).put(
extensionsOfNovaRequest.toBuilder().endpoint(
URI.create("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().endpoint(
URI.create("https://nova-api.trystack.org:9774/v1.1/3456/images/detail")).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/image_list_detail_trystack.json"))
.build()).put(
listServers.toBuilder().endpoint(
URI.create("https://nova-api.trystack.org:9774/v1.1/3456/servers/detail")).build(),
listServersResponse).put(
listFlavorsDetail.toBuilder().endpoint(
URI.create("https://nova-api.trystack.org:9774/v1.1/3456/flavors/detail")).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/flavor_list_detail_trystack.json"))
.build()).build();
ComputeService clientForTryStack = requestsSendResponses(requestResponseMap);
Template defaultTemplate = clientForTryStack.templateBuilder().imageId("RegionOne/15").build();
checkTemplate(defaultTemplate);
checkTemplate(clientForTryStack.templateBuilder().fromTemplate(defaultTemplate).build());
}
private void checkTemplate(Template defaultTemplate) {
assertEquals(defaultTemplate.getImage().getId(), "RegionOne/15");
assertEquals(defaultTemplate.getImage().getProviderId(), "15");
assertEquals(defaultTemplate.getHardware().getId(), "RegionOne/1");
assertEquals(defaultTemplate.getHardware().getProviderId(), "1");
assertEquals(defaultTemplate.getLocation().getId(), "RegionOne");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
}
public void testListServersWhenReponseIs404IsEmpty() throws Exception {
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers(
@ -89,8 +129,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder().put(
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess).put(extensionsOfNovaRequest,
extensionsOfNovaResponse).put(listImagesDetail, listImagesDetailResponse).put(listServers,
listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).put(listFloatingIps,
listFloatingIpsResponse).build();
listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).build();
ComputeService clientThatCreatesNode = requestsSendResponses(requestResponseMap);

View File

@ -44,14 +44,14 @@ import com.google.common.collect.Iterables;
*
* @author Matt Stephenson
*/
public class NovaImageToOperatingSystemTest {
public class ImageToOperatingSystemTest {
@Test(dataProvider = "getOsFamilyValues")
public void testOsFamilyValues(OsFamily family) {
Image imageToConvert = Image.builder().id("id-" + family.name()).name(family.name()).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(
ImageToOperatingSystem converter = new ImageToOperatingSystem(
new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
@ -84,7 +84,7 @@ public class NovaImageToOperatingSystemTest {
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("Server 2008 R2", "Server-2008-R2"));
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
ImageToOperatingSystem converter = new ImageToOperatingSystem(osFamilyMap);
OperatingSystem convertedOs = converter.apply(imageToConvert);
@ -105,7 +105,7 @@ public class NovaImageToOperatingSystemTest {
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("98", "98"));
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
ImageToOperatingSystem converter = new ImageToOperatingSystem(osFamilyMap);
OperatingSystem convertedOs = converter.apply(imageToConvert);
@ -123,7 +123,7 @@ public class NovaImageToOperatingSystemTest {
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(
ImageToOperatingSystem converter = new ImageToOperatingSystem(
new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
@ -142,7 +142,7 @@ public class NovaImageToOperatingSystemTest {
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(
ImageToOperatingSystem converter = new ImageToOperatingSystem(
new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
@ -154,4 +154,42 @@ public class NovaImageToOperatingSystemTest {
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
ImageToOperatingSystem converterForUbuntu = new ImageToOperatingSystem(ImmutableMap.<OsFamily, Map<String, String>> of(
OsFamily.UBUNTU, ImmutableMap.of("lucid", "10.04", "maverick", "10.10", "natty", "11.04", "oneiric",
"11.10")));
@Test
public void testTryStackOneric() {
String name = "oneiric-server-cloudimg-amd64";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
OperatingSystem convertedOs = converterForUbuntu.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.UBUNTU);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), "11.10");
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
@Test
public void testTryStackNatty() {
String name = "natty-server-cloudimg-amd64";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
OperatingSystem convertedOs = converterForUbuntu.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.UBUNTU);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), "11.04");
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
}

View File

@ -4,22 +4,41 @@ import static org.testng.Assert.assertEquals;
import java.net.URI;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.openstack.nova.v1_1.domain.Extension;
import org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces;
import org.testng.annotations.Test;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ExtensionToNameSpaceTest")
public class ExtensionToNameSpaceTest {
private final ExtensionToNameSpace fn = new ExtensionToNameSpace();
private final ExtensionToNameSpace fn = new ExtensionToNameSpace(new Provider<UriBuilder>() {
@Override
public UriBuilder get() {
return new UriBuilderImpl();
}
});
public void testReturnsNamespace() {
URI ns = URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1");
assertEquals(
fn.apply(Extension.builder().alias("os-keypairs").name("Keypairs").namespace(ns)
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00"))
.description("Keypair Support").build()), ns);
assertEquals(fn.apply(Extension.builder().alias("os-keypairs").name("Keypairs").namespace(ns).updated(
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
"Keypair Support").build()), ns);
}
public void testChangesHttpsToHttp() {
assertEquals(fn.apply(Extension.builder().alias("security_groups").name("SecurityGroups").namespace(
URI.create("https://docs.openstack.org/ext/securitygroups/api/v1.1")).updated(
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-07-21T00:00:00+00:00")).description(
"Security group support").build()), URI.create(ExtensionNamespaces.SECURITY_GROUPS));
}
}

View File

@ -0,0 +1,100 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.parse;
import java.net.URI;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.domain.Link;
import org.jclouds.openstack.domain.Resource;
import org.jclouds.openstack.domain.Link.Relation;
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
import org.jclouds.openstack.nova.v1_1.domain.Address;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.Server.Status;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseServerTest")
public class ParseServerWithInternetAddressesTest extends BaseItemParserTest<Server> {
@Override
public String resource() {
return "/server_details_trystack.json";
}
@Override
@SelectJson("server")
@Consumes(MediaType.APPLICATION_JSON)
public Server expected() {
return Server
.builder()
.id("1459")
.uuid("2443c9c7-9791-412e-ac09-a6d55ec25335")
.tenantId("37")
.userId("508151008")
.name("mygroup-72c")
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-23T01:30:26Z"))
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-23T01:30:26Z"))
.hostId("881706597197955ac7cc4b353bc7ec884e13fa280de9cc82057796cb")
.status(Status.ACTIVE)
.image(
Resource
.builder()
.id("14")
.links(
Link.create(
Relation.BOOKMARK,
URI.create("https://nova-api.trystack.org:9774/37/images/14")))
.build())
.flavor(
Resource
.builder()
.id("1")
.links(
Link.create(
Relation.BOOKMARK,
URI.create("https://nova-api.trystack.org:9774/37/flavors/1")))
.build())
.links(
Link.create(
Relation.SELF,
URI.create("https://nova-api.trystack.org:9774/v1.1/37/servers/1459")),
Link.create(
Relation.BOOKMARK,
URI.create("https://nova-api.trystack.org:9774/37/servers/1459")))
.internetAddresses(Address.createV4("8.21.28.47")).build();
}
protected Injector injector() {
return Guice.createInjector(new NovaParserModule(), new GsonModule());
}
}

View File

@ -33,10 +33,10 @@ import org.testng.annotations.Test;
*/
@Test(groups = "unit", testName = "ExtensionPredicatesTest")
public class ExtensionPredicatesTest {
Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs")
.namespace(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1"))
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00"))
.description("Keypair Support").build();
Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs").namespace(
URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).updated(
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
"Keypair Support").build();
@Test
public void testAliasEqualsWhenEqual() {
@ -53,6 +53,12 @@ public class ExtensionPredicatesTest {
assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref);
}
@Test
public void testNamespaceEqualsWhenEqualEvenOnInputHttps() {
assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(
ref.toBuilder().namespace(URI.create("https://docs.openstack.org/ext/keypairs/api/v1.1")).build());
}
@Test
public void testNamespaceEqualsWhenNotEqual() {
assert !namespaceEquals(URI.create("foo")).apply(ref);

View File

@ -0,0 +1,115 @@
{
"extensions": [{
"updated": "2011-06-09T00:00:00+00:00",
"name": "Multinic",
"links": [],
"namespace": "https://docs.openstack.org/ext/multinic/api/v1.1",
"alias": "NMN",
"description": "Multiple network support"
}, {
"updated": "2011-06-29T00:00:00+00:00",
"name": "Hosts",
"links": [],
"namespace": "https://docs.openstack.org/ext/hosts/api/v1.1",
"alias": "os-hosts",
"description": "Host administration"
}, {
"updated": "2011-03-25T00:00:00+00:00",
"name": "Volumes",
"links": [],
"namespace": "https://docs.openstack.org/ext/volumes/api/v1.1",
"alias": "os-volumes",
"description": "Volumes support"
}, {
"updated": "2011-05-25 16:12:21.656723",
"name": "Admin Controller",
"links": [],
"namespace": "https:TODO/",
"alias": "ADMIN",
"description": "The Admin API Extension"
}, {
"updated": "2011-08-08T00:00:00+00:00",
"name": "Quotas",
"links": [],
"namespace": "https://docs.openstack.org/ext/quotas-sets/api/v1.1",
"alias": "os-quota-sets",
"description": "Quotas management support"
}, {
"updated": "2011-08-24T00:00:00+00:00",
"name": "VolumeTypes",
"links": [],
"namespace": "https://docs.openstack.org/ext/volume_types/api/v1.1",
"alias": "os-volume-types",
"description": "Volume types support"
}, {
"updated": "2011-06-23T00:00:00+00:00",
"name": "FlavorExtraSpecs",
"links": [],
"namespace": "https://docs.openstack.org/ext/flavor_extra_specs/api/v1.1",
"alias": "os-flavor-extra-specs",
"description": "Instance type (flavor) extra specs"
}, {
"updated": "2011-09-14T00:00:00+00:00",
"name": "FlavorExtraData",
"links": [],
"namespace": "https://docs.openstack.org/ext/flavor_extra_data/api/v1.1",
"alias": "os-flavor-extra-data",
"description": "Provide additional data for flavors"
}, {
"updated": "2011-08-17T00:00:00+00:00",
"name": "VirtualInterfaces",
"links": [],
"namespace": "https://docs.openstack.org/ext/virtual_interfaces/api/v1.1",
"alias": "virtual_interfaces",
"description": "Virtual interface support"
}, {
"updated": "2011-07-19T00:00:00+00:00",
"name": "Createserverext",
"links": [],
"namespace": "https://docs.openstack.org/ext/createserverext/api/v1.1",
"alias": "os-create-server-ext",
"description": "Extended support to the Create Server v1.1 API"
}, {
"updated": "2011-08-08T00:00:00+00:00",
"name": "Keypairs",
"links": [],
"namespace": "https://docs.openstack.org/ext/keypairs/api/v1.1",
"alias": "os-keypairs",
"description": "Keypair Support"
}, {
"updated": "2011-08-25T00:00:00+00:00",
"name": "VSAs",
"links": [],
"namespace": "https://docs.openstack.org/ext/vsa/api/v1.1",
"alias": "zadr-vsa",
"description": "Virtual Storage Arrays support"
}, {
"updated": "2011-08-19T00:00:00+00:00",
"name": "SimpleTenantUsage",
"links": [],
"namespace": "https://docs.openstack.org/ext/os-simple-tenant-usage/api/v1.1",
"alias": "os-simple-tenant-usage",
"description": "Simple tenant usage extension"
}, {
"updated": "2011-08-18T00:00:00+00:00",
"name": "Rescue",
"links": [],
"namespace": "https://docs.openstack.org/ext/rescue/api/v1.1",
"alias": "os-rescue",
"description": "Instance rescue mode"
}, {
"updated": "2011-07-21T00:00:00+00:00",
"name": "SecurityGroups",
"links": [],
"namespace": "https://docs.openstack.org/ext/securitygroups/api/v1.1",
"alias": "security_groups",
"description": "Security group support"
}, {
"updated": "2011-06-16T00:00:00+00:00",
"name": "Floating_ips",
"links": [],
"namespace": "https://docs.openstack.org/ext/floating_ips/api/v1.1",
"alias": "os-floating-ips",
"description": "Floating IPs support"
}]
}

View File

@ -0,0 +1,83 @@
{
"flavors": [{
"rxtx_quota": 0,
"name": "m1.medium",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/3",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/flavors/3",
"rel": "bookmark"
}],
"ram": 4096,
"vcpus": 2,
"rxtx_cap": 0,
"swap": 0,
"disk": 40,
"id": 3
}, {
"rxtx_quota": 0,
"name": "m1.large",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/4",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/flavors/4",
"rel": "bookmark"
}],
"ram": 8192,
"vcpus": 4,
"rxtx_cap": 0,
"swap": 0,
"disk": 80,
"id": 4
}, {
"rxtx_quota": 0,
"name": "m1.tiny",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/1",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/flavors/1",
"rel": "bookmark"
}],
"ram": 512,
"vcpus": 1,
"rxtx_cap": 0,
"swap": 0,
"disk": 0,
"id": 1
}, {
"rxtx_quota": 0,
"name": "m1.xlarge",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/5",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/flavors/5",
"rel": "bookmark"
}],
"ram": 16384,
"vcpus": 8,
"rxtx_cap": 0,
"swap": 0,
"disk": 160,
"id": 5
}, {
"rxtx_quota": 0,
"name": "m1.small",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/2",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/flavors/2",
"rel": "bookmark"
}],
"ram": 2048,
"vcpus": 1,
"rxtx_cap": 0,
"swap": 0,
"disk": 20,
"id": 2
}]
}

View File

@ -0,0 +1,81 @@
{
"images": [{
"status": "ACTIVE",
"updated": "2012-02-02T19:11:00Z",
"name": "oneiric-server-cloudimg-amd64",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/images/15",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/images/15",
"rel": "bookmark"
}],
"created": "2012-02-02T19:10:52Z",
"progress": 100,
"id": "15",
"metadata": {
"kernel_id": "14",
"min_disk": 0,
"min_ram": 0,
"owner": "1"
}
}, {
"status": "ACTIVE",
"updated": "2012-02-02T19:10:51Z",
"name": "oneiric-server-cloudimg-amd64-kernel",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/images/14",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/images/14",
"rel": "bookmark"
}],
"created": "2012-02-02T19:10:50Z",
"progress": 100,
"id": "14",
"metadata": {
"min_disk": 0,
"owner": "1",
"min_ram": 0
}
}, {
"status": "ACTIVE",
"updated": "2012-02-02T19:10:41Z",
"name": "natty-server-cloudimg-amd64",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/images/13",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/images/13",
"rel": "bookmark"
}],
"created": "2012-02-02T19:10:33Z",
"progress": 100,
"id": "13",
"metadata": {
"kernel_id": "12",
"min_disk": 0,
"min_ram": 0,
"owner": "1"
}
}, {
"status": "ACTIVE",
"updated": "2012-02-02T19:10:33Z",
"name": "natty-server-cloudimg-amd64-kernel",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/images/12",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/images/12",
"rel": "bookmark"
}],
"created": "2012-02-02T19:10:32Z",
"progress": 100,
"id": "12",
"metadata": {
"min_disk": 0,
"owner": "1",
"min_ram": 0
}
}]
}

View File

@ -0,0 +1,46 @@
{
"server": {
"status": "ACTIVE",
"updated": "2012-03-23T01:30:26Z",
"hostId": "881706597197955ac7cc4b353bc7ec884e13fa280de9cc82057796cb",
"user_id": "508151008",
"name": "mygroup-72c",
"links": [{
"href": "https://nova-api.trystack.org:9774/v1.1/37/servers/1459",
"rel": "self"
}, {
"href": "https://nova-api.trystack.org:9774/37/servers/1459",
"rel": "bookmark"
}],
"addresses": {
"internet": [{
"version": 4,
"addr": "8.21.28.47"
}]
},
"tenant_id": "37",
"image": {
"id": "14",
"links": [{
"href": "https://nova-api.trystack.org:9774/37/images/14",
"rel": "bookmark"
}]
},
"created": "2012-03-23T01:30:26Z",
"uuid": "2443c9c7-9791-412e-ac09-a6d55ec25335",
"accessIPv4": "",
"accessIPv6": "",
"key_name": null,
"progress": 100,
"flavor": {
"id": "1",
"links": [{
"href": "https://nova-api.trystack.org:9774/37/flavors/1",
"rel": "bookmark"
}]
},
"config_drive": "",
"id": 1459,
"metadata": {}
}
}