You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/10/21 06:24:31 UTC

[1/2] git commit: Cleanup Azure compute DeploymentParams input value type.

Repository: jclouds-labs
Updated Branches:
  refs/heads/master 20c397c7f -> 21ef291a0


Cleanup Azure compute DeploymentParams input value type.


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/21ef291a
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/21ef291a
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/21ef291a

Branch: refs/heads/master
Commit: 21ef291a0b865540703440d3113dce251fdc4579
Parents: 9f8369c
Author: Adrian Cole <ac...@twitter.com>
Authored: Mon Oct 20 13:45:15 2014 -0400
Committer: Adrian Cole <ad...@apache.org>
Committed: Mon Oct 20 21:23:09 2014 -0700

----------------------------------------------------------------------
 .../BindDeploymentParamsToXmlPayload.java       | 118 -------
 .../binders/CreateDeploymentToXML.java          | 119 +++++++
 .../azurecompute/domain/DeploymentParams.java   | 309 ++++++++++++-------
 .../azurecompute/domain/InputEndpoint.java      | 137 --------
 .../jclouds/azurecompute/domain/Protocol.java   |  23 --
 .../azurecompute/features/DeploymentApi.java    |  10 +-
 .../features/DeploymentApiMockTest.java         |  45 ++-
 .../azurecompute/xml/ListImagesHandlerTest.java |   3 +-
 .../test/resources/deploymentparams-windows.xml |   1 +
 .../src/test/resources/deploymentparams.xml     |   2 +-
 azurecompute/src/test/resources/images.xml      |   4 +-
 11 files changed, 360 insertions(+), 411 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
