From 533045edd77a2abcabb544d413fc1b6e832ebba5 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 14 May 2011 22:36:07 -0700 Subject: [PATCH] Issue 561:add location_id to byon provider --- apis/byon/README.txt | 3 + .../src/main/java/org/jclouds/byon/Node.java | 180 ++++++++++++++---- .../BYONComputeServiceContextModule.java | 3 +- .../byon/functions/NodeToNodeMetadata.java | 40 +++- .../jclouds/byon/functions/NodesFromYaml.java | 53 +++++- .../internal/BYONComputeServiceAdapter.java | 30 ++- .../jclouds/byon/BYONComputeServiceTest.java | 45 ++++- .../functions/NodeToNodeMetadataTest.java | 55 ++++-- .../byon/functions/NodesFromYamlTest.java | 24 ++- .../src/test/resources/test_location.yaml | 43 +++++ 10 files changed, 397 insertions(+), 79 deletions(-) create mode 100644 apis/byon/src/test/resources/test_location.yaml diff --git a/apis/byon/README.txt b/apis/byon/README.txt index 7f26360eae..ac724e7d0f 100644 --- a/apis/byon/README.txt +++ b/apis/byon/README.txt @@ -65,6 +65,8 @@ Here are the properties: * description - optional; long description of this node * note this is not yet in jclouds NodeMetadata * hostname - name or ip address to contact the node on + * location_id - optional; correlates to a ZONE-scoped Location + * note that if present for one node, must be present for all * os_arch - ex. x86 * os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format ex. rhel, ubuntu, centos, debian, amzn-linux @@ -96,6 +98,7 @@ nodes: name: cluster-1 description: accounting analytics cluster hostname: cluster-1.mydomain.com + location_id: virginia os_arch: x86 os_family: rhel os_description: redhat with CDH diff --git a/apis/byon/src/main/java/org/jclouds/byon/Node.java b/apis/byon/src/main/java/org/jclouds/byon/Node.java index 5030da44fb..1a8e2660b8 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/Node.java +++ b/apis/byon/src/main/java/org/jclouds/byon/Node.java @@ -20,60 +20,162 @@ package org.jclouds.byon; import java.net.URI; import java.util.HashSet; -import java.util.List; import java.util.Set; import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; /** * * @author Adrian Cole */ public class Node { - // public due to snakeyaml - public Node() { + public static Builder builder() { + return new Builder(); } - public Node(String id, String name, String description, String hostname, String osArch, String osFamily, - String osDescription, String osVersion, String group, List tags, String username, - String credential, URI credentialUrl, String sudo_password) { + public static class Builder { + private String id; + private String name; + private String description; + private String hostname; + private String locationId; + private String osArch; + private String osFamily; + private String osDescription; + private String osVersion; + private String group; + private Set tags = ImmutableSet.of(); + private String username; + private String credential; + private URI credentialUrl; + private String sudoPassword; + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder hostname(String hostname) { + this.hostname = hostname; + return this; + } + + public Builder locationId(String locationId) { + this.locationId = locationId; + return this; + } + + public Builder osArch(String osArch) { + this.osArch = osArch; + return this; + } + + public Builder osFamily(String osFamily) { + this.osFamily = osFamily; + return this; + } + + public Builder osDescription(String osDescription) { + this.osDescription = osDescription; + return this; + } + + public Builder osVersion(String osVersion) { + this.osVersion = osVersion; + return this; + } + + public Builder group(String group) { + this.group = group; + return this; + } + + public Builder tags(Iterable tags) { + this.tags = ImmutableSet.copyOf(tags); + return this; + } + + public Builder username(String username) { + this.username = username; + return this; + } + + public Builder credential(String credential) { + this.credential = credential; + return this; + } + + public Builder credentialUrl(URI credentialUrl) { + this.credentialUrl = credentialUrl; + return this; + } + + public Builder sudoPassword(String sudoPassword) { + this.sudoPassword = sudoPassword; + return this; + } + + public Node build() { + return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion, + group, tags, username, credential, credentialUrl, sudoPassword); + } + } + + public Node(String id, String name, String description, String hostname, String locationId, String osArch, + String osFamily, String osDescription, String osVersion, String group, Iterable tags, + String username, String credential, URI credentialUrl, String sudoPassword) { this.id = id; this.name = name; this.description = description; this.hostname = hostname; - this.os_arch = osArch; - this.os_family = osFamily; - this.os_description = osDescription; - this.os_version = osVersion; + this.locationId = locationId; + this.osArch = osArch; + this.osFamily = osFamily; + this.osDescription = osDescription; + this.osVersion = osVersion; this.group = group; - this.tags = ImmutableList.copyOf(tags); + this.tags = ImmutableSet.copyOf(tags); this.username = username; this.credential = credential; - this.credential_url = credentialUrl != null ? credentialUrl.toASCIIString() : null; - this.sudo_password = sudo_password; + this.credentialUrl = credentialUrl; + this.sudoPassword = sudoPassword; } - // public due to snakeyaml - public String id; - public String name; - public String description; - public String hostname; - public String os_arch; - public String os_family; - public String os_description; - public String os_version; - public String group; - public List tags; - public String username; - public String credential; - public String credential_url; - public String sudo_password; + private final String id; + private final String name; + private final String description; + private final String hostname; + private final String locationId; + private final String osArch; + private final String osFamily; + private final String osDescription; + private final String osVersion; + private final String group; + private final Set tags; + private final String username; + private final String credential; + private final URI credentialUrl; + private final String sudoPassword; public String getId() { return id; } + public String getLocationId() { + return locationId; + } + public String getName() { return name; } @@ -91,19 +193,19 @@ public class Node { } public String getOsArch() { - return os_arch; + return osArch; } public String getOsFamily() { - return os_family; + return osFamily; } public String getOsDescription() { - return os_description; + return osDescription; } public String getOsVersion() { - return os_version; + return osVersion; } public Set getTags() { @@ -122,7 +224,7 @@ public class Node { } public URI getCredentialUrl() { - return credential_url != null ? URI.create(credential_url) : null; + return credentialUrl; } @Override @@ -131,7 +233,7 @@ public class Node { } public String getSudoPassword() { - return sudo_password; + return sudoPassword; } @Override @@ -144,10 +246,10 @@ public class Node { @Override public String toString() { return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add( - "hostname", hostname).add("osArch", os_arch).add("osFamily", os_family).add("osDescription", - os_description).add("osVersion", os_version).add("group", group).add("tags", tags).add("username", - username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword", - sudo_password != null).toString(); + "locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add( + "osDescription", osDescription).add("osVersion", osVersion).add("group", group).add("tags", tags).add( + "username", username).add("hasCredential", credential != null || credentialUrl != null).add( + "hasSudoPassword", sudoPassword != null).toString(); } } diff --git a/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java b/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java index b66419ba30..6ef4c20cae 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java +++ b/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java @@ -44,7 +44,7 @@ import com.google.inject.TypeLiteral; * * @author Adrian Cole */ -@SuppressWarnings( { "rawtypes", "unchecked" }) +@SuppressWarnings("unchecked") @SingleThreaded public class BYONComputeServiceContextModule extends JCloudsNativeComputeServiceAdapterContextModule { @@ -53,7 +53,6 @@ public class BYONComputeServiceContextModule extends super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class); } - @SuppressWarnings("unchecked") @Provides @Singleton Supplier provideApi(Supplier> in) { diff --git a/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java b/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java index 9c56f313b8..f15f69107e 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java +++ b/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java @@ -24,25 +24,32 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.byon.Node; +import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeState; -import org.jclouds.compute.domain.OperatingSystemBuilder; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import org.jclouds.logging.Logger; import org.jclouds.util.Strings2; import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; /** * @author Adrian Cole @@ -50,16 +57,19 @@ import com.google.common.collect.ImmutableSet; @Singleton public class NodeToNodeMetadata implements Function { @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; private final Supplier location; + private final Supplier> locations; private final Map credentialStore; private final Function slurp; @Inject - NodeToNodeMetadata(Supplier location, Function slurp, - Map credentialStore) { + NodeToNodeMetadata(Supplier location, @Memoized Supplier> locations, + Function slurp, Map credentialStore) { this.location = checkNotNull(location, "location"); + this.locations = checkNotNull(locations, "locations"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.slurp = checkNotNull(slurp, "slurp"); } @@ -69,10 +79,10 @@ public class NodeToNodeMetadata implements Function { NodeMetadataBuilder builder = new NodeMetadataBuilder(); builder.ids(from.getId()); builder.name(from.getName()); - builder.location(location.get()); + builder.location(findLocationWithId(from.getLocationId())); builder.group(from.getGroup()); // TODO add tags! - builder.operatingSystem(new OperatingSystemBuilder().arch(from.getOsArch()).family( + builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family( OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription()) .version(from.getOsVersion()).build()); builder.state(NodeState.RUNNING); @@ -99,4 +109,24 @@ public class NodeToNodeMetadata implements Function { builder.adminPassword(from.getSudoPassword()); return builder.build(); } + + private Location findLocationWithId(final String locationId) { + if (locationId == null) + return location.get(); + try { + Location location = Iterables.find(locations.get(), new Predicate() { + + @Override + public boolean apply(Location input) { + return input.getId().equals(locationId); + } + + }); + return location; + + } catch (NoSuchElementException e) { + logger.debug("couldn't match instance location %s in: %s", locationId, locations.get()); + return location.get(); + } + } } diff --git a/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java index 2e30c61d48..3e904bd0d2 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java +++ b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java @@ -21,6 +21,7 @@ package org.jclouds.byon.functions; import static com.google.common.base.Preconditions.checkState; import java.io.InputStream; +import java.net.URI; import java.util.List; import java.util.Map; @@ -33,6 +34,8 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** @@ -44,6 +47,7 @@ import com.google.common.collect.Maps; * name: cluster-1 * description: xyz * hostname: cluster-1.mydomain.com + * location_id: virginia * os_arch: x86 * os_family: linux * os_description: redhat @@ -59,6 +63,7 @@ import com.google.common.collect.Maps; * * * @author Kelvin Kakugawa + * @author Adrian Cole */ @Singleton public class NodesFromYaml implements Function> { @@ -68,27 +73,65 @@ public class NodesFromYaml implements Function> { * */ public static class Config { - public List nodes; + public List nodes; + } + + // crappy, as snakeyaml.. + // 1. complains on illegalaccesserror for extends Constructor.ConstructMapping, so we can't use a + // real constructor + // 2. cannot set non-public fields, or fill non-public classes + // 3. doesn't support a SerializedName annotation, so your fields need to be named the same as + // the text + public static class CrappyNode { + public String id; + public String name; + public String description; + public String hostname; + public String location_id; + public String os_arch; + public String os_family; + public String os_description; + public String os_version; + public String group; + public List tags = Lists.newArrayList(); + public String username; + public String credential; + public String credential_url; + public String sudo_password; } @Override public Map apply(InputStream source) { + Constructor constructor = new Constructor(Config.class); - TypeDescription nodeDesc = new TypeDescription(Node.class); + TypeDescription nodeDesc = new TypeDescription(CrappyNode.class); nodeDesc.putListPropertyType("tags", String.class); constructor.addTypeDescription(nodeDesc); TypeDescription configDesc = new TypeDescription(Config.class); - configDesc.putListPropertyType("nodes", Node.class); + configDesc.putListPropertyType("nodes", CrappyNode.class); constructor.addTypeDescription(configDesc); - + // note that snakeyaml also throws nosuchmethod error when you use the non-deprecated + // constructor Yaml yaml = new Yaml(new Loader(constructor)); Config config = (Config) yaml.load(source); checkState(config != null, "missing config: class"); checkState(config.nodes != null, "missing nodes: collection"); - return Maps.uniqueIndex(config.nodes, new Function() { + return Maps.uniqueIndex(Iterables.transform(config.nodes, new Function() { + + @Override + public Node apply(CrappyNode arg0) { + return Node.builder().id(arg0.id).name(arg0.name).description(arg0.description) + .locationId(arg0.location_id).hostname(arg0.hostname).osArch(arg0.os_arch) + .osFamily(arg0.os_family).osDescription(arg0.os_description).osVersion(arg0.os_version).group( + arg0.group).tags(arg0.tags).username(arg0.username).credential(arg0.credential) + .credentialUrl(arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword( + arg0.sudo_password).build(); + } + + }), new Function() { public String apply(Node node) { return node.getId(); } diff --git a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java index e161f328cb..5a929b0000 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java +++ b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java @@ -21,6 +21,7 @@ package org.jclouds.byon.internal; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -34,11 +35,16 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; import org.jclouds.location.suppliers.JustProvider; +import com.google.common.base.Function; +import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; /** * @@ -59,8 +65,8 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda } @Override - public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, + Template template, Map credentialStore) { throw new UnsupportedOperationException(); } @@ -79,10 +85,26 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda return Iterables.transform(nodes.get().values(), converter); } - @SuppressWarnings("unchecked") @Override public Iterable listLocations() { - return (Iterable) locationSupplier.get(); + Builder locations = ImmutableSet.builder(); + Location provider = Iterables.getOnlyElement(locationSupplier.get()); + Set zones = ImmutableSet.copyOf(Iterables.filter(Iterables.transform(nodes.get().values(), + new Function() { + + @Override + public String apply(Node arg0) { + return arg0.getLocationId(); + } + }), Predicates.notNull())); + if (zones.size() == 0) + return locations.add(provider).build(); + else + for (String zone : zones) { + locations.add(new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(provider) + .build()); + } + return locations.build(); } @Override diff --git a/apis/byon/src/test/java/org/jclouds/byon/BYONComputeServiceTest.java b/apis/byon/src/test/java/org/jclouds/byon/BYONComputeServiceTest.java index 5918fa5ae2..89d5f76c1c 100644 --- a/apis/byon/src/test/java/org/jclouds/byon/BYONComputeServiceTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/BYONComputeServiceTest.java @@ -18,16 +18,19 @@ */ package org.jclouds.byon; +import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedNodeMetadataFromResource; +import static org.jclouds.byon.functions.NodeToNodeMetadataTest.expectedProviderLocationFromResource; +import static org.jclouds.byon.functions.NodeToNodeMetadataTest.zoneCalled; import static org.testng.Assert.assertEquals; import java.net.URI; import java.util.Map; import java.util.Properties; -import org.jclouds.byon.functions.NodeToNodeMetadataTest; import org.jclouds.byon.functions.NodesFromYamlTest; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.domain.Location; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.testng.annotations.Test; @@ -56,6 +59,7 @@ public class BYONComputeServiceTest { private void assertNodesParse(String endpoint) { ComputeServiceContext context = null; try { + Location providerLocation = expectedProviderLocationFromResource(endpoint); Properties props = new Properties(); props.setProperty("byon.endpoint", endpoint); @@ -69,12 +73,45 @@ public class BYONComputeServiceTest { .getApi(); assertEquals(supplier.get().size(), context.getComputeService().listNodes().size()); - assertEquals(supplier.get(), ImmutableMap. of(NodesFromYamlTest.TEST1.id, + assertEquals(supplier.get(), ImmutableMap. of(NodesFromYamlTest.TEST1.getId(), NodesFromYamlTest.TEST1)); - assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest - .expectedNodeMetadataFromResource(endpoint))); + assertEquals(context.getComputeService().listNodes(), ImmutableSet + .of(expectedNodeMetadataFromResource(endpoint))); + assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(providerLocation)); + } finally { + if (context != null) + context.close(); + } + } + public void testNodesWithLocations() { + ComputeServiceContext context = null; + try { + String endpoint = "file://" + getClass().getResource("/test_location.yaml").getPath(); + Properties props = new Properties(); + props.setProperty("byon.endpoint", endpoint); + context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet + . of(new JschSshClientModule()), props); + + assertEquals(context.getProviderSpecificContext().getEndpoint(), URI.create(endpoint)); + + @SuppressWarnings("unchecked") + Supplier> supplier = (Supplier>) context.getProviderSpecificContext() + .getApi(); + + assertEquals(supplier.get().size(), context.getComputeService().listNodes().size()); + assertEquals(supplier.get(), ImmutableMap. of(NodesFromYamlTest.TEST2.getId(), + NodesFromYamlTest.TEST2, NodesFromYamlTest.TEST3.getId(), NodesFromYamlTest.TEST3)); + Location providerLocation = expectedProviderLocationFromResource(endpoint); + + Location virginia = zoneCalled("virginia", providerLocation); + Location maryland = zoneCalled("maryland", providerLocation); + + assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(expectedNodeMetadataFromResource(1, + endpoint, virginia), expectedNodeMetadataFromResource(2, endpoint, maryland))); + + assertEquals(context.getComputeService().listAssignableLocations(), ImmutableSet.of(virginia, maryland)); } finally { if (context != null) context.close(); diff --git a/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java b/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java index 186cf1ac98..3a59c24026 100644 --- a/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java @@ -22,12 +22,13 @@ import static org.testng.Assert.assertEquals; import java.net.URI; import java.util.Map; +import java.util.Set; import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeState; -import org.jclouds.compute.domain.OperatingSystemBuilder; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; @@ -45,31 +46,51 @@ import com.google.common.collect.Maps; * @author Adrian Cole */ public class NodeToNodeMetadataTest { - public static Location expectedLocationFromResource(String resource) { + public static Location expectedProviderLocationFromResource(String resource) { return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build(); } - public static NodeMetadata expectedNodeMetadataFromResource(String resource) { - Location location = expectedLocationFromResource(resource); + public static Location zoneCalled(String zone, Location parent) { + return new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(parent).build(); + } - return new NodeMetadataBuilder().ids("cluster-1").group("hadoop").name("cluster-1").location(location).state( - NodeState.RUNNING).operatingSystem( - new OperatingSystemBuilder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3") - .build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials( - new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build(); + String resource = "location"; + + Location provider = expectedProviderLocationFromResource(resource); + + Map credentialStore = Maps.newLinkedHashMap(); + + NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(provider), Suppliers + .> ofInstance(ImmutableSet.of(provider, zoneCalled("virginia", provider))), + new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore); + + public static NodeMetadata expectedNodeMetadataFromResource(String resource) { + return expectedNodeMetadataFromResource(resource, expectedProviderLocationFromResource(resource)); + } + + public static NodeMetadata expectedNodeMetadataFromResource(String resource, Location location) { + return expectedNodeMetadataFromResource(1, resource, location); + } + + public static NodeMetadata expectedNodeMetadataFromResource(int id, String resource, Location location) { + return new NodeMetadataBuilder().ids("cluster-" + id).group("hadoop").name("cluster-" + id).location(location) + .state(NodeState.RUNNING).operatingSystem( + OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86") + .version("5.3").build()).publicAddresses( + ImmutableSet.of("cluster-" + id + ".mydomain.com")).credentials( + new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build(); } @Test public void testNodesParse() throws Exception { - - Map credentialStore = Maps.newLinkedHashMap(); - - NodeToNodeMetadata parser = new NodeToNodeMetadata( - Suppliers.ofInstance(expectedLocationFromResource("location")), - new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore); - - assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource("location")); + assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource(resource, provider)); assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key))); + } + @Test + public void testNodesParseLocation() throws Exception { + assertEquals(parser.apply(NodesFromYamlTest.TEST2), expectedNodeMetadataFromResource(resource, zoneCalled( + "virginia", provider))); + assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key))); } } diff --git a/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java b/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java index 4a4b5855f8..fd2e8e05fc 100644 --- a/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java @@ -41,8 +41,16 @@ public class NodesFromYamlTest { .toString(); public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster", - "cluster-1.mydomain.com", "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"), "myUser", - key, null, "happy bear"); + "cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"), + "myUser", key, null, "happy bear"); + + public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster", + "cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", "hadoop", + ImmutableList.of("vanilla"), "myUser", key, null, "happy bear"); + + public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster", + "cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", "hadoop", + ImmutableList.of("vanilla"), "myUser", key, null, "happy bear"); @Test public void testNodesParse() throws Exception { @@ -53,6 +61,15 @@ public class NodesFromYamlTest { assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1)); } + @Test + public void testNodesParseLocation() throws Exception { + + InputStream is = getClass().getResourceAsStream("/test_location.yaml"); + NodesFromYaml parser = new NodesFromYaml(); + + assertEquals(parser.apply(is), ImmutableMap.of(TEST2.getId(), TEST2, TEST3.getId(), TEST3)); + } + @Test public void testNodesParseWhenCredentialInUrl() throws Exception { @@ -66,4 +83,5 @@ public class NodesFromYamlTest { public void testMustParseSomething() throws Exception { new NodesFromYaml().apply(Strings2.toInputStream("")); } -} + +} \ No newline at end of file diff --git a/apis/byon/src/test/resources/test_location.yaml b/apis/byon/src/test/resources/test_location.yaml new file mode 100644 index 0000000000..4f98110789 --- /dev/null +++ b/apis/byon/src/test/resources/test_location.yaml @@ -0,0 +1,43 @@ +nodes: + - id: cluster-1 + name: cluster-1 + description: accounting analytics cluster + hostname: cluster-1.mydomain.com + location_id: virginia + os_arch: x86 + os_family: rhel + os_description: redhat + os_version: 5.3 + group: hadoop + tags: + - vanilla + username: myUser + credential: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2 + u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ + lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o + -----END RSA PRIVATE KEY----- + sudo_password: happy bear + + - id: cluster-2 + name: cluster-2 + description: accounting analytics cluster + hostname: cluster-2.mydomain.com + location_id: maryland + os_arch: x86 + os_family: rhel + os_description: redhat + os_version: 5.3 + group: hadoop + tags: + - vanilla + username: myUser + credential: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2 + u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ + lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o + -----END RSA PRIVATE KEY----- + sudo_password: happy bear + \ No newline at end of file