You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by an...@apache.org on 2015/02/27 12:31:18 UTC
[3/4] jclouds-labs git commit: AzureCompute: initial work to support
ComputeServiceAdapter
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
index 22d0f1a..c08aeed 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java
@@ -16,13 +16,10 @@
*/
package org.jclouds.azurecompute.compute.functions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.inject.Inject;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import org.jclouds.azurecompute.domain.OSImage;
import org.jclouds.compute.domain.Image;
-
-import com.google.common.base.Function;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
@@ -31,11 +28,14 @@ import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.all.JustProvider;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
public class OSImageToImage implements Function<OSImage, Image> {
- private static final String UNRECOGNIZED = "UNRECOGNIZED";
+ private static final String UNRECOGNIZED = "UNRECOGNIZED";
private static final String UBUNTU = "Ubuntu";
private static final String WINDOWS = "Windows";
private static final String OPENLOGIC = "openLogic";
@@ -44,7 +44,7 @@ public class OSImageToImage implements Function<OSImage, Image> {
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 = "Orcale Linux";
+ private static final String ORACLE_lINUX = "Oracle Linux";
private final JustProvider provider;
@@ -70,13 +70,10 @@ public class OSImageToImage implements Function<OSImage, Image> {
}
private Location createLocation(String input) {
- if (input != null) {
- return new LocationBuilder().id(input).scope(LocationScope.REGION).description(input).parent(
+ if (input == null) return null;
+ return new LocationBuilder().id(input).scope(LocationScope.REGION).description(input).parent(
Iterables.getOnlyElement(provider.get())).metadata(ImmutableMap.<String, Object>of("name", input))
.build();
- } else {
- return null;
- }
}
public static Function<OSImage, OperatingSystem.Builder> osFamily() {
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/RoleSizeToHardware.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/RoleSizeToHardware.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/RoleSizeToHardware.java
index 97a9b2c..c778805 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/RoleSizeToHardware.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/RoleSizeToHardware.java
@@ -18,14 +18,44 @@ package org.jclouds.azurecompute.compute.functions;
import org.jclouds.azurecompute.domain.RoleSize;
import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
public class RoleSizeToHardware implements Function<RoleSize, Hardware> {
@Override
- public Hardware apply(RoleSize input) {
- return null;
- }
+ public Hardware apply(RoleSize from) {
+ HardwareBuilder builder = new HardwareBuilder().ids(from.name().name())
+ .name(from.name().name())
+ .hypervisor("Hyper-V")
+ .processors(ImmutableList.of(new Processor(from.cores(), 2)))
+ .ram(from.memoryInMb());
+
+ // TODO volumes
+ /*
+ if (from.s() != null) {
+ builder.volumes(
+ FluentIterable.from(from.getVirtualGuestBlockDevices()).filter(new Predicate<VirtualGuestBlockDevice>() {
+ @Override
+ public boolean apply(VirtualGuestBlockDevice input) {
+ return input.getMountType().equals("Disk");
+ }
+ })
+ .transform(new Function<VirtualGuestBlockDevice, Volume>() {
+ @Override
+ public Volume apply(VirtualGuestBlockDevice item) {
+ float volumeSize = item.getVirtualDiskImage().getCapacity();
+ return new VolumeImpl(
+ item.getId() + "",
+ from.isLocalDiskFlag() ? Volume.Type.LOCAL : Volume.Type.SAN,
+ volumeSize, null, item.getBootableFlag() == 1, false);
+ }
+ }).toSet());
+ }
+ */
+ return builder.build(); }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/internal/OperatingSystems.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/internal/OperatingSystems.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/internal/OperatingSystems.java
new file mode 100644
index 0000000..178d632
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/internal/OperatingSystems.java
@@ -0,0 +1,83 @@
+/*
+ * 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.compute.functions.internal;
+
+import org.jclouds.azurecompute.domain.OSImage;
+import org.jclouds.compute.domain.OsFamily;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+
+public class OperatingSystems {
+
+ protected static final String CENTOS = "CentOS";
+ protected static final String SUSE = "SUSE";
+ protected static final String OPENSUSE = "openSUSE";
+ protected static final String UBUNTU = "Ubuntu";
+ protected static final String WINDOWS = "Windows";
+ private static final String MICROSOFT = "Microsoft";
+ public static final String WINDOWS_SERVER = "Windows Server";
+ public static final String MICROSOFT_SQL_SERVER = "Microsoft SQL Server";
+
+ public static Function<String, OsFamily> osFamily() {
+ return new Function<String, OsFamily>() {
+ @Override
+ public OsFamily apply(final String label) {
+ if (label != null) {
+ if (label.contains(CENTOS)) return OsFamily.CENTOS;
+ else if (label.contains(SUSE)) return OsFamily.SUSE;
+ else if (label.contains(UBUNTU)) return OsFamily.UBUNTU;
+ else if (label.contains(WINDOWS)) return OsFamily.WINDOWS;
+ }
+ return OsFamily.UNRECOGNIZED;
+ }
+ };
+ }
+
+ public static Function<OSImage, String> version() {
+ return new Function<OSImage, String>() {
+ @Override
+ public String apply(OSImage osImage) {
+ if (osImage.category().matches("Canonical|OpenLogic")) {
+ return Iterables.get(Splitter.on(" ").split(osImage.label()), 2);
+ } else if (osImage.category().matches(SUSE)) {
+ if (osImage.label().startsWith(OPENSUSE)) {
+ return osImage.label().substring(OPENSUSE.length() + 1);
+ }
+ if (osImage.label().startsWith(SUSE)) {
+ return Iterables.get(Splitter.on("-").split(osImage.name()), 4);
+ }
+ } else if (osImage.category().matches(MICROSOFT)) {
+ if (osImage.label().startsWith(WINDOWS_SERVER)) {
+ return osImage.label().substring(WINDOWS_SERVER.length() + 1);
+ }
+ if (osImage.label().startsWith(MICROSOFT_SQL_SERVER)) {
+ return osImage.label().substring(MICROSOFT_SQL_SERVER.length() + 1);
+ }
+ } else if (osImage.category().matches("RightScale with Linux|Public ")) {
+ Iterable<String> splittedLabel = Splitter.on("-").split(osImage.label());
+ if (Iterables.size(splittedLabel) > 2) {
+ return Iterables.get(splittedLabel, 2);
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
new file mode 100644
index 0000000..1520509
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes.java
@@ -0,0 +1,270 @@
+/*
+ * 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.compute.strategy;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.tryFind;
+import static java.lang.String.format;
+import static org.jclouds.azurecompute.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.azurecompute.AzureComputeApi;
+import org.jclouds.azurecompute.config.AzureComputeProperties;
+import org.jclouds.azurecompute.domain.NetworkConfiguration;
+import org.jclouds.azurecompute.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.domain.StorageService;
+import org.jclouds.azurecompute.domain.StorageServiceParams;
+import org.jclouds.azurecompute.options.AzureComputeTemplateOptions;
+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.logging.Logger;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+
+@Singleton
+public class GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes extends CreateNodesWithGroupEncodedIntoNameThenAddToSet {
+
+ private static final String DEFAULT_STORAGE_ACCOUNT_PREFIX = "jclouds";
+ private static final String DEFAULT_STORAGE_SERVICE_TYPE = "Standard_GRS";
+ private static final String DEFAULT_VIRTUAL_NETWORK_NAME = "jclouds-virtual-network";
+ private static final String DEFAULT_ADDRESS_SPACE_ADDRESS_PREFIX = "10.0.0.0/20";
+ private static final String DEFAULT_SUBNET_NAME = "jclouds-1";
+ private static final String DEFAULT_SUBNET_ADDRESS_PREFIX = "10.0.0.0/23";
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final AzureComputeApi api;
+ private final Predicate<String> operationSucceededPredicate;
+ private final AzureComputeConstants azureComputeConstants;
+
+ @Inject
+ protected GetOrCreateStorageServiceAndVirtualNetworkThenCreateNodes(
+ CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy,
+ ListNodesStrategy listNodesStrategy,
+ GroupNamingConvention.Factory namingConvention,
+ @Named("jclouds.user-threads") ListeningExecutorService userExecutor,
+ CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
+ AzureComputeApi api,
+ Predicate<String> operationSucceededPredicate,
+ AzureComputeConstants azureComputeConstants) {
+ super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor, customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
+ this.api = api;
+ this.operationSucceededPredicate = operationSucceededPredicate;
+ this.azureComputeConstants = azureComputeConstants;
+ }
+
+ @Override
+ protected ListenableFuture<AtomicReference<NodeMetadata>> createNodeInGroupWithNameAndTemplate(String group, String name, Template template) {
+ return super.createNodeInGroupWithNameAndTemplate(group, name, template);
+ }
+
+ @Override
+ public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+
+ AzureComputeTemplateOptions templateOptions = template.getOptions().as(AzureComputeTemplateOptions.class);
+ String storageAccountName = templateOptions.getStorageAccountName().or(generateStorageServiceName(DEFAULT_STORAGE_ACCOUNT_PREFIX));
+ String location = template.getLocation().getId();
+ String storageAccountType = templateOptions.getStorageAccountType().or(DEFAULT_STORAGE_SERVICE_TYPE);
+ String virtualNetworkName = templateOptions.getVirtualNetworkName().or(DEFAULT_VIRTUAL_NETWORK_NAME);
+ String subnetName = templateOptions.getSubnetName().or(DEFAULT_SUBNET_NAME);
+ String addressSpaceAddressPrefix = templateOptions.getAddressSpaceAddressPrefix().or(DEFAULT_ADDRESS_SPACE_ADDRESS_PREFIX);
+ String subnetAddressPrefix = templateOptions.getSubnetAddressPrefix().or(DEFAULT_SUBNET_ADDRESS_PREFIX);
+ Set<String> networkSecurityGroupNames = templateOptions.getGroups().isEmpty() ? Sets.<String>newHashSet() : templateOptions.getGroups();
+
+ // get or create storage service
+ StorageService storageService = tryFindExistingStorageServiceAccountOrCreate(api, location, storageAccountName,
+ storageAccountType);
+ templateOptions.storageAccountName(storageService.serviceName());
+
+ // check existence or create virtual network
+ checkExistingVirtualNetworkNamedOrCreate(virtualNetworkName, location, subnetName, addressSpaceAddressPrefix, subnetAddressPrefix);
+ templateOptions.virtualNetworkName(virtualNetworkName);
+ templateOptions.subnetName(subnetName);
+
+ // add network security group to the subnet
+ if (!networkSecurityGroupNames.isEmpty()) {
+ String networkSecurityGroupName = Iterables.get(networkSecurityGroupNames, 0);
+ logger.warn("Only network security group '%s' will be applied to subnet '%s'.", networkSecurityGroupName, subnetName);
+ final NetworkSecurityGroup networkSecurityGroupAppliedToSubnet = api.getNetworkSecurityGroupApi().getNetworkSecurityGroupAppliedToSubnet(virtualNetworkName, subnetName);
+ if (networkSecurityGroupAppliedToSubnet != null) {
+ if (!networkSecurityGroupAppliedToSubnet.name().equals(networkSecurityGroupName)) {
+ logger.debug("Removing a networkSecurityGroup %s is already applied to subnet '%s' ...", networkSecurityGroupName, subnetName);
+ // remove existing nsg from subnet
+ String removeFromSubnetRequestId = api.getNetworkSecurityGroupApi().removeFromSubnet(virtualNetworkName, subnetName, networkSecurityGroupAppliedToSubnet.name());
+ if (!operationSucceededPredicate.apply(removeFromSubnetRequestId)) {
+ final String warnMessage = format("Remove existing networkSecurityGroup(%s) to subnet(%s) has not been completed " +
+ "within %sms.", networkSecurityGroupName, subnetName, azureComputeConstants.operationTimeout());
+ logger.warn(warnMessage);
+ String illegalStateExceptionMessage = format("%s. Please, try by increasing `%s` and try again",
+ AzureComputeProperties.OPERATION_TIMEOUT, warnMessage);
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ }
+ }
+ }
+ // add nsg to subnet
+ logger.debug("Adding a networkSecurityGroup %s is already applied to subnet '%s' of virtual network %s ...", networkSecurityGroupName, subnetName, virtualNetworkName);
+ String addToSubnetId = api.getNetworkSecurityGroupApi().addToSubnet(virtualNetworkName, subnetName,
+ NetworkSecurityGroup.create(networkSecurityGroupName, null, null, null));
+ if (!operationSucceededPredicate.apply(addToSubnetId)) {
+ final String warnMessage = format("Add networkSecurityGroup(%s) to subnet(%s) has not been completed " +
+ "within %sms.", networkSecurityGroupName, subnetName, azureComputeConstants.operationTimeout());
+ logger.warn(warnMessage);
+ String illegalStateExceptionMessage = format("%s. Please, try by increasing `%s` and try again",
+ AzureComputeProperties.OPERATION_TIMEOUT, warnMessage);
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ }
+ }
+ return super.execute(group, count, template, goodNodes, badNodes, customizationResponses);
+ }
+
+ /**
+ * Tries to find a storage service account whose name matches the regex DEFAULT_STORAGE_ACCOUNT_PREFIX+"[a-z]{10}"
+ * in the location, otherwise it creates a new storage service account with name and type in the location
+ */
+ private StorageService tryFindExistingStorageServiceAccountOrCreate(AzureComputeApi api, String location, final String name, final String type) {
+ final List<StorageService> storageServices = api.getStorageAccountApi().list();
+ Predicate<StorageService> storageServicePredicate;
+ logger.debug("Looking for a suitable existing storage account ...");
+ storageServicePredicate = and(notNull(), new SameLocationAndCreatedStorageServicePredicate(location), new Predicate<StorageService>() {
+ @Override
+ public boolean apply(StorageService input) {
+ return input.serviceName().matches(format("^%s[a-z]{10}$", DEFAULT_STORAGE_ACCOUNT_PREFIX));
+ }
+ });
+ final Optional<StorageService> storageServiceOptional = tryFind(storageServices, storageServicePredicate);
+ if (storageServiceOptional.isPresent()) {
+ final StorageService storageService = storageServiceOptional.get();
+ logger.debug("Found a suitable existing storage service account '%s'", storageService);
+ return storageService;
+ } else {
+ // create
+ if (!checkAvailability(name)) {
+ logger.warn("The storage service account name %s is not available", name);
+ throw new IllegalStateException(format("Can't create a valid storage account with name %s. " +
+ "Please, try by choosing a different `storageAccountName` in templateOptions and try again", name));
+ }
+ logger.debug("Creating a storage service account '%s' in location '%s' ...", name, location);
+ String createStorateServiceRequestId = api.getStorageAccountApi().create(StorageServiceParams.builder()
+ .name(name)
+ .label(name)
+ .location(location)
+ .accountType(StorageServiceParams.Type.valueOf(type))
+ .build());
+ if (!operationSucceededPredicate.apply(createStorateServiceRequestId)) {
+ final String warnMessage = format("Create storage service account has not been completed within %sms.", azureComputeConstants.operationTimeout());
+ logger.warn(warnMessage);
+ String illegalStateExceptionMessage = format("%s. Please, try by increasing `%s` and try again",
+ AzureComputeProperties.OPERATION_TIMEOUT, warnMessage);
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ }
+ return api.getStorageAccountApi().get(name);
+ }
+ }
+
+ private void checkExistingVirtualNetworkNamedOrCreate(final String virtualNetworkName, String
+ location, String subnetName, String addressSpaceAddressPrefix, String subnetAddressPrefix) {
+ logger.debug("Looking for a virtual network named '%s' ...", virtualNetworkName);
+ Optional<NetworkConfiguration.VirtualNetworkSite> networkSiteOptional = getVirtualNetworkNamed(virtualNetworkName);
+ if (networkSiteOptional.isPresent()) return;
+ final NetworkConfiguration networkConfiguration = NetworkConfiguration.create(
+ NetworkConfiguration.VirtualNetworkConfiguration.create(null,
+ ImmutableList.of(NetworkConfiguration.VirtualNetworkSite.create(
+ UUID.randomUUID().toString(),
+ virtualNetworkName,
+ location,
+ NetworkConfiguration.AddressSpace.create(addressSpaceAddressPrefix),
+ ImmutableList.of(NetworkConfiguration.Subnet.create(subnetName, subnetAddressPrefix, null))))
+ )
+ );
+ logger.debug("Creating a virtual network with configuration '%s' ...", networkConfiguration);
+ String setNetworkConfigurationRequestId = api.getVirtualNetworkApi().set(networkConfiguration);
+ if (!operationSucceededPredicate.apply(setNetworkConfigurationRequestId)) {
+ final String warnMessage = format("Network configuration (%s) has not been completed within %sms.",
+ networkConfiguration, azureComputeConstants.operationTimeout());
+ logger.warn(warnMessage);
+ String illegalStateExceptionMessage = format("%s. Please, try by increasing `%s` and try again",
+ AzureComputeProperties.OPERATION_TIMEOUT, warnMessage);
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ } }
+
+ private Optional<NetworkConfiguration.VirtualNetworkSite> getVirtualNetworkNamed(final String virtualNetworkName) {
+ return FluentIterable.from(api.getVirtualNetworkApi().list())
+ .filter(new Predicate<NetworkConfiguration.VirtualNetworkSite>() {
+ @Override
+ public boolean apply(NetworkConfiguration.VirtualNetworkSite input) {
+ return input.name().equals(virtualNetworkName);
+ }
+ })
+ .first();
+ }
+
+ private boolean checkAvailability(String name) {
+ return api.getStorageAccountApi().checkAvailable(name).result();
+ }
+
+ private static String generateStorageServiceName(String prefix) {
+ String characters = "abcdefghijklmnopqrstuvwxyz";
+ StringBuilder builder = new StringBuilder();
+ builder.append(prefix);
+ int charactersLength = characters.length();
+ for (int i = 0; i < 10; i++) {
+ double index = Math.random() * charactersLength;
+ builder.append(characters.charAt((int) index));
+ }
+ return builder.toString();
+ }
+
+ private static class SameLocationAndCreatedStorageServicePredicate implements Predicate<StorageService> {
+ private final String location;
+
+ public SameLocationAndCreatedStorageServicePredicate(String location) {
+ this.location = location;
+ }
+
+ @Override
+ public boolean apply(StorageService input) {
+ return input.storageServiceProperties().location().equals(location) && input.storageServiceProperties().status().equals("Created");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/UseNodeCredentialsButOverrideFromTemplate.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/UseNodeCredentialsButOverrideFromTemplate.java b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/UseNodeCredentialsButOverrideFromTemplate.java
new file mode 100644
index 0000000..9250369
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/compute/strategy/UseNodeCredentialsButOverrideFromTemplate.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.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
+import org.jclouds.domain.LoginCredentials;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Azure needs the credentials to insert the node so the node credentials already take the Image credentials into
+ * account, as such only overriding the TemplateOptions credentials is required.
+ */
+@Singleton
+public class UseNodeCredentialsButOverrideFromTemplate extends PrioritizeCredentialsFromTemplate {
+
+
+ @Inject
+ public UseNodeCredentialsButOverrideFromTemplate(
+ Function<Template, LoginCredentials> credentialsFromImageOrTemplateOptions) {
+ super(credentialsFromImageOrTemplateOptions);
+ }
+
+ public LoginCredentials apply(Template template, LoginCredentials fromNode) {
+ RunScriptOptions options = checkNotNull(template.getOptions(), "template options are required");
+ LoginCredentials.Builder builder = LoginCredentials.builder(fromNode);
+ if (options.getLoginUser() != null)
+ builder.user(template.getOptions().getLoginUser());
+ if (options.getLoginPassword() != null)
+ builder.password(options.getLoginPassword());
+ if (options.getLoginPrivateKey() != null)
+ builder.privateKey(options.getLoginPrivateKey());
+ if (options.shouldAuthenticateSudo() != null && options.shouldAuthenticateSudo())
+ builder.authenticateSudo(true);
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
index 2d07471..96bdd50 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeHttpApiModule.java
@@ -21,18 +21,42 @@ import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.jclouds.azurecompute.AzureComputeApi;
+import org.jclouds.azurecompute.handlers.AzureComputeErrorHandler;
import org.jclouds.azurecompute.suppliers.KeyStoreSupplier;
import org.jclouds.azurecompute.suppliers.SSLContextWithKeysSupplier;
+import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.annotation.ClientError;
+import org.jclouds.http.annotation.Redirection;
+import org.jclouds.http.annotation.ServerError;
+import org.jclouds.location.config.LocationModule;
+import org.jclouds.location.suppliers.ImplicitLocationSupplier;
+import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import com.google.common.base.Supplier;
+import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
@ConfiguresHttpApi
public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
+
+ @Override
+ protected void bindErrorHandlers() {
+ bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(AzureComputeErrorHandler.class);
+ bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(AzureComputeErrorHandler.class);
+ bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(AzureComputeErrorHandler.class);
+ }
+
+ @Override
+ protected void installLocations() {
+ install(new LocationModule());
+ bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
+ }
+
@Override
protected void configure() {
+ install(new AzureComputeParserModule());
super.configure();
bind(new TypeLiteral<Supplier<SSLContext>>() {
}).to(new TypeLiteral<SSLContextWithKeysSupplier>() {
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeParserModule.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeParserModule.java b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeParserModule.java
new file mode 100644
index 0000000..cc001d1
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeParserModule.java
@@ -0,0 +1,27 @@
+/*
+ * 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.config;
+
+import org.jclouds.json.config.GsonModule;
+
+import com.google.inject.AbstractModule;
+
+public class AzureComputeParserModule extends AbstractModule {
+ @Override protected void configure() {
+ bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeProperties.java b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeProperties.java
index 0981c7c..44ec8aa 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeProperties.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/config/AzureComputeProperties.java
@@ -21,16 +21,13 @@ package org.jclouds.azurecompute.config;
* connections.
*/
public class AzureComputeProperties {
- /**
- * Every call to the Service Management API must include the subscription ID
- * for your subscription. The subscription ID is appended to the base URI,
- * as follows:
- *
- * <pre>
- * https://management.core.windows.net/${subscriptionId}
- * </pre>
- *
- * @see <a href="http://msdn.microsoft.com/en-us/library/ee460786">docs</a>
- */
- public static final String SUBSCRIPTION_ID = "jclouds.azurecompute.subscription-id";
+
+ public static final String OPERATION_TIMEOUT = "jclouds.azurecompute.operation.timeout";
+
+ public static final String OPERATION_POLL_INITIAL_PERIOD = "jclouds.azurecompute..operation.poll.initial.period";
+
+ public static final String OPERATION_POLL_MAX_PERIOD = "jclouds.azurecompute.operation.poll.max.period";
+
+ public static final String TCP_RULE_FORMAT = "jclouds.azurecompute.tcp.rule.format";
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/domain/NetworkConfiguration.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/NetworkConfiguration.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/NetworkConfiguration.java
index c4f1e55..22df816 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/NetworkConfiguration.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/NetworkConfiguration.java
@@ -16,6 +16,7 @@
*/
package org.jclouds.azurecompute.domain;
+import static com.google.common.collect.ImmutableList.copyOf;
import java.util.List;
import org.jclouds.javax.annotation.Nullable;
@@ -74,12 +75,25 @@ public abstract class NetworkConfiguration {
}
+ @AutoValue
+ public abstract static class VirtualNetworkConfiguration {
+
+ VirtualNetworkConfiguration() {
+ } // For AutoValue only!
+
+ @Nullable public abstract String dns();
+ @Nullable public abstract List<VirtualNetworkSite> virtualNetworkSites();
+
+ public static VirtualNetworkConfiguration create(String dns, List<VirtualNetworkSite> virtualNetworkSites) {
+ return new AutoValue_NetworkConfiguration_VirtualNetworkConfiguration(dns, copyOf(virtualNetworkSites));
+ }
+ }
+
public NetworkConfiguration() {} // For AutoValue only!
- @Nullable public abstract String dns();
- @Nullable public abstract List<VirtualNetworkSite> virtualNetworkSites();
+ public abstract VirtualNetworkConfiguration virtualNetworkConfiguration();
- public static NetworkConfiguration create(String dns, List<VirtualNetworkSite> virtualNetworkSites) {
- return new AutoValue_NetworkConfiguration(dns, virtualNetworkSites);
+ public static NetworkConfiguration create(VirtualNetworkConfiguration virtualNetworkConfiguration) {
+ return new AutoValue_NetworkConfiguration(virtualNetworkConfiguration);
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Role.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Role.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Role.java
index c0207af..bb387ef 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Role.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Role.java
@@ -120,13 +120,16 @@ public abstract class Role {
@Nullable public abstract List<PublicIP> publicIPs();
+ @Nullable public abstract String networkSecurityGroup();
+
ConfigurationSet() { // For AutoValue only!
}
public static ConfigurationSet create(String configurationSetType, List<InputEndpoint> inputEndpoints,
- List<SubnetName> subnetNames, String staticVirtualNetworkIPAddress, List<PublicIP> publicIPs) {
+ List<SubnetName> subnetNames, String staticVirtualNetworkIPAddress,
+ List<PublicIP> publicIPs, String networkSecurityGroup) {
return new AutoValue_Role_ConfigurationSet(configurationSetType, inputEndpoints, subnetNames,
- staticVirtualNetworkIPAddress, publicIPs);
+ staticVirtualNetworkIPAddress, publicIPs, networkSecurityGroup);
}
}
@@ -158,7 +161,7 @@ public abstract class Role {
public abstract String version();
- public abstract List<ResourceExtensionParameterValue> resourceExtensionParameterValues();
+ @Nullable public abstract List<ResourceExtensionParameterValue> resourceExtensionParameterValues();
public abstract String state();
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
index 69ceba6..2e771b4 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
@@ -75,4 +75,5 @@ public interface DeploymentApi {
@Fallback(NullOnNotFoundOr404.class)
@ResponseParser(ParseRequestIdHeader.class)
String delete(@PathParam("name") String name);
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/NetworkSecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/NetworkSecurityGroupApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/NetworkSecurityGroupApi.java
new file mode 100644
index 0000000..673413c
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/NetworkSecurityGroupApi.java
@@ -0,0 +1,167 @@
+/*
+ * 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.features;
+
+import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.binders.NetworkSecurityGroupToXML;
+import org.jclouds.azurecompute.binders.RuleToXML;
+import org.jclouds.azurecompute.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.domain.Rule;
+import org.jclouds.azurecompute.functions.ParseRequestIdHeader;
+import org.jclouds.azurecompute.xml.ListNetworkSecurityGroupsHandler;
+import org.jclouds.azurecompute.xml.NetworkSecurityGroupHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+@Path("/services/networking")
+@Headers(keys = "x-ms-version", values = "{jclouds.api-version}")
+@Consumes(MediaType.APPLICATION_XML)
+public interface NetworkSecurityGroupApi {
+
+ /**
+ * Lists all of the Network Security Groups for the subscription.
+ *
+ */
+ @Named("ListNetworkSecurityGroups")
+ @Path("/networksecuritygroups")
+ @GET
+ @XMLResponseParser(ListNetworkSecurityGroupsHandler.class)
+ @Fallback(EmptyListOnNotFoundOr404.class)
+ List<NetworkSecurityGroup> list();
+
+ @Named("CreateNetworkSecurityGroup")
+ @Path("/networksecuritygroups")
+ @POST
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String create(@BinderParam(NetworkSecurityGroupToXML.class) NetworkSecurityGroup networkSecurityGroup);
+
+ /**
+ * Deletes the pecified Network Security Group from your subscription.
+ * If the Network Security group is still associated with some VM/Role/Subnet, the deletion will fail.
+ * In order to successfully delete the Network Security, it needs to be not used.
+ *
+ * @param networkSecurityGroupName
+ * @return request id
+ */
+ @Named("CreateNetworkSecurityGroup")
+ @Path("/networksecuritygroups/{networkSecurityGroupName}")
+ @DELETE
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String delete(@PathParam("networkSecurityGroupName") String networkSecurityGroupName);
+
+
+ /**
+ * Gets the Network Security Group applied to a specific subnet.
+ *
+ * @param virtualNetworkName
+ * @param subnetName
+ * @return
+ */
+ @Named("GetsNetworkSecurityGroupAppliedToSubnet")
+ @Path("/virtualnetwork/{virtualNetworkName}/subnets/{subnetName}/networksecuritygroups")
+ @GET
+ @XMLResponseParser(NetworkSecurityGroupHandler.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ NetworkSecurityGroup getNetworkSecurityGroupAppliedToSubnet(@PathParam("virtualNetworkName") String virtualNetworkName,
+ @PathParam("subnetName") String subnetName);
+
+ /**
+ * Gets the details for the specified Network Security Group in the subscription
+ *
+ * @param networkSecurityGroupName
+ * @return
+ */
+ @Named("GetDetailsNetworkSecurityGroup")
+ @Path("/networksecuritygroups/{networkSecurityGroupName}")
+ @GET
+ @QueryParams(keys = "detaillevel", values = "Full")
+ @XMLResponseParser(NetworkSecurityGroupHandler.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ NetworkSecurityGroup getFullDetails(@PathParam("networkSecurityGroupName") String networkSecurityGroupName);
+
+ /**
+ * Adds a Network Security Group to a subnet.
+ *
+ * @param virtualNetworkName
+ * @return
+ */
+ @Named("AddNetworkSecurityGroupToSubnet")
+ @Path("/virtualnetwork/{virtualNetworkName}/subnets/{subnetName}/networksecuritygroups")
+ @POST
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String addToSubnet(@PathParam("virtualNetworkName") String virtualNetworkName,
+ @PathParam("subnetName") String subnetName,
+ @BinderParam(NetworkSecurityGroupToXML.class) NetworkSecurityGroup networkSecurityGroup);
+
+ /**
+ * Removes a Network Security Group from a subnet
+ */
+ @Named("RemoveNetworkSecurityGroupToSubnet")
+ @Path("/virtualnetwork/{virtualNetworkName}/subnets/{subnetName}/networksecuritygroups/{networkSecurityGroupName}")
+ @DELETE
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String removeFromSubnet(@PathParam("virtualNetworkName") String virtualNetworkName,
+ @PathParam("subnetName") String subnetName,
+ @PathParam("networkSecurityGroupName") String networkSecurityGroupName);
+
+ /**
+ * Sets a new Network Security Rule to existing Network Security Group
+ *
+ *
+ */
+ @Named("SetNetworkSecurityRuleToNetworkSecurityGroup")
+ @Path("/networksecuritygroups/{networkSecurityGroupName}/rules/{ruleName}")
+ @PUT
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String setRule(@PathParam("networkSecurityGroupName") String networkSecurityGroupName,
+ @PathParam("ruleName") String ruleName, @BinderParam(RuleToXML.class) Rule rule);
+
+ /**
+ * Deletes a rule from the specified Network Security Group.
+ *
+ */
+ @Named("SetNetworkSecurityRuleToNetworkSecurityGroup")
+ @Path("/networksecuritygroups/{networkSecurityGroupName}/rules/{ruleName}")
+ @DELETE
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String deleteRule(@PathParam("networkSecurityGroupName") String networkSecurityGroupName,
+ @PathParam("ruleName") String ruleName);
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/StorageAccountApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/StorageAccountApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/StorageAccountApi.java
new file mode 100644
index 0000000..0a5837c
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/StorageAccountApi.java
@@ -0,0 +1,97 @@
+/*
+ * 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.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.binders.StorageServiceParamsToXML;
+import org.jclouds.azurecompute.domain.Availability;
+import org.jclouds.azurecompute.domain.StorageService;
+import org.jclouds.azurecompute.domain.StorageServiceParams;
+import org.jclouds.azurecompute.functions.ParseRequestIdHeader;
+import org.jclouds.azurecompute.xml.AvailabilityHandler;
+import org.jclouds.azurecompute.xml.ListStorageServicesHandler;
+import org.jclouds.azurecompute.xml.StorageServiceHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+@Path("/services/storageservices")
+@Headers(keys = "x-ms-version", values = "{jclouds.api-version}")
+@Consumes(MediaType.APPLICATION_XML)
+public interface StorageAccountApi {
+
+ /**
+ * The Create Storage Account asynchronous operation creates a new storage account in Microsoft Azure.
+ *
+ */
+ @Named("CreateStorageAccount")
+ @POST
+ @Produces(APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String create(@BinderParam(StorageServiceParamsToXML.class) StorageServiceParams storageServiceParams);
+
+ /**
+ * https://management.core.windows.net/<subscription-id>/services/storageservices
+ */
+ @Named("GetStorageAccountDetails")
+ @GET
+ @Path("/{storageAccountName}")
+ @XMLResponseParser(StorageServiceHandler.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ StorageService get(@PathParam("storageAccountName") String storageAccountName);
+
+ /**
+ * The List Storage Accounts operation lists the storage accounts that are available in the specified subscription.
+ */
+ @Named("ListStorageAccounts")
+ @GET
+ @XMLResponseParser(ListStorageServicesHandler.class)
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ List<StorageService> list();
+
+ /**
+ * The Check Storage Account Name Availability operation checks to see if the specified storage account name is available, or if it has already been taken.
+ */
+ @Named("CheckStorageAccountNameAvailability")
+ @GET
+ @Path("/operations/isavailable/{storageAccountName}")
+ @XMLResponseParser(AvailabilityHandler.class)
+ Availability checkAvailable(@PathParam("storageAccountName") String storageAccountName);
+
+ @Named("DeleteStorageAccount")
+ @DELETE
+ @Path("/{serviceName}")
+ @ResponseParser(ParseRequestIdHeader.class)
+ String delete(String serviceName);
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/SubscriptionApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/SubscriptionApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/SubscriptionApi.java
new file mode 100644
index 0000000..08fb45a
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/SubscriptionApi.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.features;
+
+import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.azurecompute.domain.RoleSize;
+import org.jclouds.azurecompute.xml.ListRoleSizesHandler;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * The Service Management API includes operations for retrieving information about a subscription.
+ *
+ * @see <a href="http://msdn.microsoft.com/en-us/library/gg715315.aspx">docs</a>
+ */
+@Headers(keys = "x-ms-version", values = "{jclouds.api-version}")
+@Path("/rolesizes")
+@Consumes(MediaType.APPLICATION_XML)
+public interface SubscriptionApi {
+
+ /**
+ * The List Role Sizes request may be specified as follows.
+ */
+ @Named("ListRoleSizes")
+ @GET
+ @XMLResponseParser(ListRoleSizesHandler.class)
+ @Fallback(EmptyListOnNotFoundOr404.class)
+ List<RoleSize> listRoleSizes();
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java
index 9f54ed0..468b488 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualMachineApi.java
@@ -16,15 +16,23 @@
*/
package org.jclouds.azurecompute.features;
+import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
+
import javax.inject.Named;
import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import org.jclouds.azurecompute.binders.RoleToXML;
+import org.jclouds.azurecompute.domain.Role;
import org.jclouds.azurecompute.functions.ParseRequestIdHeader;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
@@ -36,7 +44,7 @@ import org.jclouds.rest.annotations.ResponseParser;
*
* @see <a href="http://msdn.microsoft.com/en-us/library/jj157206">docs</a>
*/
-@Path("/services/hostedservices/{serviceName}/deployments/{deploymentName}/roleinstances")
+@Path("/services/hostedservices/{serviceName}/deployments/{deploymentName}")
@Headers(keys = "x-ms-version", values = "{jclouds.api-version}")
@Consumes(MediaType.APPLICATION_XML)
// NOTE: MS Docs refer to the commands as Role, but in the description, it is always Virtual Machine.
@@ -46,7 +54,7 @@ public interface VirtualMachineApi {
@POST
// Warning : the url in the documentation is WRONG ! @see
// http://social.msdn.microsoft.com/Forums/pl-PL/WAVirtualMachinesforWindows/thread/7ba2367b-e450-49e0-89e4-46c240e9d213
- @Path("/{name}/Operations")
+ @Path("/roleinstances/{name}/Operations")
@Produces(MediaType.APPLICATION_XML)
@ResponseParser(ParseRequestIdHeader.class)
@Payload(value = "<RestartRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\"><OperationType>RestartRoleOperation</OperationType></RestartRoleOperation>")
@@ -57,7 +65,7 @@ public interface VirtualMachineApi {
*/
@Named("CaptureRole")
@POST
- @Path("/{name}/Operations")
+ @Path("/roleinstances/{name}/Operations")
@Produces(MediaType.APPLICATION_XML)
@ResponseParser(ParseRequestIdHeader.class)
@Payload(value = "<CaptureRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\"><OperationType>CaptureRoleOperation</OperationType><PostCaptureAction>Delete</PostCaptureAction><TargetImageLabel>{imageLabel}</TargetImageLabel><TargetImageName>{imageName}</TargetImageName></CaptureRoleOperation>")
@@ -69,7 +77,7 @@ public interface VirtualMachineApi {
*/
@Named("ShutdownRole")
@POST
- @Path("/{name}/Operations")
+ @Path("/roleinstances/{name}/Operations")
@Produces(MediaType.APPLICATION_XML)
@ResponseParser(ParseRequestIdHeader.class)
@Payload(value = "<ShutdownRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\"><OperationType>ShutdownRoleOperation</OperationType></ShutdownRoleOperation>")
@@ -80,9 +88,31 @@ public interface VirtualMachineApi {
*/
@Named("StartRole")
@POST
- @Path("/{name}/Operations")
+ @Path("/roleinstances/{name}/Operations")
@Produces(MediaType.APPLICATION_XML)
@ResponseParser(ParseRequestIdHeader.class)
@Payload(value = "<StartRoleOperation xmlns=\"http://schemas.microsoft.com/windowsazure\"><OperationType>StartRoleOperation</OperationType></StartRoleOperation>")
String start(@PathParam("name") String name);
+
+ /**
+ * https://msdn.microsoft.com/en-us/library/azure/jj157193.aspx
+ */
+ @Named("GetRole")
+ @GET
+ @Path("/roles/{roleName}")
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ Role getRole(@PathParam("roleName") String roleName);
+
+ /**
+ * https://msdn.microsoft.com/library/azure/jj157187.aspx
+ */
+ @Named("UpdateRole")
+ @PUT
+ @Path("/roles/{roleName}")
+ @Produces(MediaType.APPLICATION_XML)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String updateRole(@PathParam("roleName") String roleName, @BinderParam(RoleToXML.class) Role role);
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualNetworkApi.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualNetworkApi.java b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualNetworkApi.java
new file mode 100644
index 0000000..e091464
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/VirtualNetworkApi.java
@@ -0,0 +1,76 @@
+/*
+ * 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.features;
+
+import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
+
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.azurecompute.binders.NetworkConfigurationToXML;
+import org.jclouds.azurecompute.domain.NetworkConfiguration;
+import org.jclouds.azurecompute.domain.NetworkConfiguration.VirtualNetworkSite;
+import org.jclouds.azurecompute.functions.ParseRequestIdHeader;
+import org.jclouds.azurecompute.xml.ListVirtualNetworkSitesHandler;
+import org.jclouds.azurecompute.xml.NetworkConfigurationHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+@Path("/services/networking")
+@Headers(keys = "x-ms-version", values = "{jclouds.api-version}")
+@Consumes(MediaType.APPLICATION_XML)
+public interface VirtualNetworkApi {
+
+ /**
+ * The Get Network Configuration operation retrieves the network configuration file.
+ *
+ * @return The response body is a netcfg.cfg file.
+
+ */
+ @Named("GetVirtualNetworkConfiguration")
+ @Path("/media")
+ @GET
+ @XMLResponseParser(NetworkConfigurationHandler.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ NetworkConfiguration getNetworkConfiguration();
+
+ @Named("ListVirtualNetworkSites")
+ @Path("/virtualnetwork")
+ @GET
+ @XMLResponseParser(ListVirtualNetworkSitesHandler.class)
+ @Fallback(EmptyListOnNotFoundOr404.class)
+ List<VirtualNetworkSite> list();
+
+ @Named("SetVirtualNetworkConfiguration")
+ @Path("/media")
+ @PUT
+ @Produces(MediaType.TEXT_PLAIN)
+ @ResponseParser(ParseRequestIdHeader.class)
+ String set(@BinderParam(NetworkConfigurationToXML.class) NetworkConfiguration networkConfiguration);
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/options/AzureComputeTemplateOptions.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/options/AzureComputeTemplateOptions.java b/azurecompute/src/main/java/org/jclouds/azurecompute/options/AzureComputeTemplateOptions.java
new file mode 100644
index 0000000..3a986d9
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/options/AzureComputeTemplateOptions.java
@@ -0,0 +1,324 @@
+/*
+ * 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.options;
+
+import java.util.Map;
+
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Optional;
+
+/**
+ * Contains options supported by the
+ * {@link org.jclouds.compute.ComputeService#createNodesInGroup(String, int, org.jclouds.compute.options.TemplateOptions)} and
+ * {@link org.jclouds.compute.ComputeService#createNodesInGroup(String, int, org.jclouds.compute.options.TemplateOptions)}
+ * operations on the <em>gogrid</em> provider.
+ *
+ * <h2>Usage</h2> The recommended way to instantiate a
+ * {@link AzureComputeTemplateOptions} object is to statically import
+ * {@code AzureComputeTemplateOptions.*} and invoke a static creation method
+ * followed by an instance mutator (if needed):
+ * <p>
+ *
+ * <pre>
+ * import static org.jclouds.compute.options.AzureComputeTemplateOptions.Builder.*;
+ * ComputeService client = // get connection
+ * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
+ * Set<? extends NodeMetadata> set = client.createNodesInGroup(tag, 2, templateBuilder.build());
+ * </pre>
+ *
+ */
+public class AzureComputeTemplateOptions extends TemplateOptions implements Cloneable {
+
+ private Optional<String> virtualNetworkName = Optional.absent();
+ private Optional<String> addressSpaceAddressPrefix = Optional.absent();
+ private Optional<String> subnetName = Optional.absent();
+ private Optional<String> subnetAddressPrefix = Optional.absent();
+ private Optional<String> storageAccountName = Optional.absent();
+ private Optional<String> storageAccountType = Optional.absent();
+ private Optional<String> networkSecurityGroupName = Optional.absent();
+
+ @Override
+ public AzureComputeTemplateOptions clone() {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ copyTo(options);
+ return options;
+ }
+
+ @Override
+ public void copyTo(TemplateOptions to) {
+ super.copyTo(to);
+ if (to instanceof AzureComputeTemplateOptions) {
+ AzureComputeTemplateOptions eTo = AzureComputeTemplateOptions.class.cast(to);
+ if (virtualNetworkName.isPresent()) {
+ eTo.virtualNetworkName(virtualNetworkName.get());
+ }
+ if (addressSpaceAddressPrefix.isPresent()) {
+ eTo.addressSpaceAddressPrefix(addressSpaceAddressPrefix.get());
+ }
+ if (subnetName.isPresent()) {
+ eTo.subnetName(subnetName.get());
+ }
+ if (networkSecurityGroupName.isPresent()) {
+ eTo.subnetName(networkSecurityGroupName.get());
+ }
+ if (subnetAddressPrefix.isPresent()) {
+ eTo.subnetAddressPrefix(subnetAddressPrefix.get());
+ }
+ if (storageAccountName.isPresent()) {
+ eTo.storageAccountName(storageAccountName.get());
+ }
+ if (storageAccountType.isPresent()) {
+ eTo.storageAccountType(storageAccountType.get());
+ }
+ }
+ }
+
+ public TemplateOptions virtualNetworkName(String virtualNetworkName) {
+ this.virtualNetworkName = Optional.of(virtualNetworkName);
+ return this;
+ }
+
+ public TemplateOptions addressSpaceAddressPrefix(String addressSpaceAddressPrefix) {
+ this.addressSpaceAddressPrefix = Optional.of(addressSpaceAddressPrefix);
+ return this;
+ }
+
+ public TemplateOptions subnetName(String subnetName) {
+ this.subnetName = Optional.of(subnetName);
+ return this;
+ }
+
+ public TemplateOptions networkSecurityGroupName(String networkSecurityGroupName) {
+ this.networkSecurityGroupName = Optional.of(networkSecurityGroupName);
+ return this;
+ }
+
+ public TemplateOptions subnetAddressPrefix(String subnetAddressPrefix) {
+ this.subnetAddressPrefix = Optional.of(subnetAddressPrefix);
+ return this;
+ }
+
+ public TemplateOptions storageAccountName(String storageAccountName) {
+ this.storageAccountName = Optional.of(storageAccountName);
+ return this;
+ }
+
+ public TemplateOptions storageAccountType(String storageAccountType) {
+ this.storageAccountType = Optional.of(storageAccountType);
+ return this;
+ }
+
+ public Optional<String> getVirtualNetworkName() {
+ return virtualNetworkName;
+ }
+
+ public Optional<String> getAddressSpaceAddressPrefix() {
+ return addressSpaceAddressPrefix;
+ }
+
+ public Optional<String> getSubnetName() { return subnetName; }
+
+ public Optional<String> getSubnetAddressPrefix() { return subnetAddressPrefix; }
+
+ public Optional<String> getStorageAccountName() {
+ return storageAccountName;
+ }
+
+ public Optional<String> getStorageAccountType() {
+ return storageAccountType;
+ }
+
+ public Optional<String> getNetworkSecurityGroupName() {
+ return networkSecurityGroupName;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see #virtualNetworkName
+ */
+ public static AzureComputeTemplateOptions virtualNetworkName(String virtualNetworkName) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.virtualNetworkName(virtualNetworkName));
+ }
+
+ /**
+ * @see #addressSpaceAddressPrefix
+ */
+ public static AzureComputeTemplateOptions addressSpaceAddressPrefix(String addressSpaceAddressPrefix) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.addressSpaceAddressPrefix(addressSpaceAddressPrefix));
+ }
+
+ /**
+ * @see #subnetName
+ */
+ public static AzureComputeTemplateOptions subnetName(String subnetName) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.subnetName(subnetName));
+ }
+
+ /**
+ * @see #networkSecurityGroupName
+ */
+ public static AzureComputeTemplateOptions networkSecurityGroupName(String networkSecurityGroupName) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.subnetName(networkSecurityGroupName));
+ }
+
+ /**
+ * @see #subnetAddressPrefix
+ */
+ public static AzureComputeTemplateOptions subnetAddressPrefix(String subnetAddressPrefix) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.subnetAddressPrefix(subnetAddressPrefix));
+ }
+
+ /**
+ * @see #storageAccountName
+ */
+ public static AzureComputeTemplateOptions storageAccountName(String storageAccountName) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.storageAccountName(storageAccountName));
+ }
+
+ /**
+ * @see #storageAccountType
+ */
+ public static AzureComputeTemplateOptions storageAccountType(String storageAccountType) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.storageAccountType(storageAccountType));
+ }
+
+ // methods that only facilitate returning the correct object type
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#inboundPorts(int...)
+ */
+ public static AzureComputeTemplateOptions inboundPorts(int... ports) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.inboundPorts(ports));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#blockOnPort(int, int)
+ */
+ public static AzureComputeTemplateOptions blockOnPort(int port, int seconds) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.blockOnPort(port, seconds));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#userMetadata(java.util.Map)
+ */
+ public static AzureComputeTemplateOptions userMetadata(Map<String, String> userMetadata) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.userMetadata(userMetadata));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#userMetadata(String, String)
+ */
+ public static AzureComputeTemplateOptions userMetadata(String key, String value) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.userMetadata(key, value));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#nodeNames(Iterable)
+ */
+ public static AzureComputeTemplateOptions nodeNames(Iterable<String> nodeNames) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.nodeNames(nodeNames));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#networks(Iterable)
+ */
+ public static AzureComputeTemplateOptions networks(Iterable<String> networks) {
+ AzureComputeTemplateOptions options = new AzureComputeTemplateOptions();
+ return AzureComputeTemplateOptions.class.cast(options.networks(networks));
+ }
+ }
+
+ // methods that only facilitate returning the correct object type
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#blockOnPort(int, int)
+ */
+ @Override
+ public AzureComputeTemplateOptions blockOnPort(int port, int seconds) {
+ return AzureComputeTemplateOptions.class.cast(super.blockOnPort(port, seconds));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#inboundPorts(int...)
+ */
+ @Override
+ public AzureComputeTemplateOptions inboundPorts(int... ports) {
+ return AzureComputeTemplateOptions.class.cast(super.inboundPorts(ports));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#authorizePublicKey(String)
+ */
+ @Override
+ public AzureComputeTemplateOptions authorizePublicKey(String publicKey) {
+ return AzureComputeTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
+ }
+
+ /**
+ * @see org.jclouds.compute.options.TemplateOptions#installPrivateKey(String)
+ */
+ @Override
+ public AzureComputeTemplateOptions installPrivateKey(String privateKey) {
+ return AzureComputeTemplateOptions.class.cast(super.installPrivateKey(privateKey));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AzureComputeTemplateOptions userMetadata(Map<String, String> userMetadata) {
+ return AzureComputeTemplateOptions.class.cast(super.userMetadata(userMetadata));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AzureComputeTemplateOptions userMetadata(String key, String value) {
+ return AzureComputeTemplateOptions.class.cast(super.userMetadata(key, value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AzureComputeTemplateOptions nodeNames(Iterable<String> nodeNames) {
+ return AzureComputeTemplateOptions.class.cast(super.nodeNames(nodeNames));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AzureComputeTemplateOptions networks(Iterable<String> networks) {
+ return AzureComputeTemplateOptions.class.cast(super.networks(networks));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/util/NetworkSecurityGroups.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/util/NetworkSecurityGroups.java b/azurecompute/src/main/java/org/jclouds/azurecompute/util/NetworkSecurityGroups.java
new file mode 100644
index 0000000..687da7e
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/util/NetworkSecurityGroups.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.util;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.jclouds.azurecompute.config.AzureComputeProperties;
+import org.jclouds.azurecompute.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.domain.Rule;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+
+public class NetworkSecurityGroups {
+
+ public static List<Rule> getCustomRules(NetworkSecurityGroup networkSecurityGroup) {
+ final List<Rule> rules = networkSecurityGroup.rules();
+ return FluentIterable.from(rules)
+ .filter(Predicates.notNull())
+ .filter(new Predicate<Rule>() {
+ @Override
+ public boolean apply(Rule rule) {
+ return rule.isDefault() == null || !rule.isDefault();
+ }
+ })
+ .toSortedList(new Comparator<Rule>() {
+ @Override
+ public int compare(Rule r1, Rule r2) {
+ int p1 = Integer.parseInt(r1.priority());
+ int p2 = Integer.parseInt(r2.priority());
+ return p1 < p2 ? -1 : p1 == p2 ? 0 : 1;
+
+ }
+ });
+ }
+
+ public static int getFirstAvailablePriority(List<Rule> rules) {
+ int priority;
+ if (rules.isEmpty()) {
+ priority = 100;
+ } else {
+ priority = Integer.parseInt(Collections.max(rules, new Comparator<Rule>() {
+ @Override
+ public int compare(Rule rule1, Rule rule2) {
+ return Integer.valueOf(rule1.priority()).compareTo(Integer.valueOf(rule2.priority()));
+ }
+ }).priority()) + 1;
+ }
+ return priority;
+ }
+
+ public static String createRuleName(int fromPort, int toPort) {
+ return String.format(AzureComputeProperties.TCP_RULE_FORMAT, fromPort, toPort);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ConfigurationSetHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ConfigurationSetHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ConfigurationSetHandler.java
index 4e5b54b..8a2fb57 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ConfigurationSetHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ConfigurationSetHandler.java
@@ -35,6 +35,7 @@ public class ConfigurationSetHandler extends ParseSax.HandlerForGeneratedRequest
private List<SubnetName> subnetNames = Lists.newArrayList();
private String staticVirtualNetworkIPAddress;
private List<PublicIP> publicIPs = Lists.newArrayList();
+ private String networkSecurityGroup;
private boolean inInputEndpoint;
private boolean inSubnetNames;
@@ -50,13 +51,14 @@ public class ConfigurationSetHandler extends ParseSax.HandlerForGeneratedRequest
@Override
public ConfigurationSet getResult() {
- ConfigurationSet result = ConfigurationSet.create(configurationSetType, inputEndpoint, subnetNames, staticVirtualNetworkIPAddress, publicIPs);
+ ConfigurationSet result = ConfigurationSet.create(configurationSetType, inputEndpoint, subnetNames,
+ staticVirtualNetworkIPAddress, publicIPs, networkSecurityGroup);
resetState(); // handler is called in a loop.
return result;
}
private void resetState() {
- configurationSetType = staticVirtualNetworkIPAddress = null;
+ configurationSetType = staticVirtualNetworkIPAddress = networkSecurityGroup = null;
inputEndpoint = Lists.newArrayList();
subnetNames = Lists.newArrayList();
publicIPs = Lists.newArrayList();
@@ -92,6 +94,8 @@ public class ConfigurationSetHandler extends ParseSax.HandlerForGeneratedRequest
subnetNameHandler.endElement(ignoredUri, ignoredName, qName);
} else if (qName.equals("ConfigurationSetType")) {
configurationSetType = currentOrNull(currentText);
+ } else if (qName.equals("NetworkSecurityGroup")) {
+ networkSecurityGroup = currentOrNull(currentText);
}
currentText.setLength(0);
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/xml/NetworkConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/NetworkConfigurationHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/NetworkConfigurationHandler.java
index 10666ec..648ddc0 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/NetworkConfigurationHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/NetworkConfigurationHandler.java
@@ -16,54 +16,54 @@
*/
package org.jclouds.azurecompute.xml;
-import static org.jclouds.util.SaxUtils.currentOrNull;
-
-import java.util.List;
-
import org.jclouds.azurecompute.domain.NetworkConfiguration;
+import org.jclouds.azurecompute.domain.NetworkConfiguration.VirtualNetworkConfiguration;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
-import com.google.common.collect.Lists;
+import com.google.inject.Inject;
public class NetworkConfigurationHandler extends ParseSax.HandlerForGeneratedRequestWithResult<NetworkConfiguration> {
- private String dns;
- private List<NetworkConfiguration.VirtualNetworkSite> virtualNetworkSites = Lists.newArrayList();
+ private VirtualNetworkConfiguration virtualNetworkConfiguration;
- private boolean inVirtualNetworkSites;
- private final VirtualNetworkSiteHandler virtualNetworkSiteHandler = new VirtualNetworkSiteHandler();
+ private boolean inVirtualNetworkConfiguration;
+ private final VirtualNetworkConfigurationHandler virtualNetworkConfigurationHandler;
+
+ @Inject
+ NetworkConfigurationHandler(VirtualNetworkConfigurationHandler virtualNetworkConfigurationHandler) {
+ this.virtualNetworkConfigurationHandler = virtualNetworkConfigurationHandler;
+ }
private final StringBuilder currentText = new StringBuilder();
@Override public void startElement(String url, String name, String qName, Attributes attributes) {
- if (qName.equals("VirtualNetworkSite")) {
- inVirtualNetworkSites = true;
+ if (qName.equals("VirtualNetworkConfiguration")) {
+ inVirtualNetworkConfiguration = true;
+ }
+ if (inVirtualNetworkConfiguration) {
+ virtualNetworkConfigurationHandler.startElement(url, name, qName, attributes);
}
}
@Override
public NetworkConfiguration getResult() {
- return NetworkConfiguration.create(dns, virtualNetworkSites);
+ return NetworkConfiguration.create(virtualNetworkConfiguration);
}
@Override
public void endElement(String ignoredUri, String ignoredName, String qName) {
- if (qName.equals("Dns")) {
- dns = currentOrNull(currentText);
- } else if (qName.equals("VirtualNetworkSites")) {
- inVirtualNetworkSites = false;
- } else if (qName.equals("VirtualNetworkSite")) {
- virtualNetworkSites.add(virtualNetworkSiteHandler.getResult());
- } else if (inVirtualNetworkSites) {
- virtualNetworkSiteHandler.endElement(ignoredUri, ignoredName, qName);
+ if (qName.equals("VirtualNetworkConfiguration")) {
+ virtualNetworkConfiguration = virtualNetworkConfigurationHandler.getResult();
+ } else if (inVirtualNetworkConfiguration) {
+ virtualNetworkConfigurationHandler.endElement(ignoredUri, ignoredName, qName);
}
currentText.setLength(0);
}
@Override public void characters(char ch[], int start, int length) {
- if (inVirtualNetworkSites) {
- virtualNetworkSiteHandler.characters(ch, start, length);
+ if (inVirtualNetworkConfiguration) {
+ virtualNetworkConfigurationHandler.characters(ch, start, length);
} else
currentText.append(ch, start, length);
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e97ddaee/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ResourceExtensionParameterValueHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ResourceExtensionParameterValueHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ResourceExtensionParameterValueHandler.java
new file mode 100644
index 0000000..2ad6c14
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ResourceExtensionParameterValueHandler.java
@@ -0,0 +1,60 @@
+/*
+ * 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.xml;
+
+import static org.jclouds.util.SaxUtils.currentOrNull;
+
+import org.jclouds.azurecompute.domain.Role.ResourceExtensionReference.ResourceExtensionParameterValue;
+import org.jclouds.http.functions.ParseSax;
+import org.xml.sax.Attributes;
+
+public final class ResourceExtensionParameterValueHandler extends ParseSax.HandlerForGeneratedRequestWithResult<ResourceExtensionParameterValue> {
+ private String key;
+ private String value;
+ private String type;
+
+ private StringBuilder currentText = new StringBuilder();
+
+ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) {
+ }
+
+ @Override public ResourceExtensionParameterValue getResult() {
+ ResourceExtensionParameterValue result = ResourceExtensionParameterValue.create(key, value, type);
+ resetState(); // handler is called in a loop.
+ return result;
+ }
+
+ private void resetState() {
+ key = value = type = null;
+ }
+
+ @Override public void endElement(String ignoredUri, String ignoredName, String qName) {
+ if (qName.equals("Key")) {
+ key = currentOrNull(currentText);
+ } else if (qName.equals("Value")) {
+ value = currentOrNull(currentText);
+ } else if (qName.equals("Type")) {
+ type = currentOrNull(currentText);
+ }
+ currentText.setLength(0);
+ }
+
+ @Override public void characters(char ch[], int start, int length) {
+ currentText.append(ch, start, length);
+ }
+
+}