deleted file mode 100644
index 8b20634..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
+++ /dev/null
@@ -1,118 +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.azurecompute.binders;
-
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-import static org.jclouds.azurecompute.domain.Image.OSType.LINUX;
-
-import javax.inject.Singleton;
-
-import org.jclouds.azurecompute.domain.DeploymentParams;
-import org.jclouds.azurecompute.domain.Image.OSType;
-import org.jclouds.azurecompute.domain.InputEndpoint;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.rest.Binder;
-
-import com.google.common.base.Throwables;
-import com.jamesmurty.utils.XMLBuilder;
-
-@Singleton
-public class BindDeploymentParamsToXmlPayload implements Binder {
-
-   @Override
-   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
-      DeploymentParams params = DeploymentParams.class.cast(input);
-      try {
-         XMLBuilder builder = XMLBuilder.create("Deployment").a("xmlns", "http://schemas.microsoft.com/windowsazure")
-            .e("Name").t(params.getName()).up()
-            .e("DeploymentSlot").t("Production").up()
-            .e("Label").t(params.getName()).up()
-            .e("RoleList")
-            .e("Role")
-            .e("RoleName").t(params.getName()).up()
-            .e("RoleType").t("PersistentVMRole").up()
-            .e("ConfigurationSets");
-
-         if (params.getOsType() == OSType.WINDOWS) {
-            XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Windows
-            configBuilder.e("ConfigurationSetType").t("WindowsProvisioningConfiguration").up()
-               .e("ComputerName").t(params.getUsername()).up()
-               .e("AdminPassword").t(params.getPassword()).up()
-               .e("ResetPasswordOnFirstLogon").t("false").up()
-               .e("EnableAutomaticUpdate").t("false").up()
-               .e("DomainJoin")
-               .e("Credentials")
-                  .e("Domain").t(params.getName()).up()
-                  .e("Username").t(params.getUsername()).up()
-                  .e("Password").t(params.getPassword()).up()
-               .up() // Credentials
-               .e("JoinDomain").t(params.getName()).up()
-               .up() // Domain Join
-               .e("StoredCertificateSettings").up()
-               .up(); // Windows ConfigurationSet
-         } else if (params.getOsType() == OSType.LINUX) {
-            XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Linux
-            configBuilder.e("ConfigurationSetType").t("LinuxProvisioningConfiguration").up()
-               .e("HostName").t(params.getName()).up()
-               .e("UserName").t(params.getUsername()).up()
-               .e("UserPassword").t(params.getPassword()).up()
-               .e("DisableSshPasswordAuthentication").t("false").up()
-               .e("SSH").up()
-               .up(); // Linux ConfigurationSet
-         }
-
-         XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Network
-         configBuilder.e("ConfigurationSetType").t("NetworkConfiguration").up();
-
-         XMLBuilder inputEndpoints = configBuilder.e("InputEndpoints");
-         for (InputEndpoint endpoint : params.getEndpoints()) {
-            XMLBuilder inputBuilder = inputEndpoints.e("InputEndpoint");
-            inputBuilder.e("LocalPort").t(endpoint.getLocalPort().toString()).up()
-               .e("Name").t(endpoint.getName()).up()
-               .e("Port").t(endpoint.getExternalPort().toString()).up()
-               .e("Protocol").t(endpoint.getProtocol().name().toLowerCase()).up()
-               .up(); //InputEndpoint
-         }
-
-         inputEndpoints.up();
-         configBuilder.e("SubnetNames").up()
-            .up();
-
-         builder.up() //ConfigurationSets
-            .e("DataVirtualHardDisks").up()
-            .e("OSVirtualHardDisk")
-            .e("HostCaching").t("ReadWrite").up()
-            .e("MediaLink").t(url(params)).up()
-            .e("SourceImageName").t(params.getSourceImageName()).up()
-            .e("OS").t(params.getOsType() == LINUX ? "Linux" : "Windows").up()
-            .up() //OSVirtualHardDisk
-            .e("RoleSize").t(UPPER_UNDERSCORE.to(UPPER_CAMEL, params.getSize().name())).up()
-            .up() //Role
-            .up(); //RoleList
-
-         return (R) request.toBuilder().payload(builder.asString()).build();
-      } catch (Exception e) {
-         throw Throwables.propagate(e);
-      }
-   }
-
-   private static String url(DeploymentParams params) {
-      return String.format("http://%s.blob.core.windows.net/disks/%s/%s", params.getStorageAccount(), params.getName(),
-            params.getSourceImageName());
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/CreateDeploymentToXML.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/CreateDeploymentToXML.java b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/CreateDeploymentToXML.java
new file mode 100644
index 0000000..67573a8
--- /dev/null
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/CreateDeploymentToXML.java
@@ -0,0 +1,119 @@
+/*
+ * 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.binders;
+
+import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
+import static com.google.common.base.Throwables.propagate;
+import static org.jclouds.azurecompute.domain.Image.OSType.LINUX;
+
+import java.util.Map;
+
+import org.jclouds.azurecompute.domain.DeploymentParams;
+import org.jclouds.azurecompute.domain.Image.OSType;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.MapBinder;
+
+import com.jamesmurty.utils.XMLBuilder;
+
+public final class CreateDeploymentToXML implements MapBinder {
+
+   @Override public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
+      String name = postParams.get("name").toString();
+      DeploymentParams params = DeploymentParams.class.cast(postParams.get("params"));
+
+      try {
+         XMLBuilder builder = XMLBuilder.create("Deployment", "http://schemas.microsoft.com/windowsazure")
+            .e("Name").t(name).up()
+            .e("DeploymentSlot").t("Production").up()
+            .e("Label").t(name).up()
+            .e("RoleList")
+            .e("Role")
+            .e("RoleName").t(name).up()
+            .e("RoleType").t("PersistentVMRole").up()
+            .e("ConfigurationSets");
+
+         if (params.os() == OSType.WINDOWS) {
+            XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Windows
+            configBuilder.e("ConfigurationSetType").t("WindowsProvisioningConfiguration").up()
+               .e("ComputerName").t(name).up()
+               .e("AdminPassword").t(params.password()).up()
+               .e("ResetPasswordOnFirstLogon").t("false").up()
+               .e("EnableAutomaticUpdate").t("false").up()
+               .e("DomainJoin")
+               .e("Credentials")
+                  .e("Domain").t(name).up()
+                  .e("Username").t(params.username()).up()
+                  .e("Password").t(params.password()).up()
+               .up() // Credentials
+               .e("JoinDomain").t(name).up()
+               .up() // Domain Join
+               .e("StoredCertificateSettings").up()
+               .up(); // Windows ConfigurationSet
+         } else if (params.os() == OSType.LINUX) {
+            XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Linux
+            configBuilder.e("ConfigurationSetType").t("LinuxProvisioningConfiguration").up()
+               .e("HostName").t(name).up()
+               .e("UserName").t(params.username()).up()
+               .e("UserPassword").t(params.password()).up()
+               .e("DisableSshPasswordAuthentication").t("false").up()
+               .e("SSH").up()
+               .up(); // Linux ConfigurationSet
+         } else {
+            throw new IllegalArgumentException("Unrecognized os type " + params);
+         }
+
+         XMLBuilder configBuilder = builder.e("ConfigurationSet"); // Network
+         configBuilder.e("ConfigurationSetType").t("NetworkConfiguration").up();
+
+         XMLBuilder inputEndpoints = configBuilder.e("InputEndpoints");
+         for (DeploymentParams.ExternalEndpoint endpoint : params.externalEndpoints()) {
+            XMLBuilder inputBuilder = inputEndpoints.e("InputEndpoint");
+            inputBuilder.e("LocalPort").t(Integer.toString(endpoint.localPort())).up()
+               .e("Name").t(endpoint.name()).up()
+               .e("Port").t(Integer.toString(endpoint.port())).up()
+               .e("Protocol").t(endpoint.protocol().toLowerCase()).up()
+               .up(); //InputEndpoint
+         }
+
+         inputEndpoints.up();
+         configBuilder.e("SubnetNames").up()
+            .up();
+
+         builder.up() //ConfigurationSets
+            .e("DataVirtualHardDisks").up()
+            .e("OSVirtualHardDisk")
+            .e("HostCaching").t("ReadWrite").up()
+            .e("MediaLink").t(params.mediaLink().toASCIIString()).up()
+            .e("SourceImageName").t(params.sourceImageName()).up()
+            .e("OS").t(params.os() == LINUX ? "Linux" : "Windows").up()
+            .up() //OSVirtualHardDisk
+            .e("RoleSize").t(UPPER_UNDERSCORE.to(UPPER_CAMEL, params.size().name())).up()
+            .up() //Role
+            .up(); //RoleList
+
+         // TODO: Undeprecate this method as forcing users to wrap a String in guava's ByteSource is not great.
+         return (R) request.toBuilder().payload(builder.asString()).build();
+      } catch (Exception e) {
+         throw propagate(e);
+      }
+   }
+
+   @Override public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      throw new UnsupportedOperationException("use map form");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
index 914b34e..2dd9ae5 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
@@ -16,13 +16,18 @@
  */
 package org.jclouds.azurecompute.domain;
 
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.Collection;
 import java.util.List;
 
 import org.jclouds.azurecompute.domain.Image.OSType;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 /**
@@ -30,34 +35,138 @@ import com.google.common.collect.Lists;
  *
  * Warning : the OSType must be the one of the source image used to create the VM
  */
-public class DeploymentParams {
+// TODO: check which can be null.
+public final class DeploymentParams {
 
-   public static Builder builder() {
-      return new Builder();
+   public static final class ExternalEndpoint {
+
+      public String name() {
+         return name;
+      }
+
+      /** Either {@code tcp} or {@code udp}. */
+      public String protocol() {
+         return protocol;
+      }
+
+      public int port() {
+         return port;
+      }
+
+      public int localPort() {
+         return localPort;
+      }
+
+      public static ExternalEndpoint inboundTcpToLocalPort(int port, int localPort) {
+         return new ExternalEndpoint(String.format("tcp %s:%s", port, localPort), "tcp", port, localPort);
+      }
+
+      public static ExternalEndpoint inboundUdpToLocalPort(int port, int localPort) {
+         return new ExternalEndpoint(String.format("udp %s:%s", port, localPort), "udp", port, localPort);
+      }
+
+      // TODO: Remove from here down with @AutoValue.
+      private ExternalEndpoint(String name, String protocol, int port, int localPort) {
+         this.name = checkNotNull(name, "name");
+         this.protocol = checkNotNull(protocol, "protocol");
+         this.port = port;
+         this.localPort = localPort;
+      }
+
+      private final String name;
+      private final String protocol;
+      private final int port;
+      private final int localPort;
+
+      @Override public int hashCode() {
+         return Objects.hashCode(name, protocol, localPort, port);
+      }
+
+      @Override public boolean equals(Object object) {
+         if (this == object) {
+            return true;
+         }
+         if (object instanceof ExternalEndpoint) {
+            ExternalEndpoint that = ExternalEndpoint.class.cast(object);
+            return equal(name, that.name)
+                  && equal(protocol, that.protocol)
+                  && equal(localPort, that.localPort)
+                  && equal(port, that.port);
+         } else {
+            return false;
+         }
+      }
+
+      @Override public String toString() {
+         return toStringHelper(this)
+               .add("name", name)
+               .add("protocol", protocol)
+               .add("port", port)
+               .add("localPort", localPort).toString();
+      }
+   }
+
+   /**
+    * Specifies the name of a user to be created in the sudoers group of the
+    * virtual machine. User names are ASCII character strings 1 to 32
+    * characters in length.
+    */
+   public String username() {
+      return username;
+   }
+
+   /** The size of the virtual machine to allocate. The default value is Small. */
+   public RoleSize size() {
+      return size;
+   }
+
+   /**
+    * Specifies the associated password for the user name.
+    * Passwords are ASCII character strings 6 to 72 characters in
+    * length.
+    */
+   public String password() {
+      return password;
+   }
+
+   /** {@link Image#name() name} of the user or platform image. */
+   public String sourceImageName() {
+      return sourceImageName;
+   }
+
+   /** Indicates the {@link Image#mediaLink() location} when {@link #sourceImageName() source} is a platform image. */
+   public URI mediaLink() {
+      return mediaLink;
+   }
+
+   /** {@link Image#os() Os type} of the {@link #sourceImageName() source image}. */
+   public OSType os() {
+      return os;
+   }
+
+   public List<ExternalEndpoint> externalEndpoints() {
+      return externalEndpoints;
    }
 
    public Builder toBuilder() {
       return builder().fromDeploymentParams(this);
    }
 
-   public static class Builder {
+   public static Builder builder() {
+      return new Builder();
+   }
 
-      private String name;
-      private String sourceImageName;
+   public static final class Builder {
+      private RoleSize size = RoleSize.SMALL;
       private String username;
       private String password;
-      private String storageAccount;
-      private OSType osType;
-      private RoleSize size = RoleSize.SMALL;
-      private List<InputEndpoint> endpoints = Lists.newArrayList();
-
-      public Builder name(String name) {
-         this.name = name;
-         return this;
-      }
+      private String sourceImageName;
+      private URI mediaLink;
+      private OSType os;
+      private List<ExternalEndpoint> externalEndpoints = Lists.newArrayList();
 
-      public Builder sourceImageName(String sourceImageName) {
-         this.sourceImageName = sourceImageName;
+      public Builder size(RoleSize size) {
+         this.size = size;
          return this;
       }
 
@@ -71,141 +180,105 @@ public class DeploymentParams {
          return this;
       }
 
-      public Builder storageAccount(String storageAccount) {
-         this.storageAccount = storageAccount;
+      public Builder sourceImageName(String sourceImageName) {
+         this.sourceImageName = sourceImageName;
          return this;
       }
 
-      public Builder size(RoleSize size) {
-         this.size = size;
+      public Builder mediaLink(URI mediaLink) {
+         this.mediaLink = mediaLink;
+         return this;
+      }
+
+      public Builder os(OSType os) {
+         this.os = os;
          return this;
       }
 
-      public Builder osType(OSType osType) {
-         this.osType = osType;
+      public Builder externalEndpoint(ExternalEndpoint endpoint) {
+         externalEndpoints.add(endpoint);
          return this;
       }
 
-      public Builder endpoint(InputEndpoint endpoint) {
-         endpoints.add(endpoint);
+      public Builder externalEndpoints(Collection<ExternalEndpoint> externalEndpoints) {
+         externalEndpoints.addAll(externalEndpoints);
          return this;
       }
 
       public DeploymentParams build() {
-         return new DeploymentParams(name, sourceImageName, username, password, storageAccount, size, osType,
-               endpoints);
+         return DeploymentParams.create(size, username, password, sourceImageName, mediaLink, os,
+               ImmutableList.copyOf(externalEndpoints));
       }
 
       public Builder fromDeploymentParams(DeploymentParams in) {
-         // TODO Since the virtualMachineName should be unique, is it a good idea to copy it ?
-         return this.name(in.getName()).sourceImageName(in.getSourceImageName()).username(in.getUsername())
-               .password(in.getPassword()).size(in.getSize());
+         return size(in.size())
+               .username(in.username())
+               .password(in.password())
+               .sourceImageName(in.sourceImageName())
+               .mediaLink(in.mediaLink())
+               .os(in.os())
+               .externalEndpoints(in.externalEndpoints());
       }
    }
 
-   private final String name;
-   private final String sourceImageName;
-   private final String username;
-   private final String password;
-   private final String storageAccount;
-   private final RoleSize size;
-   private final OSType osType;
-   private final List<InputEndpoint> endpoints;
-
-   public DeploymentParams(String name, String sourceImageName, String username, String password, String storageAccount,
-         RoleSize size, OSType osType, final List<InputEndpoint> endpoints) {
-      this.name = name;
-      this.sourceImageName = sourceImageName;
-      this.username = username;
-      this.password = password;
-      this.storageAccount = storageAccount;
-      this.size = size;
-      this.osType = osType;
-      this.endpoints = endpoints;
-   }
-
-   /**
-    * Specifies the name for the deployment and its virtual machine. The name must be unique
-    * within Windows Azure.
-    */
-   public String getName() {
-      return name;
-   }
-
-   /**
-    * Specifies the name of an operating system image in the image repository.
-    */
-   public String getSourceImageName() {
-      return sourceImageName;
-   }
-
-   /**
-    * Specifies the name of a user to be created in the sudoer group of the
-    * virtual machine. User names are ASCII character strings 1 to 32
-    * characters in length.
-    */
-   public String getUsername() {
-      return username;
-   }
-
-   /**
-    * Specifies the associated password for the user name.
-    * PasswoazureManagement are ASCII character strings 6 to 72 characters in
-    * length.
-    */
-   public String getPassword() {
-      return password;
+   private static DeploymentParams create(RoleSize size, String username, String password, String sourceImageName,
+         URI mediaLink, OSType os, List<ExternalEndpoint> externalEndpoints) {
+      return new DeploymentParams(size, username, password, sourceImageName, mediaLink, os, externalEndpoints);
    }
 
-   public String getStorageAccount() {
-      return storageAccount;
+   // TODO: Remove from here down with @AutoValue.
+   private DeploymentParams(RoleSize size, String username, String password, String sourceImageName, URI mediaLink,
+         OSType os, List<ExternalEndpoint> externalEndpoints) {
+      this.size = checkNotNull(size, "size");
+      this.username = checkNotNull(username, "username");
+      this.password = checkNotNull(password, "password");
+      this.sourceImageName = checkNotNull(sourceImageName, "sourceImageName");
+      this.mediaLink = checkNotNull(mediaLink, "mediaLink");
+      this.os = checkNotNull(os, "os");
+      this.externalEndpoints = checkNotNull(externalEndpoints, "externalEndpoints");
    }
 
-   /**
-    * The size of the virtual machine to allocate. The default value is Small.
-    */
-   public RoleSize getSize() {
-      return size;
-   }
-
-   /**
-    * Os type of the given sourceImage
-    */
-   public OSType getOsType() {
-      return osType;
-   }
-
-   public List<InputEndpoint> getEndpoints() {
-      return endpoints;
-   }
+   private final RoleSize size;
+   private final String username;
+   private final String password;
+   private final String sourceImageName;
+   private final URI mediaLink;
+   private final OSType os;
+   private final List<ExternalEndpoint> externalEndpoints;
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(name);
+      return Objects.hashCode(sourceImageName, username, password, mediaLink, size, os, externalEndpoints);
    }
 
    @Override
-   public boolean equals(Object obj) {
-      if (this == obj) {
+   public boolean equals(Object object) {
+      if (this == object) {
          return true;
       }
-      if (obj == null) {
+      if (object instanceof DeploymentParams) {
+         DeploymentParams that = DeploymentParams.class.cast(object);
+         return equal(size, that.size)
+               && equal(username, that.username)
+               && equal(password, that.password)
+               && equal(sourceImageName, that.sourceImageName)
+               && equal(mediaLink, that.mediaLink)
+               && equal(os, that.os)
+               && equal(externalEndpoints, that.externalEndpoints);
+      } else {
          return false;
       }
-      if (getClass() != obj.getClass()) {
-         return false;
-      }
-      DeploymentParams other = (DeploymentParams) obj;
-      return Objects.equal(this.name, other.name);
    }
 
    @Override
    public String toString() {
-      return string().toString();
-   }
-
-   private ToStringHelper string() {
-      return MoreObjects.toStringHelper(this).add("name", name).add("sourceImageName", sourceImageName)
-            .add("size", size);
+      return toStringHelper(this)
+            .add("size", size)
+            .add("username", username)
+            .add("password", password)
+            .add("sourceImageName", sourceImageName)
+            .add("mediaLink", mediaLink)
+            .add("os", os)
+            .add("externalEndpoints", externalEndpoints).toString();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/InputEndpoint.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/InputEndpoint.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/InputEndpoint.java
deleted file mode 100644
index a06c0f5..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/InputEndpoint.java
+++ /dev/null
@@ -1,137 +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.azurecompute.domain;
-
-public class InputEndpoint {
-
-	public static Builder builder() {
-		return new Builder();
-	}
-
-	public static class Builder {
-		private Integer localPort;
-		private Integer externalPort;
-		private String name;
-		private Protocol protocol;
-
-		public Builder localPort(Integer localPort) {
-			this.localPort = localPort;
-			return this;
-		}
-
-		public Builder externalPort(Integer externalPort) {
-			this.externalPort = externalPort;
-			return this;
-		}
-
-		public Builder name(String name) {
-			this.name = name;
-			return this;
-		}
-
-		public Builder protocol(Protocol protocol) {
-			this.protocol = protocol;
-			return this;
-		}
-
-		public InputEndpoint build(){
-			return new InputEndpoint(localPort, externalPort, name, protocol);
-		}
-
-	}
-
-	private final Integer localPort;
-	private final Integer externalPort;
-	private final String name;
-	private final Protocol protocol;
-
-	public InputEndpoint(Integer localPort, Integer externalPort, String name,
-			Protocol protocol) {
-		super();
-		this.localPort = localPort;
-		this.externalPort = externalPort;
-		this.name = name;
-		this.protocol = protocol;
-	}
-
-	public Integer getLocalPort() {
-		return localPort;
-	}
-
-	public Integer getExternalPort() {
-		return externalPort;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Protocol getProtocol() {
-		return protocol;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result
-				+ ((externalPort == null) ? 0 : externalPort.hashCode());
-		result = prime * result
-				+ ((localPort == null) ? 0 : localPort.hashCode());
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		result = prime * result
-				+ ((protocol == null) ? 0 : protocol.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		InputEndpoint other = (InputEndpoint) obj;
-		if (externalPort == null) {
-			if (other.externalPort != null)
-				return false;
-		} else if (!externalPort.equals(other.externalPort))
-			return false;
-		if (localPort == null) {
-			if (other.localPort != null)
-				return false;
-		} else if (!localPort.equals(other.localPort))
-			return false;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		if (protocol != other.protocol)
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return "InputEndPoint [localPort=" + localPort + ", externalPort="
-				+ externalPort + ", name=" + name + ", protocol=" + protocol
-				+ "]";
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Protocol.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Protocol.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Protocol.java
deleted file mode 100644
index 2e3d245..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Protocol.java
+++ /dev/null
@@ -1,23 +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.azurecompute.domain;
-
-public enum Protocol {
-   TCP,
-   HTTP,
-   UDP
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/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 ada88ac..37dfd4e 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/features/DeploymentApi.java
@@ -25,14 +25,15 @@ 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.BindDeploymentParamsToXmlPayload;
+import org.jclouds.azurecompute.binders.CreateDeploymentToXML;
 import org.jclouds.azurecompute.domain.Deployment;
 import org.jclouds.azurecompute.domain.DeploymentParams;
 import org.jclouds.azurecompute.functions.ParseRequestIdHeader;
 import org.jclouds.azurecompute.xml.DeploymentHandler;
-import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
 import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.annotations.XMLResponseParser;
 
@@ -57,13 +58,14 @@ public interface DeploymentApi {
    Deployment get(@PathParam("name") String name);
 
    /**
-    * http://msdn.microsoft.com/en-us/library/jj157194
+    * @param name the name for the deployment and its virtual machine. The name must be unique within Windows Azure.
     */
    @Named("CreateVirtualMachineDeployment")
    @POST
    @Produces(MediaType.APPLICATION_XML)
    @ResponseParser(ParseRequestIdHeader.class)
-   String create(@BinderParam(BindDeploymentParamsToXmlPayload.class) DeploymentParams deploymentParams);
+   @MapBinder(CreateDeploymentToXML.class)
+   String create(@PayloadParam("name") String name, @PayloadParam("params") DeploymentParams params);
 
    /**
     * The Delete Deployment operation deletes the specified deployment from Windows Azure.

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
index d31e699..e665557 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
@@ -16,14 +16,17 @@
  */
 package org.jclouds.azurecompute.features;
 
+import static org.jclouds.azurecompute.domain.DeploymentParams.ExternalEndpoint.inboundTcpToLocalPort;
+import static org.jclouds.azurecompute.domain.DeploymentParams.ExternalEndpoint.inboundUdpToLocalPort;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
 import org.jclouds.azurecompute.domain.DeploymentParams;
-import org.jclouds.azurecompute.domain.Image.OSType;
+import org.jclouds.azurecompute.domain.Image;
 import org.jclouds.azurecompute.domain.RoleSize;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiMockTest;
 import org.jclouds.azurecompute.xml.DeploymentHandlerTest;
+import org.jclouds.azurecompute.xml.ListImagesHandlerTest;
 import org.testng.annotations.Test;
 
 import com.squareup.okhttp.mockwebserver.MockResponse;
@@ -32,19 +35,23 @@ import com.squareup.okhttp.mockwebserver.MockWebServer;
 @Test(groups = "unit", testName = "DeploymentApiMockTest")
 public class DeploymentApiMockTest extends BaseAzureComputeApiMockTest {
 
-   public void create() throws Exception {
+   public void createLinux() throws Exception {
       MockWebServer server = mockAzureManagementServer();
       server.enqueue(requestIdResponse("request-1"));
 
       try {
          DeploymentApi api = api(server.getUrl("/")).getDeploymentApiForService("myservice");
 
-         DeploymentParams params = DeploymentParams.builder().osType(OSType.LINUX).name("mydeployment")
-               .username("username").password("testpwd").size(RoleSize.MEDIUM)
-               .sourceImageName("OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd")
-               .storageAccount("portalvhds0g7xhnq2x7t21").build();
+         Image image = ListImagesHandlerTest.expected().get(5); // CentOS
 
-         assertEquals(api.create(params), "request-1");
+         DeploymentParams params = DeploymentParams.builder()
+               .size(RoleSize.MEDIUM)
+               .sourceImageName(image.name()).mediaLink(image.mediaLink()).os(image.os())
+               .username("username").password("testpwd")
+               .externalEndpoint(inboundTcpToLocalPort(80, 8080))
+               .externalEndpoint(inboundUdpToLocalPort(53, 53)).build();
+
+         assertEquals(api.create("mydeployment", params), "request-1");
 
          assertSent(server, "POST", "/services/hostedservices/myservice/deployments", "/deploymentparams.xml");
       } finally {
@@ -52,6 +59,30 @@ public class DeploymentApiMockTest extends BaseAzureComputeApiMockTest {
       }
    }
 
+   public void createWindows() throws Exception {
+      MockWebServer server = mockAzureManagementServer();
+      server.enqueue(requestIdResponse("request-1"));
+
+      try {
+         DeploymentApi api = api(server.getUrl("/")).getDeploymentApiForService("myservice");
+
+         Image image = ListImagesHandlerTest.expected().get(1); // Windows
+
+         DeploymentParams params = DeploymentParams.builder()
+               .size(RoleSize.MEDIUM)
+               .sourceImageName(image.name()).mediaLink(image.mediaLink()).os(image.os())
+               .username("username").password("testpwd")
+               .externalEndpoint(inboundTcpToLocalPort(80, 8080))
+               .externalEndpoint(inboundUdpToLocalPort(53, 53)).build();
+
+         assertEquals(api.create("mydeployment", params), "request-1");
+
+         assertSent(server, "POST", "/services/hostedservices/myservice/deployments", "/deploymentparams-windows.xml");
+      } finally {
+         server.shutdown();
+      }
+   }
+
    public void getWhenFound() throws Exception {
       MockWebServer server = mockAzureManagementServer();
       server.enqueue(xmlResponse("/deployment.xml"));

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
index b82c55b..ffd3de3 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
@@ -19,6 +19,7 @@ package org.jclouds.azurecompute.xml;
 import static org.testng.Assert.assertEquals;
 
 import java.io.InputStream;
+import java.net.URI;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -111,7 +112,7 @@ public class ListImagesHandlerTest extends BaseHandlerTest {
                   "This distribution of Linux is based on CentOS.", //description
                   "OpenLogic", // category
                   OSType.LINUX, // os
-                  null, // mediaLink
+                  URI.create("http://blobs/disks/mydeployment/OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd"), // mediaLink
                   30, // logicalSizeInGB
                   Arrays.asList("http://www.openlogic.com/azure/service-agreement/") // eula
             ),

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/test/resources/deploymentparams-windows.xml
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/resources/deploymentparams-windows.xml b/azurecompute/src/test/resources/deploymentparams-windows.xml
new file mode 100644
index 0000000..a819115
--- /dev/null
+++ b/azurecompute/src/test/resources/deploymentparams-windows.xml
@@ -0,0 +1 @@
+<Deployment xmlns="http://schemas.microsoft.com/windowsazure"><Name>mydeployment</Name><DeploymentSlot>Production</DeploymentSlot><Label>mydeployment</Label><RoleList><Role><RoleName>mydeployment</RoleName><RoleType>PersistentVMRole</RoleType><ConfigurationSets><ConfigurationSet><ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType><ComputerName>mydeployment</ComputerName><AdminPassword>testpwd</AdminPassword><ResetPasswordOnFirstLogon>false</ResetPasswordOnFirstLogon><EnableAutomaticUpdate>false</EnableAutomaticUpdate><DomainJoin><Credentials><Domain>mydeployment</Domain><Username>username</Username><Password>testpwd</Password></Credentials><JoinDomain>mydeployment</JoinDomain></DomainJoin><StoredCertificateSettings/></ConfigurationSet><ConfigurationSet><ConfigurationSetType>NetworkConfiguration</ConfigurationSetType><InputEndpoints><InputEndpoint><LocalPort>8080</LocalPort><Name>tcp 80:8080</Name><Port>80</Port><Protocol>tcp</Protocol></InputEndpoint><InputE
 ndpoint><LocalPort>53</LocalPort><Name>udp 53:53</Name><Port>53</Port><Protocol>udp</Protocol></InputEndpoint></InputEndpoints><SubnetNames/></ConfigurationSet></ConfigurationSets><DataVirtualHardDisks/><OSVirtualHardDisk><HostCaching>ReadWrite</HostCaching><MediaLink>http://blobs/disks/mydeployment/MSFT__Win2K8R2SP1-120612-1520-121206-01-en-us-30GB.vhd</MediaLink><SourceImageName>MSFT__Win2K8R2SP1-120612-1520-121206-01-en-us-30GB.vhd</SourceImageName><OS>Windows</OS></OSVirtualHardDisk><RoleSize>Medium</RoleSize></Role></RoleList></Deployment>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/test/resources/deploymentparams.xml
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/resources/deploymentparams.xml b/azurecompute/src/test/resources/deploymentparams.xml
index fadaff1..415276f 100644
--- a/azurecompute/src/test/resources/deploymentparams.xml
+++ b/azurecompute/src/test/resources/deploymentparams.xml
@@ -1 +1 @@
-<Deployment xmlns="http://schemas.microsoft.com/windowsazure"><Name>mydeployment</Name><DeploymentSlot>Production</DeploymentSlot><Label>mydeployment</Label><RoleList><Role><RoleName>mydeployment</RoleName><RoleType>PersistentVMRole</RoleType><ConfigurationSets><ConfigurationSet><ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType><HostName>mydeployment</HostName><UserName>username</UserName><UserPassword>testpwd</UserPassword><DisableSshPasswordAuthentication>false</DisableSshPasswordAuthentication><SSH/></ConfigurationSet><ConfigurationSet><ConfigurationSetType>NetworkConfiguration</ConfigurationSetType><InputEndpoints/><SubnetNames/></ConfigurationSet></ConfigurationSets><DataVirtualHardDisks/><OSVirtualHardDisk><HostCaching>ReadWrite</HostCaching><MediaLink>http://portalvhds0g7xhnq2x7t21.blob.core.windows.net/disks/mydeployment/OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd</MediaLink><SourceImageName>OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30
 GB.vhd</SourceImageName><OS>Linux</OS></OSVirtualHardDisk><RoleSize>Medium</RoleSize></Role></RoleList></Deployment>
\ No newline at end of file
+<Deployment xmlns="http://schemas.microsoft.com/windowsazure"><Name>mydeployment</Name><DeploymentSlot>Production</DeploymentSlot><Label>mydeployment</Label><RoleList><Role><RoleName>mydeployment</RoleName><RoleType>PersistentVMRole</RoleType><ConfigurationSets><ConfigurationSet><ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType><HostName>mydeployment</HostName><UserName>username</UserName><UserPassword>testpwd</UserPassword><DisableSshPasswordAuthentication>false</DisableSshPasswordAuthentication><SSH/></ConfigurationSet><ConfigurationSet><ConfigurationSetType>NetworkConfiguration</ConfigurationSetType><InputEndpoints><InputEndpoint><LocalPort>8080</LocalPort><Name>tcp 80:8080</Name><Port>80</Port><Protocol>tcp</Protocol></InputEndpoint><InputEndpoint><LocalPort>53</LocalPort><Name>udp 53:53</Name><Port>53</Port><Protocol>udp</Protocol></InputEndpoint></InputEndpoints><SubnetNames/></ConfigurationSet></ConfigurationSets><DataVirtualHardDisks/><OSVirtualHardD
 isk><HostCaching>ReadWrite</HostCaching><MediaLink>http://blobs/disks/mydeployment/OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd</MediaLink><SourceImageName>OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd</SourceImageName><OS>Linux</OS></OSVirtualHardDisk><RoleSize>Medium</RoleSize></Role></RoleList></Deployment>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/21ef291a/azurecompute/src/test/resources/images.xml
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/resources/images.xml b/azurecompute/src/test/resources/images.xml
index deaeae5..8c01393 100644
--- a/azurecompute/src/test/resources/images.xml
+++ b/azurecompute/src/test/resources/images.xml
@@ -1,5 +1,4 @@
-<Images xmlns="http://schemas.microsoft.com/windowsazure"
-    >
+<Images xmlns="http://schemas.microsoft.com/windowsazure">
     <OSImage>
         <Category>Canonical</Category>
         <Label>Ubuntu Server 12.04 LTS</Label>
@@ -51,6 +50,7 @@
         <Label>OpenLogic CentOS 6.2</Label>
         <LogicalSizeInGB>30</LogicalSizeInGB>
         <Name>OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd</Name>
+        <MediaLink>http://blobs/disks/mydeployment/OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd</MediaLink>
         <OS>Linux</OS>
         <Eula>http://www.openlogic.com/azure/service-agreement/</Eula>
         <Description>This distribution of Linux is based on CentOS.</Description>


[2/2] git commit: Azure's OSType is reliable so needs no defensive UNRECOGNIZED enum value. Simplify use and couple to Image.

Posted by ad...@apache.org.
Azure's OSType is reliable so needs no defensive UNRECOGNIZED enum value. Simplify use and couple to Image.


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/9f8369cb
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/9f8369cb
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/9f8369cb

Branch: refs/heads/master
Commit: 9f8369cbb2d7f86b5760b70891ee3d82a3d40861
Parents: 20c397c
Author: Adrian Cole <ac...@twitter.com>
Authored: Mon Oct 20 14:39:19 2014 -0400
Committer: Adrian Cole <ad...@apache.org>
Committed: Mon Oct 20 21:23:09 2014 -0700

----------------------------------------------------------------------
 .../BindDeploymentParamsToXmlPayload.java       |  5 ++-
 .../binders/BindOSImageParamsToXmlPayload.java  | 25 ++++++-----
 .../azurecompute/domain/DeploymentParams.java   |  5 ++-
 .../org/jclouds/azurecompute/domain/Disk.java   |  1 +
 .../org/jclouds/azurecompute/domain/Image.java  |  3 ++
 .../azurecompute/domain/ImageParams.java        |  9 ++--
 .../org/jclouds/azurecompute/domain/OSType.java | 45 --------------------
 .../jclouds/azurecompute/xml/DiskHandler.java   | 12 +++---
 .../jclouds/azurecompute/xml/ImageHandler.java  |  7 ++-
 .../features/DeploymentApiMockTest.java         |  2 +-
 .../azurecompute/features/DiskApiLiveTest.java  |  3 --
 .../azurecompute/features/ImageApiLiveTest.java |  2 -
 .../azurecompute/features/ImageApiMockTest.java |  2 +-
 .../azurecompute/xml/ListDisksHandlerTest.java  |  2 +-
 .../azurecompute/xml/ListImagesHandlerTest.java |  4 +-
 azurecompute/src/test/resources/images.xml      |  1 +
 16 files changed, 47 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
index 22aa011..8b20634 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindDeploymentParamsToXmlPayload.java
@@ -18,12 +18,13 @@ package org.jclouds.azurecompute.binders;
 
 import static com.google.common.base.CaseFormat.UPPER_CAMEL;
 import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
+import static org.jclouds.azurecompute.domain.Image.OSType.LINUX;
 
 import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.domain.DeploymentParams;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.azurecompute.domain.InputEndpoint;
-import org.jclouds.azurecompute.domain.OSType;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.rest.Binder;
 
@@ -98,7 +99,7 @@ public class BindDeploymentParamsToXmlPayload implements Binder {
             .e("HostCaching").t("ReadWrite").up()
             .e("MediaLink").t(url(params)).up()
             .e("SourceImageName").t(params.getSourceImageName()).up()
-            .e("OS").t("Linux").up()
+            .e("OS").t(params.getOsType() == LINUX ? "Linux" : "Windows").up()
             .up() //OSVirtualHardDisk
             .e("RoleSize").t(UPPER_UNDERSCORE.to(UPPER_CAMEL, params.getSize().name())).up()
             .up() //Role

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindOSImageParamsToXmlPayload.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindOSImageParamsToXmlPayload.java b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindOSImageParamsToXmlPayload.java
index bbe0459..1c1ec1e 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindOSImageParamsToXmlPayload.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/binders/BindOSImageParamsToXmlPayload.java
@@ -16,13 +16,17 @@
  */
 package org.jclouds.azurecompute.binders;
 
-import com.google.common.base.Throwables;
-import com.jamesmurty.utils.XMLBuilder;
+import static com.google.common.base.Throwables.propagate;
+import static org.jclouds.azurecompute.domain.Image.OSType.LINUX;
+
 import javax.inject.Singleton;
+
 import org.jclouds.azurecompute.domain.ImageParams;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.rest.Binder;
 
+import com.jamesmurty.utils.XMLBuilder;
+
 @Singleton
 public class BindOSImageParamsToXmlPayload implements Binder {
 
@@ -31,16 +35,15 @@ public class BindOSImageParamsToXmlPayload implements Binder {
    public <R extends HttpRequest> R bindToRequest(R request, Object input) {
       ImageParams params = ImageParams.class.cast(input);
       try {
-         return (R) request.toBuilder().payload(XMLBuilder.create("OSImage").a("xmlns", "http://schemas.microsoft.com/windowsazure")
-                                                          .e("Label").t(params.getLabel()).up()
-                                                          .e("MediaLink").t(params.getMediaLink().toASCIIString()).up()
-                                                          .e("Name").t(params.getName()).up()
-                                                          .e("OS").t(params.getOS().toString()).up()
-                                                          .up().asString()).build();
+         String xml = XMLBuilder.create("OSImage", "http://schemas.microsoft.com/windowsazure")
+                                .e("Label").t(params.getLabel()).up()
+                                .e("MediaLink").t(params.getMediaLink().toASCIIString()).up()
+                                .e("Name").t(params.getName()).up()
+                                .e("OS").t(params.getOS() == LINUX ? "Linux" : "Windows").up()
+                                .up().asString();
+         return (R) request.toBuilder().payload(xml).build();
       } catch (Exception e) {
-         throw Throwables.propagate(e);
+         throw propagate(e);
       }
-
    }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
index 54325ae..914b34e 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/DeploymentParams.java
@@ -16,11 +16,14 @@
  */
 package org.jclouds.azurecompute.domain;
 
+import java.util.List;
+
+import org.jclouds.azurecompute.domain.Image.OSType;
+
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
-import java.util.List;
 
 /**
  * To create a new deployment/role

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java
index 6590330..26a16b6 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java
@@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.net.URI;
 
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.javax.annotation.Nullable;
 
 import com.google.common.base.Objects;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Image.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Image.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Image.java
index 8a1e373..d533c41 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Image.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Image.java
@@ -33,6 +33,9 @@ import com.google.common.base.Objects;
  * @see <a href="http://msdn.microsoft.com/en-us/library/jj157191" >api</a>
  */
 public final class Image {
+   public enum OSType {
+      LINUX, WINDOWS;
+   }
 
    public String name() {
       return name;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/domain/ImageParams.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/ImageParams.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/ImageParams.java
index 3de38a5..134c858 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/ImageParams.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/ImageParams.java
@@ -16,12 +16,15 @@
  */
 package org.jclouds.azurecompute.domain;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+
+import org.jclouds.azurecompute.domain.Image.OSType;
+
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Objects;
-import java.net.URI;
-
-import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * The Add OS Image operation adds an OS image that is currently stored in a storage account in your

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/domain/OSType.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/OSType.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/OSType.java
deleted file mode 100644
index c81b590..0000000
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/OSType.java
+++ /dev/null
@@ -1,45 +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.azurecompute.domain;
-
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public enum OSType {
-
-   LINUX,
-   WINDOWS,
-   UNRECOGNIZED;
-
-   public String value() {
-      return UPPER_UNDERSCORE.to(UPPER_CAMEL, name());
-   }
-
-   @Override
-   public String toString() {
-      return value();
-   }
-
-   public static OSType fromValue(String type) {
-      try {
-         return valueOf(UPPER_CAMEL.to(UPPER_UNDERSCORE, checkNotNull(type, "type")));
-      } catch (IllegalArgumentException e) {
-         return UNRECOGNIZED;
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java
index 0cc62c6..3792527 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java
@@ -22,7 +22,7 @@ import java.net.URI;
 
 import org.jclouds.azurecompute.domain.Disk;
 import org.jclouds.azurecompute.domain.Disk.Attachment;
-import org.jclouds.azurecompute.domain.OSType;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.http.functions.ParseSax;
 import org.xml.sax.Attributes;
 
@@ -45,8 +45,8 @@ final class DiskHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Di
    private final StringBuilder currentText = new StringBuilder();
 
    @Override public Disk getResult() {
-      Disk result = Disk.create(name, location, affinityGroup, description, os, mediaLink, logicalSizeInGB,
-            attachedTo, sourceImage);
+      Disk result = Disk.create(name, location, affinityGroup, description, os, mediaLink, logicalSizeInGB, attachedTo,
+            sourceImage);
       resetState(); // handler is called in a loop.
       return result;
    }
@@ -73,10 +73,8 @@ final class DiskHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Di
          attachmentHandler.endElement(ignoredUri, ignoredName, qName);
       } else if (qName.equals("OS")) {
          String osText = currentOrNull(currentText);
-         if (osText != null && osText.toUpperCase().equals("NULL")) {
-            os = null;
-         } else {
-            os = OSType.fromValue(currentOrNull(currentText));
+         if (osText != null) {
+            os = OSType.valueOf(currentOrNull(currentText).toUpperCase());
          }
       } else if (qName.equals("Name")) {
          name = currentOrNull(currentText);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java
index c53888d..f13dd5d 100644
--- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java
+++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/ImageHandler.java
@@ -23,7 +23,7 @@ import java.net.URI;
 import java.util.List;
 
 import org.jclouds.azurecompute.domain.Image;
-import org.jclouds.azurecompute.domain.OSType;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.http.functions.ParseSax;
 
 import com.google.common.base.Splitter;
@@ -64,7 +64,10 @@ final class ImageHandler extends ParseSax.HandlerForGeneratedRequestWithResult<I
 
    @Override public void endElement(String ignoredUri, String ignoredName, String qName) {
       if (qName.equals("OS")) {
-         os = OSType.fromValue(currentOrNull(currentText));
+         String osText = currentOrNull(currentText);
+         if (osText != null) {
+            os = OSType.valueOf(currentOrNull(currentText).toUpperCase());
+         }
       } else if (qName.equals("Name")) {
          name = currentOrNull(currentText);
       } else if (qName.equals("LogicalSizeInGB")) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
index 90f34a9..d31e699 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DeploymentApiMockTest.java
@@ -20,7 +20,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
 import org.jclouds.azurecompute.domain.DeploymentParams;
-import org.jclouds.azurecompute.domain.OSType;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.azurecompute.domain.RoleSize;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiMockTest;
 import org.jclouds.azurecompute.xml.DeploymentHandlerTest;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java
index 4e8caba..0f54641 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java
@@ -17,14 +17,12 @@
 package org.jclouds.azurecompute.features;
 
 import static com.google.common.collect.Iterables.transform;
-import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 import org.jclouds.azurecompute.domain.Disk;
 import org.jclouds.azurecompute.domain.Image;
 import org.jclouds.azurecompute.domain.Location;
-import org.jclouds.azurecompute.domain.OSType;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -64,7 +62,6 @@ public class DiskApiLiveTest extends BaseAzureComputeApiLiveTest {
    private void checkDisk(Disk disk) {
       assertNull(disk.name(), "Name cannot be null for: " + disk);
       assertNull(disk.os(), "OS cannot be null for: " + disk);
-      assertNotEquals(disk.os(), OSType.UNRECOGNIZED, "Status cannot be UNRECOGNIZED for: " + disk);
 
       if (disk.attachedTo() != null) {
          // TODO: verify you can lookup the role

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiLiveTest.java
index 71d4deb..c4b36e4 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiLiveTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiLiveTest.java
@@ -24,7 +24,6 @@ import static org.testng.Assert.assertTrue;
 
 import org.jclouds.azurecompute.domain.Image;
 import org.jclouds.azurecompute.domain.Location;
-import org.jclouds.azurecompute.domain.OSType;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiLiveTest;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -58,7 +57,6 @@ public class ImageApiLiveTest extends BaseAzureComputeApiLiveTest {
       assertNotNull(image.label(), "Label cannot be null for " + image);
       assertNotNull(image.name(), "Name cannot be null for " + image);
       assertNotNull(image.os(), "OS cannot be null for " + image);
-      assertNotEquals(image.os(), OSType.UNRECOGNIZED, "Status cannot be UNRECOGNIZED for " + image);
       assertTrue(image.logicalSizeInGB() > 0, "LogicalSizeInGB should be positive, if set" + image);
 
       if (image.category() != null) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiMockTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiMockTest.java
index be3d9d7..4e05102 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiMockTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/ImageApiMockTest.java
@@ -22,8 +22,8 @@ import static org.testng.Assert.assertTrue;
 
 import java.net.URI;
 
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.azurecompute.domain.ImageParams;
-import org.jclouds.azurecompute.domain.OSType;
 import org.jclouds.azurecompute.internal.BaseAzureComputeApiMockTest;
 import org.jclouds.azurecompute.xml.ListImagesHandlerTest;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListDisksHandlerTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListDisksHandlerTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListDisksHandlerTest.java
index f263567..320c405 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListDisksHandlerTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListDisksHandlerTest.java
@@ -24,7 +24,7 @@ import java.util.List;
 
 import org.jclouds.azurecompute.domain.Disk;
 import org.jclouds.azurecompute.domain.Disk.Attachment;
-import org.jclouds.azurecompute.domain.OSType;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.http.functions.BaseHandlerTest;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
index 823a6e2..b82c55b 100644
--- a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
+++ b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListImagesHandlerTest.java
@@ -24,7 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.jclouds.azurecompute.domain.Image;
-import org.jclouds.azurecompute.domain.OSType;
+import org.jclouds.azurecompute.domain.Image.OSType;
 import org.jclouds.http.functions.BaseHandlerTest;
 import org.testng.annotations.Test;
 
@@ -62,7 +62,7 @@ public class ListImagesHandlerTest extends BaseHandlerTest {
                   "Windows Server 2008 R2 is a multi-purpose server.", //description
                   "Microsoft", // category
                   OSType.WINDOWS, // os
-                  null, // mediaLink
+                  URI.create("http://blobs/disks/mydeployment/MSFT__Win2K8R2SP1-120612-1520-121206-01-en-us-30GB.vhd"), // mediaLink
                   30, // logicalSizeInGB
                   Collections.<String>emptyList() // eula
             ),

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9f8369cb/azurecompute/src/test/resources/images.xml
----------------------------------------------------------------------
diff --git a/azurecompute/src/test/resources/images.xml b/azurecompute/src/test/resources/images.xml
index e7b37d6..deaeae5 100644
--- a/azurecompute/src/test/resources/images.xml
+++ b/azurecompute/src/test/resources/images.xml
@@ -14,6 +14,7 @@
         <Label>Windows Server 2008 R2 SP1, June 2012</Label>
         <LogicalSizeInGB>30</LogicalSizeInGB>
         <Name>MSFT__Win2K8R2SP1-120612-1520-121206-01-en-us-30GB.vhd</Name>
+        <MediaLink>http://blobs/disks/mydeployment/MSFT__Win2K8R2SP1-120612-1520-121206-01-en-us-30GB.vhd</MediaLink>
         <OS>Windows</OS>
         <Eula />
         <Description>Windows Server 2008 R2 is a multi-purpose server.</Description>