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 <[email protected]> Authored: Mon Oct 20 13:45:15 2014 -0400 Committer: Adrian Cole <[email protected]> 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>
