You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/06/17 20:58:17 UTC
[1/3] jclouds-labs git commit: JCLOUDS-664 Azurecompute-arm compute
service
Repository: jclouds-labs
Updated Branches:
refs/heads/master e4cbe223b -> 88ef0a221
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
index ffa533e..ed5ec9e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
@@ -19,6 +19,7 @@ package org.jclouds.azurecompute.arm.util;
import com.google.common.collect.ImmutableMap;
import com.google.inject.assistedinject.Assisted;
+import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
import org.jclouds.azurecompute.arm.domain.DeploymentProperties;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.azurecompute.arm.domain.DataDisk;
@@ -72,12 +73,11 @@ public class DeploymentTemplateBuilder {
private TemplateOptions options;
private List<ResourceDefinition> resources;
private Map<String, String> variables;
- private String loginUser;
- private String loginPassword;
+ private static String loginUser;
+ private static String loginPassword;
private String location;
+ private AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
- public static final String DEFAULT_LOGIN_USER = "jclouds";
- public static final String DEFAULT_LOGIN_PASSWORD = "Password1!";
private static final String DEPLOYMENT_MODE = "Incremental";
private static final String DEFAULT_DATA_DISK_SIZE = "1023";
@@ -85,24 +85,37 @@ public class DeploymentTemplateBuilder {
private static final String DEFAULT_subnetAddressPrefix = "10.0.0.0/24";
@Inject
- DeploymentTemplateBuilder(Json json, @Assisted("group") String group, @Assisted("name") String name, @Assisted Template template) {
+ DeploymentTemplateBuilder(Json json, @Assisted("group") String group, @Assisted("name") String name, @Assisted Template template,
+ final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
this.name = name;
this.group = group;
this.template = template;
this.options = template.getOptions().as(TemplateOptions.class);
this.variables = new HashMap<String, String>();
this.resources = new ArrayList<ResourceDefinition>();
- this.loginUser = options.getLoginUser() == null ? DEFAULT_LOGIN_USER : options.getLoginUser();
- this.loginPassword = options.getLoginPassword() == null ? DEFAULT_LOGIN_PASSWORD : options.getLoginPassword();
this.location = template.getLocation().getId();
this.json = json;
+
+ this.azureComputeConstants = azureComputeConstants;
+
+ String[] defaultLogin = this.azureComputeConstants.azureDefaultImageLogin().split(":");
+ String defaultUser = null;
+ String defaultPassword = null;
+
+ if (defaultLogin.length == 2) {
+ defaultUser = defaultLogin[0].trim();
+ defaultPassword = defaultLogin[1].trim();
+ }
+
+ loginUser = options.getLoginUser() == null ? defaultUser : options.getLoginUser();
+ loginPassword = options.getLoginPassword() == null ? defaultPassword : options.getLoginPassword();
}
- public String getLoginUserUsername() {
+ public static String getLoginUserUsername() {
return loginUser;
}
- public String getLoginPassword() {
+ public static String getLoginPassword() {
return loginPassword;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java
new file mode 100644
index 0000000..940f785
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.inject.Module;
+import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
+import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.RunScriptOnNodesException;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
+
+import static org.jclouds.compute.predicates.NodePredicates.inGroup;
+import static org.jclouds.compute.options.TemplateOptions.Builder.overrideLoginCredentials;
+import static org.jclouds.scriptbuilder.domain.Statements.exec;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "live", testName = "AzureComputeServiceContextLiveTest")
+public class AzureComputeServiceContextLiveTest extends BaseComputeServiceContextLiveTest {
+
+ public String azureGroup;
+ protected static final int RAND = new Random().nextInt(999);
+
+ @Override
+ protected Module getSshModule() {
+ return new SshjSshClientModule();
+ }
+
+ @Override protected Properties setupProperties() {
+ azureGroup = "jc" + RAND;
+
+ Properties properties = super.setupProperties();
+ long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES);
+ properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
+ properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
+
+ AzureLiveTestUtils.defaultProperties(properties);
+ checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
+
+ properties.put(RESOURCE_GROUP_NAME, azureGroup);
+ return properties;
+ }
+
+ public AzureComputeServiceContextLiveTest() {
+ provider = "azurecompute-arm";
+ }
+
+ @Test
+ public void testDefault() throws RunNodesException {
+
+ final String groupName = this.azureGroup;
+ final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder();
+ templateBuilder.osFamily(OsFamily.UBUNTU);
+ templateBuilder.osVersionMatches("14.04");
+ templateBuilder.hardwareId("Standard_A0");
+ templateBuilder.locationId("westus");
+
+ final Template template = templateBuilder.build();
+
+ try {
+ Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template);
+ assertThat(nodes).hasSize(1);
+ } finally {
+// Do not destroy view.getComputeService().destroyNodesMatching(inGroup(groupName));
+ }
+ }
+
+ private LoginCredentials getLogin() {
+ Credentials credentials = new Credentials("jclouds", "Password1!");
+ LoginCredentials login = LoginCredentials.fromCredentials(credentials);
+ return login;
+ }
+
+ @Test(dependsOnMethods = "testDefault")
+ public void testExec() throws RunScriptOnNodesException {
+ final String groupName = this.azureGroup;
+ String command = "echo hello";
+
+ Map<? extends NodeMetadata, ExecResponse> responses = view.getComputeService().runScriptOnNodesMatching(//
+ inGroup(groupName), // predicate used to select nodes
+ exec(command), // what you actually intend to run
+ overrideLoginCredentials(getLogin()) // use my local user &
+ // ssh key
+ .runAsRoot(false) // don't attempt to run as root (sudo)
+ .wrapInInitScript(false)); // run command directly
+
+ assertTrue(responses.size() > 0);
+ }
+
+ public static Predicate<ComputeMetadata> nameStartsWith(final String prefix) {
+ Preconditions.checkNotNull(prefix, "prefix must be defined");
+
+ return new Predicate<ComputeMetadata>() {
+ @Override
+ public boolean apply(ComputeMetadata computeMetadata) {
+ return computeMetadata.getName().startsWith(prefix);
+ }
+
+ @Override
+ public String toString() {
+ return "nameStartsWith(" + prefix + ")";
+ }
+ };
+ }
+
+ @Test(dependsOnMethods = "testExec")
+ public void testStop() throws RunScriptOnNodesException {
+ final String groupName = this.azureGroup;
+ Set<? extends NodeMetadata> nodes = view.getComputeService().suspendNodesMatching(inGroup(groupName));
+ assertTrue(nodes.size() > 0);
+
+ boolean allStopped = false;
+ while (!allStopped) {
+ nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName));
+ for (NodeMetadata node : nodes) {
+ if (node.getStatus() != NodeMetadata.Status.SUSPENDED)
+ {
+ // Not stopped yet
+ allStopped = false;
+ try {
+ Thread.sleep(15 * 1000);
+ } catch (InterruptedException e) {
+ }
+ continue;
+ }
+ else
+ {
+ allStopped = true;
+ }
+ }
+ }
+ assertTrue(allStopped);
+ }
+
+ @Test(dependsOnMethods = "testStop")
+ public void testStart() throws RunScriptOnNodesException {
+ final String groupName = this.azureGroup;
+ Set<? extends NodeMetadata> nodes = view.getComputeService().resumeNodesMatching(inGroup(groupName));
+ assertTrue(nodes.size() > 0);
+
+ boolean allStarted = false;
+ while (!allStarted) {
+ nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName));
+ for (NodeMetadata node : nodes) {
+ if (node.getStatus() != NodeMetadata.Status.RUNNING)
+ {
+ // Not started yet
+ allStarted = false;
+ try {
+ Thread.sleep(15 * 1000);
+ } catch (InterruptedException e) {
+ }
+ continue;
+ }
+ else
+ {
+ allStarted = true;
+ }
+ }
+ }
+ assertTrue(allStarted);
+ }
+
+ @Test(dependsOnMethods = "testStart")
+ public void testRestart() throws RunScriptOnNodesException {
+ final String groupName = this.azureGroup;
+ Set<? extends NodeMetadata> nodes = view.getComputeService().rebootNodesMatching(inGroup(groupName));
+ assertTrue(nodes.size() > 0);
+
+ boolean allRestarted = false;
+ while (!allRestarted) {
+ nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName));
+ for (NodeMetadata node : nodes) {
+ if (node.getStatus() != NodeMetadata.Status.RUNNING)
+ {
+ // Not started yet
+ allRestarted = false;
+ try {
+ Thread.sleep(30 * 1000);
+ } catch (InterruptedException e) {
+ }
+ continue;
+ }
+ else
+ {
+ allRestarted = true;
+ }
+ }
+ }
+ assertTrue(allRestarted);
+
+ view.getComputeService().destroyNodesMatching(inGroup(groupName));
+ }
+
+ @Test(dependsOnMethods = "testRestart")
+ public void testLinuxNode() throws RunNodesException {
+ final String groupName = this.azureGroup;
+ final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder();
+ templateBuilder.osFamily(OsFamily.UBUNTU);
+ templateBuilder.osVersionMatches("14.04");
+ templateBuilder.hardwareId("Standard_A0");
+ templateBuilder.locationId("westus");
+ final Template template = templateBuilder.build();
+
+ try {
+ Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template);
+ assertThat(nodes).hasSize(1);
+ } finally {
+ view.getComputeService().destroyNodesMatching(inGroup(groupName));
+ }
+ }
+
+ @Test(dependsOnMethods = "testLinuxNode")
+ public void testWindowsNode() throws RunNodesException {
+ final String groupName = this.azureGroup;
+ final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder();
+ templateBuilder.imageId("global/MicrosoftWindowsServer/WindowsServer/Windows-Server-Technical-Preview");
+ templateBuilder.hardwareId("Standard_A0");
+ templateBuilder.locationId("westus");
+ final Template template = templateBuilder.build();
+
+ try {
+ Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template);
+ assertThat(nodes).hasSize(1);
+ } finally {
+ view.getComputeService().destroyNodesMatching(inGroup(groupName));
+ }
+ }
+
+ @Override
+ protected ProviderMetadata createProviderMetadata() {
+ AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
+ return pm;
+ }
+
+ protected String setIfTestSystemPropertyPresent(Properties overrides, String key) {
+ if (System.getProperties().containsKey("test." + key)) {
+ String val = System.getProperty("test." + key);
+ overrides.setProperty(key, val);
+ return val;
+ } else {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java
new file mode 100644
index 0000000..ae43511
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute;
+
+import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+import org.jclouds.providers.ProviderMetadata;
+
+import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
+import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
+
+import com.google.inject.Module;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Live tests for the {@link org.jclouds.compute.ComputeService} integration.
+ */
+@Test(groups = "live", singleThreaded = true, testName = "AzureComputeServiceLiveTest")
+public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
+ public String azureGroup;
+
+ public AzureComputeServiceLiveTest() {
+ provider = "azurecompute-arm";
+ }
+
+ @Override
+ protected Module getSshModule() {
+ return new SshjSshClientModule();
+ }
+
+ @Override
+ protected ProviderMetadata createProviderMetadata() {
+ AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
+ return pm;
+ }
+
+ @Override protected Properties setupProperties() {
+ azureGroup = "jc" + System.getProperty("user.name").substring(0, 3);
+ Properties properties = super.setupProperties();
+ long scriptTimeout = TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES);
+ properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
+ properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
+ properties.put(RESOURCE_GROUP_NAME, azureGroup);
+
+ AzureLiveTestUtils.defaultProperties(properties);
+ checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
+
+ return properties;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureTemplateBuilderLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureTemplateBuilderLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureTemplateBuilderLiveTest.java
new file mode 100644
index 0000000..652c12a
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureTemplateBuilderLiveTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute;
+
+import com.google.inject.Module;
+import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
+import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
+import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.collect.ImmutableSet;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
+
+@Test(groups = "live", testName = "AzureTemplateBuilderLiveTest")
+public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
+ public String azureGroup;
+
+ @Override
+ protected Set<String> getIso3166Codes() {
+ return ImmutableSet.of("US-IA", "US-VA", "US-IL", "US-TX", "US-CA", "IE", "NL", "HK", "SG", "JP-11", "JP-27", "BR", "AU-NSW", "AU-VIC");
+ }
+
+ public AzureTemplateBuilderLiveTest() {
+ provider = "azurecompute-arm";
+ }
+
+ @Override
+ protected Module getSshModule() {
+ return new SshjSshClientModule();
+ }
+
+ @Override
+ protected ProviderMetadata createProviderMetadata() {
+ AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
+ return pm;
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ azureGroup = "jc" + System.getProperty("user.name").substring(0, 3);
+ Properties properties = super.setupProperties();
+ long scriptTimeout = TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES);
+ properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
+ properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
+ properties.put(RESOURCE_GROUP_NAME, azureGroup);
+
+ AzureLiveTestUtils.defaultProperties(properties);
+ checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
+
+ return properties;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderAPIMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderAPIMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderAPIMockTest.java
new file mode 100644
index 0000000..70f2ad6
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderAPIMockTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.features;
+
+import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "NetworkInterfaceCardApiMockTest", singleThreaded = true)
+public class ResourceProviderAPIMockTest extends BaseAzureComputeApiMockTest {
+
+ final String apiVersion = "2015-01-01";
+ final String resource = "Microsoft.Compute";
+ private final String vm_resource = "virtualMachines";
+
+ public void getPublicIPAddressInfo() throws InterruptedException {
+ server.enqueue(jsonResponse("/getresourceprovidermetadata.json"));
+
+ final ResourceProviderApi resourceProviderApi = api.getResourceProviderApi();
+
+ List<ResourceProviderMetaData> metaDatas = resourceProviderApi.get(resource);
+
+ String path = String.format("/subscriptions/SUBSCRIPTIONID/providers/%s?api-version=%s", resource, apiVersion);
+
+ assertSent(server, "GET", path);
+ assertTrue(metaDatas.size() > 0);
+ ResourceProviderMetaData md = metaDatas.get(0);
+
+ assertEquals(md.resourceType(), "availabilitySets");
+ assertEquals(md.locations().get(0), "East US");
+ assertEquals(md.apiVersions().get(0), "2016-03-30");
+ }
+
+ public void getPublicIPAddressInfoEmpty() throws InterruptedException {
+ server.enqueue(response404());
+
+ final ResourceProviderApi resourceProviderApi = api.getResourceProviderApi();
+
+ List<ResourceProviderMetaData> metaDatas = resourceProviderApi.get(resource);
+
+ String path = String.format("/subscriptions/SUBSCRIPTIONID/providers/%s?api-version=%s", resource, apiVersion);
+
+ assertSent(server, "GET", path);
+ assertNull(metaDatas);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderApiLiveTest.java
new file mode 100644
index 0000000..5ebf996
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/ResourceProviderApiLiveTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.features;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+
+@Test(groups = "live", testName = "ResourceProviderApiLiveTest")
+public class ResourceProviderApiLiveTest extends BaseAzureComputeApiLiveTest {
+
+ private final String PROVIDER = "Microsoft.Compute";
+ private final String VM_RESOURCE_TYPE = "virtualMachines";
+
+ private ResourceProviderApi api() {
+ return api.getResourceProviderApi();
+ }
+
+ @Test
+ public void testGetComputeProviderMetadata() {
+
+ List<ResourceProviderMetaData> resourceProviderMetaDatas = api().get(PROVIDER);
+
+ assertNotNull(resourceProviderMetaDatas);
+
+ assertTrue(Iterables.any(resourceProviderMetaDatas, new Predicate<ResourceProviderMetaData>() {
+ @Override
+ public boolean apply(final ResourceProviderMetaData providerMetaData) {
+ return providerMetaData.resourceType().equals(VM_RESOURCE_TYPE);
+ }
+ }));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/AbstractAzureComputeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/AbstractAzureComputeApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/AbstractAzureComputeApiLiveTest.java
index bd55694..337812b 100644
--- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/AbstractAzureComputeApiLiveTest.java
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/AbstractAzureComputeApiLiveTest.java
@@ -17,20 +17,19 @@
package org.jclouds.azurecompute.arm.internal;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
import java.util.Properties;
import java.util.Random;
+import com.google.inject.Module;
+import com.google.inject.Injector;
+
+
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
-import org.jclouds.compute.config.ComputeServiceProperties;
import org.jclouds.providers.ProviderMetadata;
+
public abstract class AbstractAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi> {
protected static final int RAND = new Random().nextInt(999);
@@ -39,19 +38,16 @@ public abstract class AbstractAzureComputeApiLiveTest extends BaseApiLiveTest<Az
provider = "azurecompute-arm";
}
+ @Override protected AzureComputeApi create(Properties props, Iterable<Module> modules) {
+ Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
+ return injector.getInstance(AzureComputeApi.class);
+ }
+
@Override protected Properties setupProperties() {
Properties properties = super.setupProperties();
- properties.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, 1000);
- properties.put(ComputeServiceProperties.POLL_MAX_PERIOD, 10000);
- properties.setProperty(OPERATION_TIMEOUT, "60000");
- properties.setProperty(OPERATION_POLL_INITIAL_PERIOD, "5");
- properties.setProperty(OPERATION_POLL_MAX_PERIOD, "15");
- properties.setProperty(TCP_RULE_FORMAT, "tcp_%s-%s");
- properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
// for oauth
AzureLiveTestUtils.defaultProperties(properties);
- checkNotNull(setIfTestSystemPropertyPresent(properties, "jclouds.oauth.resource"), "test.jclouds.oauth.resource");
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
return properties;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
index 900d3e0..bd9adfc 100644
--- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
@@ -65,25 +65,6 @@ public class BaseAzureComputeApiLiveTest extends AbstractAzureComputeApiLiveTest
private String storageServiceName = null;
-
- protected String getCredential() {
- String credential = null;
- if (System.getProperty("test.azurecompute-arm.credential") != null) {
- credential = System.getProperty("test.azurecompute-arm.credential");
- }
- assertNotNull(credential);
- return credential;
- }
-
- protected String getIdentity() {
- String identity = null;
- if (System.getProperty("test.azurecompute-arm.identity") != null) {
- identity = System.getProperty("test.azurecompute-arm.identity");
- }
- assertNotNull(identity);
- return identity;
- }
-
protected String getStorageServiceName() {
if (storageServiceName == null) {
storageServiceName = String.format("%3.24s",
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/test/resources/getresourceprovidermetadata.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/getresourceprovidermetadata.json b/azurecompute-arm/src/test/resources/getresourceprovidermetadata.json
new file mode 100644
index 0000000..b7693d7
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/getresourceprovidermetadata.json
@@ -0,0 +1,366 @@
+{
+ "id": "/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute",
+ "namespace": "Microsoft.Compute",
+ "authorization": {
+ "applicationId": "12312312-1212-1212-1212-121212121212",
+ "roleDefinitionId": "34534534-272e-4238-8723-123423452224"
+ },
+ "resourceTypes": [
+ {
+ "resourceType": "availabilitySets",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ],
+ "capabilities": "CrossResourceGroupResourceMove, CrossSubscriptionResourceMove"
+ },
+ {
+ "resourceType": "virtualMachines",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ],
+ "capabilities": "CrossResourceGroupResourceMove, CrossSubscriptionResourceMove"
+ },
+ {
+ "resourceType": "virtualMachines/extensions",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ],
+ "capabilities": "CrossResourceGroupResourceMove, CrossSubscriptionResourceMove"
+ },
+ {
+ "resourceType": "virtualMachines/diagnosticSettings",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2014-04-01"
+ ]
+ },
+ {
+ "resourceType": "virtualMachines/metricDefinitions",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2014-04-01"
+ ]
+ },
+ {
+ "resourceType": "virtualMachineScaleSets",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ],
+ "capabilities": "None"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/extensions",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ],
+ "capabilities": "CrossResourceGroupResourceMove, CrossSubscriptionResourceMove"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/virtualMachines",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/networkInterfaces",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/virtualMachines/networkInterfaces",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "locations",
+ "locations": [],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "locations/operations",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "locations/vmSizes",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "locations/usages",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "locations/publishers",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ },
+ {
+ "resourceType": "operations",
+ "locations": [
+ "East US",
+ "East US 2",
+ "West US",
+ "Central US",
+ "North Central US",
+ "South Central US",
+ "North Europe",
+ "West Europe",
+ "East Asia",
+ "Southeast Asia",
+ "Japan East",
+ "Japan West",
+ "Brazil South"
+ ],
+ "apiVersions": [
+ "2016-03-30",
+ "2015-06-15",
+ "2015-05-01-preview"
+ ]
+ }
+ ],
+ "registrationState": "Registered"
+}
\ No newline at end of file
[3/3] jclouds-labs git commit: Algin labs providers with the new
NodeAndTemplateOptionsToStatement interface
Posted by na...@apache.org.
Algin labs providers with the new NodeAndTemplateOptionsToStatement interface
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/88ef0a22
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/88ef0a22
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/88ef0a22
Branch: refs/heads/master
Commit: 88ef0a2210afb5a079b59f03899d18141cdc5acc
Parents: 03f72d5
Author: Ignasi Barrera <na...@apache.org>
Authored: Fri Jun 17 22:22:35 2016 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Jun 17 22:52:44 2016 +0200
----------------------------------------------------------------------
.../CloudSigma2ComputeServiceContextModule.java | 36 +++++-----
...plateOptionsToStatementWithoutPublicKey.java | 59 ---------------
...eOptionsToStatementWithoutPublicKeyTest.java | 75 --------------------
3 files changed, 19 insertions(+), 151 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/88ef0a22/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/config/CloudSigma2ComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/config/CloudSigma2ComputeServiceContextModule.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/config/CloudSigma2ComputeServiceContextModule.java
index 84497e4..cd9e5d8 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/config/CloudSigma2ComputeServiceContextModule.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/config/CloudSigma2ComputeServiceContextModule.java
@@ -16,18 +16,21 @@
*/
package org.jclouds.cloudsigma2.compute.config;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.cloudsigma2.config.CloudSigma2Properties.TIMEOUT_DRIVE_CLONED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
import org.jclouds.cloudsigma2.CloudSigma2Api;
import org.jclouds.cloudsigma2.compute.functions.LibraryDriveToImage;
import org.jclouds.cloudsigma2.compute.functions.NICToAddress;
import org.jclouds.cloudsigma2.compute.functions.ServerDriveToVolume;
import org.jclouds.cloudsigma2.compute.functions.ServerInfoToNodeMetadata;
-import org.jclouds.cloudsigma2.compute.functions.TemplateOptionsToStatementWithoutPublicKey;
import org.jclouds.cloudsigma2.compute.options.CloudSigma2TemplateOptions;
import org.jclouds.cloudsigma2.compute.strategy.CloudSigma2ComputeServiceAdapter;
import org.jclouds.cloudsigma2.domain.DriveInfo;
@@ -43,21 +46,20 @@ import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Volume;
-import org.jclouds.compute.functions.TemplateOptionsToStatement;
+import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement;
+import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.domain.Location;
import org.jclouds.functions.IdentityFunction;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.cloudsigma2.config.CloudSigma2Properties.TIMEOUT_DRIVE_CLONED;
-import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
-import static org.jclouds.util.Predicates2.retry;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
public class CloudSigma2ComputeServiceContextModule extends
ComputeServiceAdapterContextModule<ServerInfo, Hardware, LibraryDrive, Location> {
@@ -84,7 +86,7 @@ public class CloudSigma2ComputeServiceContextModule extends
}).to(NICToAddress.class);
bind(TemplateOptions.class).to(CloudSigma2TemplateOptions.class);
- bind(TemplateOptionsToStatement.class).to(TemplateOptionsToStatementWithoutPublicKey.class);
+ bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class);
}
@VisibleForTesting
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/88ef0a22/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
deleted file mode 100644
index 077917b..0000000
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.cloudsigma2.compute.functions;
-
-import com.google.common.collect.ImmutableList;
-import org.jclouds.compute.functions.TemplateOptionsToStatement;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.scriptbuilder.InitScript;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.StatementList;
-import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey;
-
-import javax.inject.Singleton;
-
-/**
- * Convert the template options into a statement, but ignoring the public key.
- * <p/>
- * The {@link org.jclouds.cloudsigma2.compute.strategy.CloudSigma2ComputeServiceAdapter} already takes care of
- * installing it using the server metadata.
- */
-@Singleton
-public class TemplateOptionsToStatementWithoutPublicKey extends TemplateOptionsToStatement {
-
- @Override
- public Statement apply(TemplateOptions options) {
- ImmutableList.Builder<Statement> builder = ImmutableList.builder();
- if (options.getRunScript() != null) {
- builder.add(options.getRunScript());
- }
- if (options.getPrivateKey() != null) {
- builder.add(new InstallRSAPrivateKey(options.getPrivateKey()));
- }
-
- ImmutableList<Statement> bootstrap = builder.build();
- if (bootstrap.isEmpty()) {
- return null;
- }
-
- if (options.getTaskName() == null && !(options.getRunScript() instanceof InitScript)) {
- options.nameTask("bootstrap");
- }
- return bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/88ef0a22/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java
deleted file mode 100644
index 93caac0..0000000
--- a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.cloudsigma2.compute.functions;
-
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.scriptbuilder.domain.OsFamily;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.StatementList;
-import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey;
-import org.jclouds.ssh.SshKeys;
-import org.testng.annotations.Test;
-
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-/**
- * Unit tests for the {@link TemplateOptionsToStatementWithoutPublicKey} class.
- */
-@Test(groups = "unit", testName = "TemplateOptionsToStatementWithoutPublicKeyTest")
-public class TemplateOptionsToStatementWithoutPublicKeyTest {
-
- @Test
- public void testPublicKeyDoesNotGenerateAuthorizePublicKeyStatementIfOnlyPublicKeyOptionsConfigured() {
- Map<String, String> keys = SshKeys.generate();
- TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public"));
-
- TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey();
- assertNull(function.apply(options));
- }
-
- @Test
- public void testPublicAndRunScriptKeyDoesNotGenerateAuthorizePublicKeyStatementIfRunScriptPresent() {
- Map<String, String> keys = SshKeys.generate();
- TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public")).runScript("uptime");
-
- TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey();
- Statement statement = function.apply(options);
-
- assertEquals(statement.render(OsFamily.UNIX), "uptime\n");
- }
-
- @Test
- public void testPublicAndPrivateKeyAndRunScriptDoesNotGenerateAuthorizePublicKeyStatementIfOtherOptionsPresent() {
- Map<String, String> keys = SshKeys.generate();
- TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public"))
- .installPrivateKey(keys.get("private")).runScript("uptime");
-
- TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey();
- Statement statement = function.apply(options);
-
- assertTrue(statement instanceof StatementList);
- StatementList statements = (StatementList) statement;
-
- assertEquals(statements.size(), 2);
- assertEquals(statements.get(0).render(OsFamily.UNIX), "uptime\n");
- assertTrue(statements.get(1) instanceof InstallRSAPrivateKey);
- }
-}
[2/3] jclouds-labs git commit: JCLOUDS-664 Azurecompute-arm compute
service
Posted by na...@apache.org.
JCLOUDS-664 Azurecompute-arm compute service
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/03f72d5e
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/03f72d5e
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/03f72d5e
Branch: refs/heads/master
Commit: 03f72d5e2f225f212d05151c1c15a99af14cd29e
Parents: e4cbe22
Author: Rita Zhang <ri...@gmail.com>
Authored: Mon May 16 18:55:01 2016 -0700
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Jun 17 22:24:32 2016 +0200
----------------------------------------------------------------------
azurecompute-arm/README.md | 20 +-
.../azurecompute/arm/AzureComputeApi.java | 11 +-
.../arm/AzureComputeProviderMetadata.java | 21 +-
.../arm/AzureManagementApiMetadata.java | 2 +
.../arm/compute/AzureComputeService.java | 104 +++++
.../arm/compute/AzureComputeServiceAdapter.java | 393 +++++++++++++++++++
.../AzureComputeServiceContextModule.java | 191 +++++++++
.../functions/DeploymentToNodeMetadata.java | 207 ++++++++++
.../compute/functions/LocationToLocation.java | 7 +-
.../compute/functions/VMHardwareToHardware.java | 79 ++++
.../arm/compute/functions/VMImageToImage.java | 124 ++++++
.../CreateResourceGroupThenCreateNodes.java | 96 +++++
.../arm/config/AzureComputeProperties.java | 8 +
.../arm/domain/ResourceProviderMetaData.java | 68 ++++
.../azurecompute/arm/domain/VMDeployment.java | 2 +
.../azurecompute/arm/domain/VMHardware.java | 68 ++++
.../azurecompute/arm/domain/VMImage.java | 53 +++
.../azurecompute/arm/domain/VirtualMachine.java | 2 +-
.../arm/features/ResourceProviderApi.java | 57 +++
.../arm/functions/CleanupResources.java | 107 +++++
.../arm/util/DeploymentTemplateBuilder.java | 31 +-
.../AzureComputeServiceContextLiveTest.java | 284 ++++++++++++++
.../compute/AzureComputeServiceLiveTest.java | 73 ++++
.../compute/AzureTemplateBuilderLiveTest.java | 77 ++++
.../features/ResourceProviderAPIMockTest.java | 67 ++++
.../features/ResourceProviderApiLiveTest.java | 55 +++
.../AbstractAzureComputeApiLiveTest.java | 24 +-
.../internal/BaseAzureComputeApiLiveTest.java | 19 -
.../resources/getresourceprovidermetadata.json | 366 +++++++++++++++++
29 files changed, 2564 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/README.md
----------------------------------------------------------------------
diff --git a/azurecompute-arm/README.md b/azurecompute-arm/README.md
index fc8bb54..c944a8a 100644
--- a/azurecompute-arm/README.md
+++ b/azurecompute-arm/README.md
@@ -53,13 +53,25 @@ azure login -u <Application-id> -p <password> --service-principal --tenant <Tena
## Run Live Tests
-Use the following to run the live tests
+Use the following to run one live test:
+
+```bash
+mvn -Dtest=<name of the live test> \
+ -Dtest.azurecompute-arm.identity="<Application-id>" \
+ -Dtest.azurecompute-arm.credential="<password>" \
+ -Dtest.azurecompute-arm.endpoint="https://management.azure.com/subscriptions/<Subscription-id>" \
+ -Dtest.oauth.endpoint="https://login.microsoftonline.com/<Tenant-id>/oauth2/token" test
+
+```
+
+Use the following to run all the live tests:
```bash
mvn clean verify -Plive \
- -Dtest.azurecompute-arm.identity=<Application-id> \
- -Dtest.azurecompute-arm.credential=<password> \
- -Dtest.azurecompute-arm.endpoint=https://management.azure.com/subscriptions/<Subscription-id> \
+ -Dtest.azurecompute-arm.identity="<Application-id>"" \
+ -Dtest.azurecompute-arm.credential="<password>"" \
+ -Dtest.azurecompute-arm.endpoint="https://management.azure.com/subscriptions/<Subscription-id>"" \
-Dtest.oauth.endpoint=https://login.microsoftonline.com/<Tenant-id>/oauth2/token
+
```
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
index c39022e..42749cf 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
@@ -17,18 +17,19 @@
package org.jclouds.azurecompute.arm;
import org.jclouds.azurecompute.arm.features.DeploymentApi;
+import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
import org.jclouds.azurecompute.arm.features.JobApi;
import org.jclouds.azurecompute.arm.features.LocationApi;
import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
import org.jclouds.azurecompute.arm.features.OSImageApi;
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
+import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
import org.jclouds.azurecompute.arm.features.StorageAccountApi;
import org.jclouds.azurecompute.arm.features.SubnetApi;
import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
import org.jclouds.azurecompute.arm.features.VMSizeApi;
-import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
import org.jclouds.rest.annotations.Delegate;
@@ -156,6 +157,14 @@ public interface AzureComputeApi extends Closeable {
NetworkSecurityRuleApi getNetworkSecurityRuleApi(@PathParam("resourcegroup") String resourcegroup,
@PathParam("networksecuritygroup") String networksecuritygroup);
+ /**
+ * The Azure Resource Provider API provides information about a resource provider and its supported resource types.
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790534.aspx">docs</a>
+ */
+ @Delegate
+ ResourceProviderApi getResourceProviderApi();
+
@Provides
DeploymentTemplateBuilder.Factory deploymentTemplateFactory();
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
index 39defdc..4bbc508 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
@@ -16,11 +16,17 @@
*/
package org.jclouds.azurecompute.arm;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
+
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
@@ -30,6 +36,9 @@ import java.util.Properties;
import org.jclouds.azurecompute.arm.domain.Region;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
+import org.jclouds.compute.config.ComputeServiceProperties;
+
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import com.google.auto.service.AutoService;
@@ -51,13 +60,19 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
public static Properties defaultProperties() {
final Properties properties = AzureManagementApiMetadata.defaultProperties();
- properties.setProperty(OPERATION_TIMEOUT, "60000");
+ properties.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, 1000);
+ properties.put(ComputeServiceProperties.POLL_MAX_PERIOD, 10000);
+ properties.setProperty(OPERATION_TIMEOUT, "46000000");
properties.setProperty(OPERATION_POLL_INITIAL_PERIOD, "5");
properties.setProperty(OPERATION_POLL_MAX_PERIOD, "15");
properties.setProperty(TCP_RULE_FORMAT, "tcp_%s-%s");
properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
- properties.put(RESOURCE, "https://management.azure.com");
+ properties.put(RESOURCE, "https://management.azure.com/");
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
+ properties.put(RESOURCE_GROUP_NAME, "jcloudsgroup");
+ properties.put(IMAGE_PUBLISHERS, "Microsoft.WindowsAzure.Compute, MicrosoftWindowsServer, Canonical");
+ properties.put(DEFAULT_IMAGE_LOGIN, "jclouds:Password1!");
+ properties.put(TIMEOUT_NODE_TERMINATED, 60 * 10 * 1000);
return properties;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
index 9a3292c..989fd84 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
@@ -26,6 +26,7 @@ import org.jclouds.azurecompute.arm.config.AzureComputeHttpApiModule;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.oauth.v2.config.OAuthModule;
+import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
@@ -68,6 +69,7 @@ public class AzureManagementApiMetadata extends BaseHttpApiMetadata<AzureCompute
.defaultProperties(AzureManagementApiMetadata.defaultProperties())
.view(typeToken(ComputeServiceContext.class))
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+ .add(AzureComputeServiceContextModule.class)
.add(OAuthModule.class)
.add(OkHttpCommandExecutorServiceModule.class)
.add(AzureComputeHttpApiModule.class).build());
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java
new file mode 100644
index 0000000..c215e37
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeService.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute;
+
+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 java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.internal.BaseComputeService;
+import org.jclouds.compute.internal.PersistNodeCredentials;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
+import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
+import org.jclouds.compute.strategy.DestroyNodeStrategy;
+import org.jclouds.compute.strategy.GetImageStrategy;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.compute.strategy.RebootNodeStrategy;
+import org.jclouds.compute.strategy.ResumeNodeStrategy;
+import org.jclouds.compute.strategy.SuspendNodeStrategy;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.Location;
+import org.jclouds.azurecompute.arm.functions.CleanupResources;
+import org.jclouds.scriptbuilder.functions.InitAdminAccess;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+@Singleton
+public class AzureComputeService extends BaseComputeService {
+ protected final CleanupResources cleanupResources;
+
+ @Inject
+ protected AzureComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
+ @Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
+ @Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
+ GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy,
+ CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy,
+ DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy,
+ SuspendNodeStrategy stopNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider,
+ @Named("DEFAULT") Provider<TemplateOptions> templateOptionsProvider,
+ @Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning,
+ @Named(TIMEOUT_NODE_TERMINATED) Predicate<AtomicReference<NodeMetadata>> nodeTerminated,
+ @Named(TIMEOUT_NODE_SUSPENDED) Predicate<AtomicReference<NodeMetadata>> nodeSuspended,
+ InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
+ RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
+ PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ CleanupResources cleanupResources,
+ Optional<ImageExtension> imageExtension,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
+ super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
+ getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
+ startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
+ nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
+ persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension);
+ this.cleanupResources = checkNotNull(cleanupResources, "cleanupResources");
+
+ }
+
+ @Override
+ protected void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
+ for (NodeMetadata deadNode : deadNodes) {
+ cleanupResources.apply(deadNode.getId());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
new file mode 100644
index 0000000..9a1d221
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute;
+
+import static java.lang.String.format;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.util.Predicates2.retry;
+import java.util.ArrayList;
+
+import java.util.Collection;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.net.UrlEscapers;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
+import org.jclouds.azurecompute.arm.domain.Deployment;
+import org.jclouds.azurecompute.arm.domain.DeploymentBody;
+import org.jclouds.azurecompute.arm.domain.DeploymentProperties;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VMHardware;
+import org.jclouds.azurecompute.arm.domain.Location;
+import org.jclouds.azurecompute.arm.domain.Offer;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
+import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
+import org.jclouds.azurecompute.arm.domain.SKU;
+import org.jclouds.azurecompute.arm.domain.VMDeployment;
+import org.jclouds.azurecompute.arm.domain.VMSize;
+import org.jclouds.azurecompute.arm.domain.VirtualMachine;
+import org.jclouds.azurecompute.arm.features.DeploymentApi;
+import org.jclouds.azurecompute.arm.features.OSImageApi;
+import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
+import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.logging.Logger;
+import org.jclouds.azurecompute.arm.functions.CleanupResources;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.base.Splitter;
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
+ * {@link org.jclouds.compute.ComputeService}.
+ */
+@Singleton
+public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeployment, VMHardware, VMImage, Location> {
+
+ private String azureGroup;
+ protected final CleanupResources cleanupResources;
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ private Logger logger = Logger.NULL;
+
+ private final AzureComputeApi api;
+
+ private final AzureComputeConstants azureComputeConstants;
+
+ @Inject
+ AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
+ CleanupResources cleanupResources) {
+
+ this.api = api;
+ this.azureComputeConstants = azureComputeConstants;
+
+ this.azureGroup = azureComputeConstants.azureResourceGroup();
+
+ logger.debug("AzureComputeServiceAdapter set azuregroup to: " + azureGroup);
+
+ this.cleanupResources = cleanupResources;
+ }
+
+ @Override
+ public NodeAndInitialCredentials<VMDeployment> createNodeWithGroupEncodedIntoName(
+ final String group, final String name, final Template template) {
+
+ DeploymentTemplateBuilder deploymentTemplateBuilder = api.deploymentTemplateFactory().create(group, name, template);
+
+ final String loginUser = DeploymentTemplateBuilder.getLoginUserUsername();
+ final String loginPassword = DeploymentTemplateBuilder.getLoginPassword();
+
+ DeploymentBody deploymentTemplateBody = deploymentTemplateBuilder.getDeploymentTemplate();
+
+ DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody);
+
+ final String deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplateBuilder.getDeploymentTemplateJson(properties));
+
+ logger.debug("Deployment created with name: %s group: %s", name, group);
+
+
+
+ final Set<VMDeployment> deployments = Sets.newHashSet();
+
+ final DeploymentApi deploymentApi = api.getDeploymentApi(group);
+
+ if (!retry(new Predicate<String>() {
+ @Override
+ public boolean apply(final String name) {
+
+ Deployment deployment = deploymentApi.create(name, deploymentTemplate);
+
+ if (deployment != null) {
+ VMDeployment vmDeployment = new VMDeployment();
+ vmDeployment.deployment = deployment;
+ deployments.add(vmDeployment);
+ } else {
+ logger.debug("Failed to create deployment!");
+ }
+ return !deployments.isEmpty();
+ }
+ }, azureComputeConstants.operationTimeout(), 1, SECONDS).apply(name)) {
+ final String illegalStateExceptionMessage = format("Deployment %s was not created within %sms so it will be destroyed.",
+ name, azureComputeConstants.operationTimeout());
+ logger.warn(illegalStateExceptionMessage);
+ destroyNode(name);
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ }
+
+ final VMDeployment deployment = deployments.iterator().next();
+
+
+ return new NodeAndInitialCredentials<VMDeployment>(deployment, name,
+ LoginCredentials.builder().user(loginUser).identity(loginUser).password(loginPassword).authenticateSudo(true).build());
+ }
+
+ @Override
+ public Iterable<VMHardware> listHardwareProfiles() {
+
+ final List<VMHardware> hwProfiles = Lists.newArrayList();
+ final List<String> locationIds = Lists.newArrayList();
+
+ Iterable<Location> locations = listLocations();
+ for (Location location : locations){
+ locationIds.add(location.name());
+
+ Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
+
+ for (VMSize vmSize : vmSizes){
+ VMHardware hwProfile = new VMHardware();
+ hwProfile.name = vmSize.name();
+ hwProfile.numberOfCores = vmSize.numberOfCores();
+ hwProfile.osDiskSizeInMB = vmSize.osDiskSizeInMB();
+ hwProfile.resourceDiskSizeInMB = vmSize.resourceDiskSizeInMB();
+ hwProfile.memoryInMB = vmSize.memoryInMB();
+ hwProfile.maxDataDiskCount = vmSize.maxDataDiskCount();
+ hwProfile.location = location.name();
+ hwProfiles.add(hwProfile);
+ }
+
+ }
+
+ checkAndSetHwAvailability(hwProfiles, Sets.newHashSet(locationIds));
+
+ return hwProfiles;
+ }
+ private void checkAndSetHwAvailability(List<VMHardware> hwProfiles, Collection<String> locations) {
+ Multimap<String, String> hwMap = ArrayListMultimap.create();
+ for (VMHardware hw : hwProfiles) {
+ hwMap.put(hw.name, hw.location);
+ }
+
+ for (VMHardware hw : hwProfiles) {
+ hw.globallyAvailable = hwMap.get(hw.name).containsAll(locations);
+ }
+ }
+
+ private void getImagesFromPublisher(String publisherName, List<VMImage> osImagesRef, String location) {
+
+ OSImageApi osImageApi = api.getOSImageApi(location);
+
+ Iterable<Offer> offerList = osImageApi.listOffers(publisherName);
+
+ for (Offer offer : offerList) {
+ Iterable<SKU> skuList = osImageApi.listSKUs(publisherName, offer.name());
+
+ for (SKU sku : skuList) {
+ VMImage vmImage = new VMImage();
+ vmImage.publisher = publisherName;
+ vmImage.offer = offer.name();
+ vmImage.sku = sku.name();
+ vmImage.location = location;
+ osImagesRef.add(vmImage);
+ }
+ }
+ }
+
+ private List<VMImage> listImagesByLocation(String location) {
+ final List<VMImage> osImages = Lists.newArrayList();
+ Iterable<String> publishers = Splitter.on(',').trimResults().omitEmptyStrings().split(this.azureComputeConstants.azureImagePublishers());
+ for (String publisher : publishers) {
+ getImagesFromPublisher(publisher, osImages, location);
+ }
+ return osImages;
+ }
+
+ @Override
+ public Iterable<VMImage> listImages() {
+
+ final List<VMImage> osImages = Lists.newArrayList();
+ final List<String> locationIds = Lists.newArrayList();
+
+ for (Location location : listLocations()){
+ locationIds.add(location.name());
+ osImages.addAll(listImagesByLocation(location.name()));
+ }
+ checkAndSetImageAvailability(osImages, Sets.newHashSet(locationIds));
+ return osImages;
+ }
+
+ private void checkAndSetImageAvailability(List<VMImage> images, Collection<String> locations) {
+ Multimap<String, String> map = ArrayListMultimap.create();
+
+ for (VMImage image : images) {
+ map.put( image.offer + "/" + image.sku, image.location);
+ }
+
+ for (VMImage image : images) {
+ image.globallyAvailable = map.get(image.offer + "/" + image.sku).containsAll(locations);
+ }
+ }
+
+ @Override
+ public VMImage getImage(final String id) {
+ String[] fields = VMImageToImage.decodeFieldsFromUniqueId(id);
+
+ Iterable<VMImage> images = listImages();
+
+ for (VMImage image : images) {
+ String imageId = VMImageToImage.encodeFieldsToUniqueId(image);
+ if (id.equals(imageId)){
+ return image;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<Location> listLocations() {
+ List<Location> locations = api.getLocationApi().list();
+
+ List<ResourceProviderMetaData> resources = api.getResourceProviderApi().get("Microsoft.Compute");
+
+ final List<String> vmLocations = new ArrayList<String>();
+
+ for (ResourceProviderMetaData m : resources){
+ if (m.resourceType().equals("virtualMachines")){
+ vmLocations.addAll(m.locations());
+ break;
+ }
+ }
+
+ Iterable<Location> result = Iterables.filter(locations, new Predicate<Location>() {
+ @Override
+ public boolean apply(Location input) {
+ return vmLocations.contains(input.displayName());
+ }
+ });
+
+ return result;
+ }
+
+ private String getResourceGroupFromId(String id) {
+ String searchStr = "/resourceGroups/";
+ int indexStart = id.lastIndexOf(searchStr) + searchStr.length();
+ searchStr = "/providers/";
+ int indexEnd = id.lastIndexOf(searchStr);
+
+ String resourceGroup = id.substring(indexStart, indexEnd);
+ return resourceGroup;
+ }
+
+ @Override
+ public VMDeployment getNode(final String id) {
+ Deployment deployment = api.getDeploymentApi(azureGroup).get(id);
+ if (deployment == null)
+ return null;
+ String resourceGroup = getResourceGroupFromId(deployment.id());
+ VMDeployment vmDeployment = new VMDeployment();
+ vmDeployment.deployment = deployment;
+ List<PublicIPAddress> list = getIPAddresses(deployment);
+ vmDeployment.ipAddressList = list;
+
+ VirtualMachine vm = api.getVirtualMachineApi(azureGroup).get(id);
+ vmDeployment.virtualMachine = vm;
+ return vmDeployment;
+ }
+
+ @Override
+ public void destroyNode(final String id) {
+ checkState(cleanupResources.apply(id), "server(%s) and its resources still there after deleting!?", id);
+ }
+
+ @Override
+ public void rebootNode(final String id) {
+ api.getVirtualMachineApi(azureGroup).restart(id);
+ }
+
+ @Override
+ public void resumeNode(final String id) {
+ api.getVirtualMachineApi(azureGroup).start(id);
+ }
+
+ @Override
+ public void suspendNode(final String id) {
+ api.getVirtualMachineApi(azureGroup).stop(id);
+ }
+
+ private List<PublicIPAddress> getIPAddresses(Deployment deployment) {
+ List<PublicIPAddress> list = new ArrayList<PublicIPAddress>();
+ String resourceGroup = getResourceGroupFromId(deployment.id());
+
+ if (deployment.properties() != null && deployment.properties().dependencies() != null) {
+ List<Deployment.Dependency> dependencies = deployment.properties().dependencies();
+ for (int d = 0; d < dependencies.size(); d++) {
+ if (dependencies.get(d).resourceType().equals("Microsoft.Network/networkInterfaces")) {
+ List<Deployment.Dependency> dependsOn = dependencies.get(d).dependsOn();
+ for (int e = 0; e < dependsOn.size(); e++) {
+ if (dependsOn.get(e).resourceType().equals("Microsoft.Network/publicIPAddresses")) {
+ String resourceName = dependsOn.get(e).resourceName();
+ PublicIPAddress ip = api.getPublicIPAddressApi(resourceGroup).get(resourceName);
+ list.add(ip);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return list;
+ }
+
+ @Override
+ public Iterable<VMDeployment> listNodes() {
+ List<Deployment> deployments = api.getDeploymentApi(azureGroup).list();
+
+ List<VMDeployment> vmDeployments = new ArrayList<VMDeployment>();
+
+ for (Deployment d : deployments){
+ VMDeployment vmDeployment = new VMDeployment();
+ vmDeployment.deployment = d;
+ VirtualMachineApi vmApi = api.getVirtualMachineApi(azureGroup);
+ vmDeployment.vm = vmApi.getInstanceDetails(d.name());
+ List<PublicIPAddress> list = getIPAddresses(d);
+ vmDeployment.ipAddressList = list;
+
+ VirtualMachine virtualMachine = vmApi.get(d.name());
+ vmDeployment.virtualMachine = virtualMachine;
+
+ vmDeployments.add(vmDeployment);
+ }
+ return vmDeployments;
+ }
+
+ @Override
+ public Iterable<VMDeployment> listNodesByIds(final Iterable<String> ids) {
+ return Iterables.filter(listNodes(), new Predicate<VMDeployment>() {
+ @Override
+ public boolean apply(final VMDeployment input) {
+ return Iterables.contains(ids, input.deployment.name());
+ }
+ });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
new file mode 100644
index 0000000..9844be4
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute.config;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+import com.google.inject.Provides;
+
+import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter;
+import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
+import org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata;
+import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
+import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
+import org.jclouds.azurecompute.arm.domain.VMDeployment;
+import org.jclouds.azurecompute.arm.domain.VMHardware;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.Location;
+import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
+import org.jclouds.azurecompute.arm.compute.AzureComputeService;
+
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
+import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
+import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
+import org.jclouds.compute.ComputeService;
+import static org.jclouds.util.Predicates2.retry;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+import com.google.common.base.Predicate;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.VisibleForTesting;
+import java.net.URI;
+
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+
+public class AzureComputeServiceContextModule
+ extends ComputeServiceAdapterContextModule<VMDeployment, VMHardware, VMImage, Location> {
+
+ @Override
+ protected void configure() {
+ super.configure();
+ bind(new TypeLiteral<ComputeServiceAdapter<VMDeployment, VMHardware, VMImage, Location>>() {
+ }).to(AzureComputeServiceAdapter.class);
+ bind(new TypeLiteral<Function<VMImage, org.jclouds.compute.domain.Image>>() {
+ }).to(VMImageToImage.class);
+ bind(new TypeLiteral<Function<VMHardware, Hardware>>() {
+ }).to(VMHardwareToHardware.class);
+ bind(new TypeLiteral<Function<VMDeployment, NodeMetadata>>() {
+ }).to(DeploymentToNodeMetadata.class);
+ bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {
+ }).to(LocationToLocation.class);
+ bind(ComputeService.class).to(AzureComputeService.class);
+ install(new LocationsFromComputeServiceAdapterModule<VMDeployment, VMHardware, VMImage, Location>() {
+ });
+
+ bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
+ }
+
+ @Singleton
+ public static class AzureComputeConstants {
+
+ @Named(OPERATION_TIMEOUT)
+ @Inject
+ private String operationTimeoutProperty;
+
+ @Named(OPERATION_POLL_INITIAL_PERIOD)
+ @Inject
+ private String operationPollInitialPeriodProperty;
+
+ @Named(OPERATION_POLL_MAX_PERIOD)
+ @Inject
+ private String operationPollMaxPeriodProperty;
+
+ @Named(TCP_RULE_FORMAT)
+ @Inject
+ private String tcpRuleFormatProperty;
+
+ @Named(TCP_RULE_REGEXP)
+ @Inject
+ private String tcpRuleRegexpProperty;
+
+ @Named(RESOURCE_GROUP_NAME)
+ @Inject
+ private String azureResourceGroupProperty;
+
+ @Named(IMAGE_PUBLISHERS)
+ @Inject
+ private String azureImagePublishersProperty;
+
+ @Named(DEFAULT_IMAGE_LOGIN)
+ @Inject
+ private String azureDefaultImageLoginProperty;
+
+ public Long operationTimeout() {
+ return Long.parseLong(operationTimeoutProperty);
+ }
+
+ public String azureResourceGroup() {
+ return azureResourceGroupProperty;
+ }
+
+ public String azureImagePublishers() {
+ return azureImagePublishersProperty;
+ }
+
+ public String azureDefaultImageLogin() {
+ return azureDefaultImageLoginProperty;
+ }
+
+ public Integer operationPollInitialPeriod() {
+ return Integer.parseInt(operationPollInitialPeriodProperty);
+ }
+
+ public Integer operationPollMaxPeriod() {
+ return Integer.parseInt(operationPollMaxPeriodProperty);
+ }
+
+ public String tcpRuleFormat() {
+ return tcpRuleFormatProperty;
+ }
+
+ public String tcpRuleRegexp() {
+ return tcpRuleRegexpProperty;
+ }
+ }
+
+ @Provides
+ @Named(TIMEOUT_NODE_TERMINATED)
+ protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, Timeouts timeouts,
+ PollPeriod pollPeriod) {
+ return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
+ pollPeriod.pollMaxPeriod);
+ }
+
+ @Provides
+ @Named(TIMEOUT_RESOURCE_DELETED)
+ protected Predicate<URI> provideResourceDeletedPredicate(final AzureComputeApi api, Timeouts timeouts,
+ PollPeriod pollPeriod) {
+ return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
+ pollPeriod.pollMaxPeriod);
+ }
+
+ @VisibleForTesting
+ static class ActionDonePredicate implements Predicate<URI> {
+
+ private final AzureComputeApi api;
+
+ public ActionDonePredicate(AzureComputeApi api) {
+ this.api = checkNotNull(api, "api must not be null");
+ }
+
+ @Override
+ public boolean apply(URI uri) {
+ checkNotNull(uri, "uri cannot be null");
+ return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
new file mode 100644
index 0000000..bccc63c
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute.functions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import com.google.common.collect.Sets;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.domain.ComputeNode;
+import org.jclouds.azurecompute.arm.domain.Deployment;
+import org.jclouds.azurecompute.arm.domain.ImageReference;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
+import org.jclouds.azurecompute.arm.domain.VMDeployment;
+import org.jclouds.azurecompute.arm.domain.VMHardware;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VMSize;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
+import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.Location;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Hardware;
+
+public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMetadata> {
+
+ public static final String AZURE_LOGIN_USERNAME = DeploymentTemplateBuilder.getLoginUserUsername();
+ public static final String AZURE_LOGIN_PASSWORD = DeploymentTemplateBuilder.getLoginPassword();
+
+ private static final Map<ComputeNode.Status, NodeMetadata.Status> INSTANCESTATUS_TO_NODESTATUS =
+ ImmutableMap.<ComputeNode.Status, NodeMetadata.Status>builder().
+ put(ComputeNode.Status.GOOD, NodeMetadata.Status.RUNNING).
+ put(ComputeNode.Status.BAD, NodeMetadata.Status.ERROR).
+ put(ComputeNode.Status.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
+ build();
+
+ // When using the Deployment API to deploy an ARM template, the deployment goes through
+ // stages. Accepted -> Running -> Succeeded. Only when the deployment has SUCCEEDED is
+ // the resource deployed using the template actually ready.
+ //
+ // To get details about the resource(s) deployed via template, one needs to query the
+ // various resources after the deployment has "SUCCEEDED".
+ private static final Map<Deployment.ProvisioningState, NodeMetadata.Status> STATUS_TO_NODESTATUS =
+ ImmutableMap.<Deployment.ProvisioningState, NodeMetadata.Status>builder().
+ put(Deployment.ProvisioningState.ACCEPTED, NodeMetadata.Status.PENDING).
+ put(Deployment.ProvisioningState.READY, NodeMetadata.Status.PENDING).
+ put(Deployment.ProvisioningState.RUNNING, NodeMetadata.Status.PENDING).
+ put(Deployment.ProvisioningState.CANCELED, NodeMetadata.Status.TERMINATED).
+ put(Deployment.ProvisioningState.FAILED, NodeMetadata.Status.ERROR).
+ put(Deployment.ProvisioningState.DELETED, NodeMetadata.Status.TERMINATED).
+ put(Deployment.ProvisioningState.SUCCEEDED, NodeMetadata.Status.RUNNING).
+ put(Deployment.ProvisioningState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
+ build();
+
+ public static Deployment.ProvisioningState provisioningStateFromString(final String text) {
+ return (Deployment.ProvisioningState) GetEnumValue.fromValueOrDefault(text, Deployment.ProvisioningState.UNRECOGNIZED);
+ }
+
+ private final AzureComputeApi api;
+
+ private final LocationToLocation locationToLocation;
+
+ private final GroupNamingConvention nodeNamingConvention;
+
+ private final VMImageToImage vmImageToImage;
+
+ private final VMHardwareToHardware vmHardwareToHardware;
+
+ private final Map<String, Credentials> credentialStore;
+
+ @Inject
+ DeploymentToNodeMetadata(
+ AzureComputeApi api,
+ LocationToLocation locationToLocation,
+ GroupNamingConvention.Factory namingConvention, VMImageToImage vmImageToImage,
+ VMHardwareToHardware vmHardwareToHardware, Map<String, Credentials> credentialStore) {
+
+ this.nodeNamingConvention = namingConvention.createWithoutPrefix();
+ this.locationToLocation = locationToLocation;
+ this.vmImageToImage = vmImageToImage;
+ this.vmHardwareToHardware = vmHardwareToHardware;
+ this.credentialStore = credentialStore;
+ this.api = api;
+ }
+
+ @Override
+ public NodeMetadata apply(final VMDeployment from) {
+ final NodeMetadataBuilder builder = new NodeMetadataBuilder();
+ final Deployment deployment = from.deployment;
+ builder.id(deployment.name());
+ builder.providerId(deployment.name());
+ builder.name(deployment.name());
+ String group = this.nodeNamingConvention.extractGroup(deployment.name());
+ builder.group(group);
+
+ NodeMetadata.Status status = STATUS_TO_NODESTATUS.get(provisioningStateFromString(deployment.properties().provisioningState()));
+ if (status == NodeMetadata.Status.RUNNING && from.vm != null && from.vm.statuses() != null) {
+ List<VirtualMachineInstance.VirtualMachineStatus> statuses = from.vm.statuses();
+ for (int c = 0; c < statuses.size(); c++) {
+ if (statuses.get(c).code().substring(0, 10).equals("PowerState")) {
+ if (statuses.get(c).displayStatus().equals("VM running")) {
+ status = NodeMetadata.Status.RUNNING;
+ } else if (statuses.get(c).displayStatus().equals("VM stopped")) {
+ status = NodeMetadata.Status.SUSPENDED;
+ }
+ break;
+ }
+ }
+ }
+
+ builder.status(status);
+
+ Credentials credentials = credentialStore.get("node#" + from.deployment.name());
+ if (credentials == null) {
+ credentials = new Credentials(AZURE_LOGIN_USERNAME, AZURE_LOGIN_PASSWORD);
+ }
+ builder.credentials(LoginCredentials.fromCredentials(credentials));
+
+ final Set<String> publicIpAddresses = Sets.newLinkedHashSet();
+ if (from.ipAddressList != null) {
+ for (int c = 0; c < from.ipAddressList.size(); c++) {
+ PublicIPAddress ip = from.ipAddressList.get(c);
+ if (ip != null && ip.properties() != null && ip.properties().ipAddress() != null)
+ {
+ publicIpAddresses.add(ip.properties().ipAddress());
+ break;
+ }
+
+ }
+ if (publicIpAddresses.size() > 0)
+ builder.publicAddresses(publicIpAddresses);
+ }
+
+ org.jclouds.azurecompute.arm.domain.Location myLocation = null;
+ if (from.virtualMachine != null) {
+ String locationName = from.virtualMachine.location();
+ List<org.jclouds.azurecompute.arm.domain.Location> locations = api.getLocationApi().list();
+
+ for (org.jclouds.azurecompute.arm.domain.Location location : locations) {
+ if (location.name().equals(locationName)) {
+ myLocation = location;
+ break;
+ }
+ }
+ Location jLocation = this.locationToLocation.apply(myLocation);
+ builder.location(jLocation);
+
+ ImageReference imageReference = from.virtualMachine.properties().storageProfile().imageReference();
+
+ VMImage vmImage = new VMImage();
+ vmImage.publisher = imageReference.publisher();
+ vmImage.offer = imageReference.offer();
+ vmImage.sku = imageReference.sku();
+ vmImage.location = locationName;
+ Image image = vmImageToImage.apply(vmImage);
+ builder.imageId(image.getId());
+
+ VMSize myVMSize = null;
+ String vmSizeName = from.virtualMachine.properties().hardwareProfile().vmSize();
+ List<VMSize> vmSizes = api.getVMSizeApi(locationName).list();
+ for (VMSize vmSize : vmSizes) {
+ if (vmSize.name().equals(vmSizeName)) {
+ myVMSize = vmSize;
+ break;
+ }
+ }
+
+ VMHardware hwProfile = new VMHardware();
+ hwProfile.name = myVMSize.name();
+ hwProfile.numberOfCores = myVMSize.numberOfCores();
+ hwProfile.osDiskSizeInMB = myVMSize.osDiskSizeInMB();
+ hwProfile.resourceDiskSizeInMB = myVMSize.resourceDiskSizeInMB();
+ hwProfile.memoryInMB = myVMSize.memoryInMB();
+ hwProfile.maxDataDiskCount = myVMSize.maxDataDiskCount();
+ hwProfile.location = locationName;
+
+ Hardware hardware = vmHardwareToHardware.apply(hwProfile);
+ builder.hardware(hardware);
+ }
+
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/LocationToLocation.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/LocationToLocation.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/LocationToLocation.java
index a4d4b1e..0ca1458 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/LocationToLocation.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/LocationToLocation.java
@@ -38,6 +38,7 @@ public class LocationToLocation implements Function<Location, org.jclouds.domain
private final JustProvider justProvider;
+ // allow us to lazy discover the provider of a resource
@Inject
LocationToLocation(JustProvider justProvider) {
this.justProvider = justProvider;
@@ -46,7 +47,11 @@ public class LocationToLocation implements Function<Location, org.jclouds.domain
@Override
public org.jclouds.domain.Location apply(final Location location) {
final LocationBuilder builder = new LocationBuilder();
- builder.id(location.id());
+ String id = location.id();
+ int index = id.lastIndexOf('/');
+ if (index > 0 && (index + 1) < id.length())
+ id = id.substring(index + 1);
+ builder.id(id);
builder.description(location.displayName());
builder.parent(getOnlyElement(justProvider.get()));
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
new file mode 100644
index 0000000..51a6e5e
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute.functions;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.inject.Inject;
+import org.jclouds.azurecompute.arm.domain.VMHardware;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.domain.Location;
+import org.jclouds.location.predicates.LocationPredicates;
+
+import java.util.Set;
+
+public class VMHardwareToHardware implements Function<VMHardware, Hardware> {
+
+ private final Supplier<Set<? extends Location>> locations;
+
+ @Inject
+ VMHardwareToHardware(@Memoized final Supplier<Set<? extends Location>> locations) {
+ this.locations = locations;
+ }
+
+ @Override
+ public Hardware apply(VMHardware from) {
+ final HardwareBuilder builder = new HardwareBuilder()
+ .name(from.name)
+ .id(from.name)
+ .processors(ImmutableList.of(new Processor(from.numberOfCores, 2)))
+ .ram(from.memoryInMB)
+ .location(from.globallyAvailable ? null : FluentIterable.from(locations.get())
+ .firstMatch(LocationPredicates.idEquals(from.location))
+ .get());
+
+ // No id or providerId from Azure
+ if (from.resourceDiskSizeInMB != null) {
+ builder.volume(new VolumeBuilder()
+ .size(Float.valueOf(from.resourceDiskSizeInMB))
+ .type(Volume.Type.LOCAL)
+ .build());
+ }
+ if (from.osDiskSizeInMB != null) {
+ builder.volume(new VolumeBuilder()
+ .size(Float.valueOf(from.osDiskSizeInMB))
+ .type(Volume.Type.LOCAL)
+ .build());
+ }
+
+ ImmutableMap.Builder<String, String> metadata = ImmutableMap.builder();
+ metadata.put("maxDataDiskCount", String.valueOf(from.maxDataDiskCount));
+ builder.userMetadata(metadata.build());
+
+ return builder.build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
new file mode 100644
index 0000000..65a3d4b
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import org.jclouds.domain.Location;
+import org.jclouds.location.predicates.LocationPredicates;
+
+import java.util.Set;
+
+public class VMImageToImage implements Function<VMImage, Image> {
+
+ private static final String UNRECOGNIZED = "UNRECOGNIZED";
+
+ private static final String UBUNTU = "Ubuntu";
+
+ private static final String WINDOWS = "Windows";
+
+ private static final String OPENLOGIC = "openLogic";
+
+ private static final String CENTOS = "CentOS";
+
+ private static final String COREOS = "CoreOS";
+
+ private static final String OPENSUSE = "openSUSE";
+
+ private static final String SUSE = "SUSE";
+
+ private static final String SQL_SERVER = "SQL Server";
+
+ private static final String ORACLE_lINUX = "Oracle Linux";
+
+ private final Supplier<Set<? extends org.jclouds.domain.Location>> locations;
+
+ public static String encodeFieldsToUniqueId(VMImage imageReference){
+ return (imageReference.globallyAvailable ? "global" : imageReference.location) + "/" + imageReference.publisher + "/" + imageReference.offer + "/" + imageReference.sku;
+ }
+
+ public static String[] decodeFieldsFromUniqueId(final String id) {
+ return checkNotNull(id, "id").split("/");
+ }
+
+ @Inject
+ VMImageToImage(@Memoized final Supplier<Set<? extends Location>> locations) {
+ this.locations = locations;
+ }
+
+ @Override
+ public Image apply(final VMImage image) {
+
+ final ImageBuilder builder = new ImageBuilder()
+ .name(image.offer)
+ .description(image.sku)
+ .status(Image.Status.AVAILABLE)
+ .version(image.sku)
+ .id(encodeFieldsToUniqueId(image))
+ .providerId(image.publisher)
+ .location(image.globallyAvailable ? null : FluentIterable.from(locations.get())
+ .firstMatch(LocationPredicates.idEquals(image.location))
+ .get());
+
+
+ final OperatingSystem.Builder osBuilder = osFamily().apply(image);
+ return builder.operatingSystem(osBuilder.build()).build();
+ }
+
+ public static Function<VMImage, OperatingSystem.Builder> osFamily() {
+ return new Function<VMImage, OperatingSystem.Builder>() {
+ @Override
+ public OperatingSystem.Builder apply(final VMImage image) {
+ checkNotNull(image.offer, "offer");
+ final String label = image.offer;
+
+ OsFamily family = OsFamily.UNRECOGNIZED;
+ if (label.contains(CENTOS)) {
+ family = OsFamily.CENTOS;
+ } else if (label.contains(OPENLOGIC)) {
+ family = OsFamily.CENTOS;
+ } else if (label.contains(SUSE)) {
+ family = OsFamily.SUSE;
+ } else if (label.contains(UBUNTU)) {
+ family = OsFamily.UBUNTU;
+ } else if (label.contains(WINDOWS)) {
+ family = OsFamily.WINDOWS;
+ } else if (label.contains(ORACLE_lINUX)) {
+ family = OsFamily.OEL;
+ }
+
+ // only 64bit OS images are supported by Azure ARM
+ return OperatingSystem.builder().
+ family(family).
+ is64Bit(true).
+ description(image.sku).
+ version(image.sku);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
new file mode 100644
index 0000000..6900f17
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.Constants;
+import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
+import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
+import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+
+import org.jclouds.logging.Logger;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+@Singleton
+public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEncodedIntoNameThenAddToSet {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final AzureComputeApi api;
+
+ @Inject
+ protected CreateResourceGroupThenCreateNodes(
+ CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy,
+ ListNodesStrategy listNodesStrategy,
+ GroupNamingConvention.Factory namingConvention,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
+ AzureComputeApi api) {
+ super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
+ this.api = checkNotNull(api, "api cannot be null");
+ checkNotNull(userExecutor, "userExecutor cannot be null");
+ }
+
+ @Override
+ public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template,
+ Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
+ Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+
+ ResourceGroupApi resourceGroupApi = api.getResourceGroupApi();
+ ResourceGroup resourceGroup = resourceGroupApi.get(group);
+ final String location = template.getLocation().getId();
+ final String resourceGroupName;
+
+ if (resourceGroup == null){
+
+ final Map<String, String> tags = ImmutableMap.of("description", "jClouds managed VMs");
+ resourceGroupName = resourceGroupApi.create(group, location, tags).name();
+ } else {
+ resourceGroupName = resourceGroup.name();
+ }
+
+ Map<?, ListenableFuture<Void>> responses = super.execute(resourceGroupName, count, template, goodNodes, badNodes,
+ customizationResponses);
+
+ return responses;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
index 48188c4..48d6287 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
@@ -33,4 +33,12 @@ public class AzureComputeProperties {
public static final String STORAGE_API_VERSION = "2015-06-15";
+ public static final String RESOURCE_GROUP_NAME = "jclouds.azurecompute.arm.operation.resourcegroup";
+
+ public static final String IMAGE_PUBLISHERS = "jclouds.azurecompute.arm.publishers";
+
+ public static final String DEFAULT_IMAGE_LOGIN = "jclouds.azurecompute.arm.defaultimagelogin";
+
+ public static final String TIMEOUT_RESOURCE_DELETED = "jclouds.azurecompute.arm.timeout.resourcedeleted";
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceProviderMetaData.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceProviderMetaData.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceProviderMetaData.java
new file mode 100644
index 0000000..84526b9
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceProviderMetaData.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import org.jclouds.json.SerializedNames;
+
+import java.util.List;
+
+@AutoValue
+public abstract class ResourceProviderMetaData {
+
+ public abstract String resourceType();
+
+ public abstract List<String> locations();
+
+ public abstract List<String> apiVersions();
+
+ @SerializedNames({"resourceType", "locations", "apiVersions"})
+ public static ResourceProviderMetaData create(final String resourceType, final List<String> locations, final List<String> apiVersions) {
+ ResourceProviderMetaData.Builder builder = ResourceProviderMetaData.builder()
+ .resourceType(resourceType)
+ .locations(locations == null ? ImmutableList.<String>of() : ImmutableList.copyOf(locations))
+ .apiVersions(apiVersions == null ? ImmutableList.<String>of() : ImmutableList.copyOf(apiVersions));
+
+ return builder.build();
+ }
+
+ public static Builder builder() {
+ return new AutoValue_ResourceProviderMetaData.Builder();
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder resourceType(String resourceType);
+
+ public abstract Builder locations(List<String> locations);
+
+ public abstract Builder apiVersions(List<String> apiVersions);
+
+ abstract List<String> locations();
+
+ abstract List<String> apiVersions();
+
+ abstract ResourceProviderMetaData autoBuild();
+
+ public ResourceProviderMetaData build() {
+ locations(locations() != null ? ImmutableList.copyOf(locations()) : ImmutableList.<String>of());
+ apiVersions(apiVersions() != null ? ImmutableList.copyOf(apiVersions()) : ImmutableList.<String>of());
+ return autoBuild();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
index 2504409..6909a7b 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
@@ -26,4 +26,6 @@ public class VMDeployment {
public List<PublicIPAddress> ipAddressList;
public VirtualMachineInstance vm;
+
+ public VirtualMachine virtualMachine;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
new file mode 100644
index 0000000..d338327
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+
+/**
+ * A VM Size that is available in a region for a given subscription.
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt269440.aspx" >api</a>
+ */
+@AutoValue
+public class VMHardware {
+
+ /**
+ * The name of the VM size.
+ */
+ public String name;
+
+ /**
+ * The number of cores that are available in the VM size.
+ */
+ public Integer numberOfCores;
+
+ /**
+ * Specifies the size in MB of the OS Disk.
+ */
+ public Integer osDiskSizeInMB;
+
+ /**
+ * The size of the resource disk.
+ */
+ public Integer resourceDiskSizeInMB;
+
+ /**
+ * Specifies the available RAM in MB.
+ */
+ public Integer memoryInMB;
+
+ /**
+ * Specifies the maximum number of data disks that can be attached to the VM size.
+ */
+ public Integer maxDataDiskCount;
+
+ /**
+ * Specifies the location of the HW resource
+ */
+ public String location;
+
+ /**
+ * Specifies if this HW is globally available
+ */
+ public boolean globallyAvailable;
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
new file mode 100644
index 0000000..ccfb05a
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public class VMImage {
+
+ /**
+ * The publisher of the image reference.
+ */
+ public String publisher;
+
+ /**
+ * The offer of the image reference.
+ */
+ public String offer;
+
+ /**
+ * The sku of the image reference.
+ */
+ public String sku;
+
+ /**
+ * The version of the image reference.
+ */
+ public String version;
+
+ /**
+ * The location from where Image was fetched
+ */
+ public String location;
+
+ /**
+ * Specifies if this image is globally available
+ */
+ public boolean globallyAvailable;
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
index 71387e6..3013543 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
@@ -64,6 +64,6 @@ public abstract class VirtualMachine {
public static VirtualMachine create(final String id, final String name, final String type, final String location,
@Nullable final Map<String, String> tags, VirtualMachineProperties properties) {
- return new AutoValue_VirtualMachine(id, name, location, type, tags == null ? null : ImmutableMap.copyOf(tags), properties);
+ return new AutoValue_VirtualMachine(id, name, type, location, tags == null ? null : ImmutableMap.copyOf(tags), properties);
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
new file mode 100644
index 0000000..e3d38b8
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.features;
+
+
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+
+import javax.inject.Named;
+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 java.io.Closeable;
+import java.util.List;
+
+/**
+ * The Azure Resource Provider API provides information about a resource provider and its supported resource types.
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790534.aspx">docs</a>
+ */
+@Path("/providers")
+
+@QueryParams(keys = "api-version", values = "2015-01-01")
+@RequestFilters(OAuthFilter.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface ResourceProviderApi extends Closeable {
+
+ @Named("providers:get")
+ @GET
+ @Path("/{namespace}")
+ @SelectJson("resourceTypes")
+ @Fallback(NullOnNotFoundOr404.class)
+ @Nullable
+ List<ResourceProviderMetaData> get(@PathParam("namespace") String namespace);
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/03f72d5e/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
new file mode 100644
index 0000000..2b6a18e
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.azurecompute.arm.functions;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.common.base.Predicate;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+
+import java.net.URI;
+
+@Singleton
+public class CleanupResources implements Function<String, Boolean> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final AzureComputeApi api;
+ private Predicate<URI> nodeTerminated;
+ private Predicate<URI> resourceDeleted;
+
+ @Inject
+ public CleanupResources(AzureComputeApi azureComputeApi,
+ @Named(TIMEOUT_NODE_TERMINATED) Predicate<URI> nodeTerminated,
+ @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted) {
+
+ this.api = azureComputeApi;
+ this.nodeTerminated = nodeTerminated;
+ this.resourceDeleted = resourceDeleted;
+ }
+
+ @Override
+ public Boolean apply(String id) {
+
+ logger.debug("Destroying %s ...", id);
+ String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "storage";
+ int index = id.lastIndexOf("-");
+ String group = id.substring(0, index);
+
+ // Delete VM
+ URI uri = api.getVirtualMachineApi(group).delete(id);
+ if (uri != null){
+ boolean jobDone = nodeTerminated.apply(uri);
+
+ if (jobDone) {
+ // Delete storage account
+ api.getStorageAccountApi(group).delete(storageAccountName);
+
+ // Delete NIC
+ uri = api.getNetworkInterfaceCardApi(group).delete(id + "nic");
+ if (uri != null){
+ jobDone = resourceDeleted.apply(uri);
+ if (jobDone) {
+
+ // Delete deployment
+ uri = api.getDeploymentApi(group).delete(id);
+ jobDone = resourceDeleted.apply(uri);
+ if (jobDone) {
+ // Delete public ip
+ boolean ipDeleteStatus = api.getPublicIPAddressApi(group).delete(id + "publicip");
+
+ // Delete Virtual network
+ boolean vnetDeleteStatus = api.getVirtualNetworkApi(group).delete(group + "virtualnetwork");
+ return ipDeleteStatus && vnetDeleteStatus;
+
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+}