diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java index ddb0223ebf..844cd47c65 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java @@ -25,6 +25,7 @@ package org.jclouds.vcloud; import static org.jclouds.vcloud.VCloudMediaType.CATALOGITEM_XML; import static org.jclouds.vcloud.VCloudMediaType.CATALOG_XML; +import static org.jclouds.vcloud.VCloudMediaType.NETWORK_XML; import static org.jclouds.vcloud.VCloudMediaType.TASKSLIST_XML; import static org.jclouds.vcloud.VCloudMediaType.TASK_XML; import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML; @@ -50,6 +51,7 @@ import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.CatalogItem; +import org.jclouds.vcloud.domain.Network; import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.TasksList; @@ -62,6 +64,7 @@ import org.jclouds.vcloud.functions.VAppTemplateIdToUri; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import org.jclouds.vcloud.xml.CatalogHandler; import org.jclouds.vcloud.xml.CatalogItemHandler; +import org.jclouds.vcloud.xml.NetworkHandler; import org.jclouds.vcloud.xml.OrgHandler; import org.jclouds.vcloud.xml.TaskHandler; import org.jclouds.vcloud.xml.TasksListHandler; @@ -107,10 +110,10 @@ public interface VCloudAsyncClient { @GET @Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class) - @Path("/vdc/{vDCId}") - @XMLResponseParser(VDCHandler.class) - @Consumes(VDC_XML) - Future getVDC(@PathParam("vDCId") String vDCId); + @Path("/network/{networkId}") + @Consumes(NETWORK_XML) + @XMLResponseParser(NetworkHandler.class) + Future getNetwork(@PathParam("networkId") String networkId); @GET @Endpoint(org.jclouds.vcloud.endpoints.VDC.class) @@ -118,6 +121,13 @@ public interface VCloudAsyncClient { @Consumes(VDC_XML) Future getDefaultVDC(); + @GET + @Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class) + @Path("/vdc/{vDCId}") + @XMLResponseParser(VDCHandler.class) + @Consumes(VDC_XML) + Future getVDC(@PathParam("vDCId") String vDCId); + @GET @Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class) @Path("/tasksList/{tasksListId}") diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java index 136479b519..8162584643 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.CatalogItem; +import org.jclouds.vcloud.domain.Network; import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.TasksList; @@ -57,6 +58,8 @@ public interface VCloudClient { VAppTemplate getVAppTemplate(String vAppTemplateId); + Network getNetwork(String networkId); + VDC getVDC(String vDCId); VDC getDefaultVDC(); diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java index 22cac0208d..3761376959 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java @@ -35,22 +35,22 @@ public class VCloudMediaType { * "application/vnd.vmware.vcloud.organizationList+xml" */ public final static String VCLOUD_XML = "application/vnd.vmware.vcloud.vcloud+xml"; - + /** * "application/vnd.vmware.vcloud.organizationList+xml" */ public final static MediaType VCLOUD_XML_TYPE = new MediaType("application", - "vnd.vmware.vcloud.vcloud+xml"); + "vnd.vmware.vcloud.vcloud+xml"); /** * "application/vnd.vmware.vcloud.organizationList+xml" */ public final static String ORGLIST_XML = "application/vnd.vmware.vcloud.organizationList+xml"; - + /** * "application/vnd.vmware.vcloud.organizationList+xml" */ public final static MediaType ORGLIST_XML_TYPE = new MediaType("application", - "vnd.vmware.vcloud.organizationList+xml"); + "vnd.vmware.vcloud.organizationList+xml"); /** * "application/vnd.vmware.vcloud.org+xml" */ @@ -120,7 +120,7 @@ public class VCloudMediaType { */ public final static MediaType VAPP_XML_TYPE = new MediaType("application", "vnd.vmware.vcloud.vApp+xml"); - + /** * "application/vnd.vmware.vcloud.vAppTemplate+xml" */ @@ -131,4 +131,14 @@ public class VCloudMediaType { public final static MediaType VAPPTEMPLATE_XML_TYPE = new MediaType("application", "vnd.vmware.vcloud.vAppTemplate+xml"); + /** + * "application/vnd.vmware.vcloud.network+xml" + */ + public final static String NETWORK_XML = "application/vnd.vmware.vcloud.network+xml"; + /** + * "application/vnd.vmware.vcloud.network+xml" + */ + public final static MediaType NETWORK_XML_TYPE = new MediaType("application", + "vnd.vmware.vcloud.network+xml"); + } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FenceMode.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FenceMode.java new file mode 100644 index 0000000000..4d87456ebd --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FenceMode.java @@ -0,0 +1,54 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.CaseFormat; + +/** + * + * The FenceMode specifies network constraints. + * + * @author Adrian Cole + */ +public enum FenceMode { + + BRIDGED, ISOLATED, BLOCK_IN_OUT, ALLOW_IN, ALLOW_IN_OUT, ALLOW_OUT; + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + + public static FenceMode fromValue(String fenceMode) { + return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(fenceMode, + "fenceMode"))); + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FirewallRule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FirewallRule.java new file mode 100644 index 0000000000..40db82155e --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/FirewallRule.java @@ -0,0 +1,113 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.InetAddress; + +import com.google.common.base.CaseFormat; + +/** + * @author Adrian Cole + */ +public class FirewallRule { + public static enum Policy { + DENY, ALLOW; + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + + public static Policy fromValue(String policy) { + return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(policy, + "policy"))); + } + + } + + public static enum Protocol { + TCP, UDP, ICMP; + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + + public static Protocol fromValue(String protocol) { + return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull( + protocol, "protocol"))); + } + + } + + private final Policy policy; + private final Protocol protocol; + private final InetAddress sourceIP; + private final String sourcePort; + + public FirewallRule(Policy policy, Protocol protocol, InetAddress sourceIP, String sourcePort) { + this.policy = policy; + this.protocol = protocol; + this.sourceIP = sourceIP; + this.sourcePort = sourcePort; + } + + /** + * One of deny, allow + */ + public Policy getPolicy() { + return policy; + } + + /** + * An attribute that specifies the protocol to which the rule applies. One of tcp, udp, icmp + */ + public Protocol getProtocol() { + return protocol; + } + + /** + * An IP address to which this rule applies + */ + public InetAddress getSourceIP() { + return sourceIP; + } + + /** + * An IP port or port range to which this rule applies. A value of * specifies all ports. + */ + public String getSourcePort() { + return sourcePort; + } +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/NatRule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/NatRule.java new file mode 100644 index 0000000000..939200295c --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/NatRule.java @@ -0,0 +1,124 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.domain; + +import java.net.InetAddress; + +/** + * Specifies a set of Network Address Translation rules using a pair of IP addresses and a pair of + * IP port numbers. + * + * @author Adrian Cole + */ +public class NatRule { + private final InetAddress externalIP; + private final Integer externalPort; + private final InetAddress internalIP; + private final Integer internalPort; + + public NatRule(InetAddress externalIP, Integer externalPort, InetAddress IntegerernalIP, Integer IntegerernalPort) { + this.externalIP = externalIP; + this.externalPort = externalPort; + this.internalIP = IntegerernalIP; + this.internalPort = IntegerernalPort; + } + + /** + * The externally‐visible IP address. + */ + public InetAddress getExternalIP() { + return externalIP; + } + + /** + * The externally‐visible IP port. + */ + public Integer getExternalPort() { + return externalPort; + } + + /** + * The Integerernally‐visible (non‐routable) IP address. + */ + public InetAddress getInternalIP() { + return internalIP; + } + + /** + * The Integerernally‐visible IP port. + */ + public Integer getInternalPort() { + return internalPort; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((externalIP == null) ? 0 : externalIP.hashCode()); + result = prime * result + ((externalPort == null) ? 0 : externalPort.hashCode()); + result = prime * result + ((internalIP == null) ? 0 : internalIP.hashCode()); + result = prime * result + ((internalPort == null) ? 0 : internalPort.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; + NatRule other = (NatRule) obj; + if (externalIP == null) { + if (other.externalIP != null) + return false; + } else if (!externalIP.equals(other.externalIP)) + return false; + if (externalPort == null) { + if (other.externalPort != null) + return false; + } else if (!externalPort.equals(other.externalPort)) + return false; + if (internalIP == null) { + if (other.internalIP != null) + return false; + } else if (!internalIP.equals(other.internalIP)) + return false; + if (internalPort == null) { + if (other.internalPort != null) + return false; + } else if (!internalPort.equals(other.internalPort)) + return false; + return true; + } + + @Override + public String toString() { + return "NatRule [externalIP=" + externalIP + ", externalPort=" + externalPort + + ", internalIP=" + internalIP + ", internalPort=" + internalPort + "]"; + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Network.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Network.java new file mode 100644 index 0000000000..ffe3362fc5 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Network.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.domain; + +import java.net.InetAddress; +import java.util.Set; + +import javax.annotation.Nullable; + +/** + * + * A network that is available in a vDC. + * + * @author Adrian Cole + */ +public interface Network extends NamedResource { + /** + * + * @return Description of the network + */ + String getDescription(); + + /** + * @return IP addresses of the network’s DNS servers. + */ + Set getDnsServers(); + + /** + * + * + * @return The IP address of the network’s primary gateway + */ + InetAddress getGateway(); + + /** + * * + * + * @return the network’s subnet mask + */ + InetAddress getNetmask(); + + /** + * return the network’s fence modes. + */ + Set getFenceModes(); + + /** + * return True if the network provides DHCP services + */ + @Nullable + Boolean isDhcp(); + + /** + * + * @return Network Address Translation rules for the network + */ + Set getNatRules(); + + /** + * @return Firewall rules for the network + */ + Set getFirewallRules(); + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/NetworkImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/NetworkImpl.java new file mode 100644 index 0000000000..dcb4e02b3d --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/NetworkImpl.java @@ -0,0 +1,212 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.domain.internal; + +import java.net.InetAddress; +import java.net.URI; +import java.util.Set; + +import org.jclouds.vcloud.VCloudMediaType; +import org.jclouds.vcloud.domain.FenceMode; +import org.jclouds.vcloud.domain.FirewallRule; +import org.jclouds.vcloud.domain.NamedResource; +import org.jclouds.vcloud.domain.NatRule; +import org.jclouds.vcloud.domain.Network; + +import com.google.common.collect.Sets; +import com.google.inject.internal.Nullable; + +/** + * Locations of resources in vCloud + * + * @author Adrian Cole + * + */ +public class NetworkImpl extends NamedResourceImpl implements Network { + + /** The serialVersionUID */ + private static final long serialVersionUID = 8464716396538298809L; + private final String description; + private final Set dnsServers = Sets.newHashSet(); + private final InetAddress gateway; + private final InetAddress netmask; + private final Set fenceModes = Sets.newHashSet(); + @Nullable + private final Boolean dhcp; + private final Set natRules = Sets.newHashSet(); + private final Set firewallRules = Sets.newHashSet(); + + public NetworkImpl(String id, String name, URI location, String description, + Set dnsServers, InetAddress gateway, InetAddress netmask, + Set fenceModes, Boolean dhcp, Set natRules, + Set firewallRules) { + super(id, name, VCloudMediaType.NETWORK_XML, location); + this.description = description; + this.dnsServers.addAll(dnsServers); + this.gateway = gateway; + this.netmask = netmask; + this.fenceModes.addAll(fenceModes); + this.dhcp = dhcp; + this.natRules.addAll(natRules); + this.firewallRules.addAll(firewallRules); + } + + /** + * {@inheritDoc} + */ + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + public Set getDnsServers() { + return dnsServers; + } + + /** + * {@inheritDoc} + */ + public InetAddress getGateway() { + return gateway; + } + + /** + * {@inheritDoc} + */ + public InetAddress getNetmask() { + return netmask; + } + + /** + * {@inheritDoc} + */ + public Set getFenceModes() { + return fenceModes; + } + + /** + * {@inheritDoc} + */ + public Boolean isDhcp() { + return dhcp; + } + + /** + * {@inheritDoc} + */ + public Set getNatRules() { + return natRules; + } + + /** + * {@inheritDoc} + */ + public Set getFirewallRules() { + return firewallRules; + } + + @Override + public int compareTo(NamedResource o) { + return (this == o) ? 0 : getId().compareTo(o.getId()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode()); + result = prime * result + ((dnsServers == null) ? 0 : dnsServers.hashCode()); + result = prime * result + ((fenceModes == null) ? 0 : fenceModes.hashCode()); + result = prime * result + ((firewallRules == null) ? 0 : firewallRules.hashCode()); + result = prime * result + ((gateway == null) ? 0 : gateway.hashCode()); + result = prime * result + ((natRules == null) ? 0 : natRules.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + NetworkImpl other = (NetworkImpl) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (dhcp == null) { + if (other.dhcp != null) + return false; + } else if (!dhcp.equals(other.dhcp)) + return false; + if (dnsServers == null) { + if (other.dnsServers != null) + return false; + } else if (!dnsServers.equals(other.dnsServers)) + return false; + if (fenceModes == null) { + if (other.fenceModes != null) + return false; + } else if (!fenceModes.equals(other.fenceModes)) + return false; + if (firewallRules == null) { + if (other.firewallRules != null) + return false; + } else if (!firewallRules.equals(other.firewallRules)) + return false; + if (gateway == null) { + if (other.gateway != null) + return false; + } else if (!gateway.equals(other.gateway)) + return false; + if (natRules == null) { + if (other.natRules != null) + return false; + } else if (!natRules.equals(other.natRules)) + return false; + if (netmask == null) { + if (other.netmask != null) + return false; + } else if (!netmask.equals(other.netmask)) + return false; + return true; + } + + @Override + public String toString() { + return "NetworkImpl [id=" + getId() + ", location=" + getLocation() + ", name=" + getName() + + ", type=" + getType() + ", description=" + description + ", dhcp=" + dhcp + + ", dnsServers=" + dnsServers + ", fenceModes=" + fenceModes + ", firewallRules=" + + firewallRules + ", gateway=" + gateway + ", natRules=" + natRules + ", netmask=" + + netmask + "]"; + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/NetworkHandler.java b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/NetworkHandler.java new file mode 100644 index 0000000000..4f0d162177 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/NetworkHandler.java @@ -0,0 +1,161 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.xml; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Set; + +import javax.annotation.Resource; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.logging.Logger; +import org.jclouds.vcloud.domain.FenceMode; +import org.jclouds.vcloud.domain.FirewallRule; +import org.jclouds.vcloud.domain.NamedResource; +import org.jclouds.vcloud.domain.NatRule; +import org.jclouds.vcloud.domain.Network; +import org.jclouds.vcloud.domain.FirewallRule.Policy; +import org.jclouds.vcloud.domain.FirewallRule.Protocol; +import org.jclouds.vcloud.domain.internal.NetworkImpl; +import org.jclouds.vcloud.util.Utils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import com.google.common.collect.Sets; + +/** + * @author Adrian Cole + */ +public class NetworkHandler extends ParseSax.HandlerWithResult { + + @Resource + protected Logger logger = Logger.NULL; + + private StringBuilder currentText = new StringBuilder(); + + private NamedResource network; + + private String description; + + private Set dnsServers = Sets.newHashSet(); + private InetAddress gateway; + private InetAddress netmask; + private Set fenceModes = Sets.newHashSet(); + private Boolean dhcp; + private Set natRules = Sets.newHashSet(); + private Set firewallRules = Sets.newHashSet(); + + private InetAddress externalIP; + private Integer externalPort; + private InetAddress internalIP; + private Integer internalPort; + + private Policy policy; + private Protocol protocol; + private InetAddress sourceIP; + private String sourcePort; + + public Network getResult() { + return new NetworkImpl(network.getId(), network.getName(), network.getLocation(), + description, dnsServers, gateway, netmask, fenceModes, dhcp, natRules, firewallRules); + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + if (qName.equals("Network")) { + network = Utils.newNamedResource(attributes); + } + } + + public void endElement(String uri, String name, String qName) { + if (qName.equals("Description")) { + description = currentOrNull(); + } else if (qName.equals("Dns")) { + dnsServers.add(parseInetAddress(currentOrNull())); + } else if (qName.equals("Gateway")) { + gateway = parseInetAddress(currentOrNull()); + } else if (qName.equals("Netmask")) { + netmask = parseInetAddress(currentOrNull()); + } else if (qName.equals("FenceMode")) { + fenceModes.add(FenceMode.fromValue(currentOrNull())); + } else if (qName.equals("Dhcp")) { + dhcp = new Boolean(currentOrNull()); + } else if (qName.equals("NatRule")) { + natRules.add(new NatRule(externalIP, externalPort, internalIP, internalPort)); + externalIP = null; + externalPort = null; + internalIP = null; + internalPort = null; + } else if (qName.equals("ExternalIP")) { + externalIP = parseInetAddress(currentOrNull()); + } else if (qName.equals("ExternalPort")) { + externalPort = Integer.parseInt(currentOrNull()); + } else if (qName.equals("InternalIP")) { + internalIP = parseInetAddress(currentOrNull()); + } else if (qName.equals("InternalPort")) { + internalPort = Integer.parseInt(currentOrNull()); + } else if (qName.equals("FirewallRule")) { + firewallRules.add(new FirewallRule(policy, protocol, sourceIP, sourcePort)); + policy = null; + protocol = null; + sourceIP = null; + sourcePort = null; + } else if (qName.equals("Policy")) { + policy = Policy.fromValue(currentOrNull()); + } else if (qName.equals("Policy")) { + protocol = Protocol.fromValue(currentOrNull()); + } else if (qName.equals("SourceIp")) { + sourceIP = parseInetAddress(currentOrNull()); + } else if (qName.equals("SourcePort")) { + sourcePort = currentOrNull(); + } + + currentText = new StringBuilder(); + } + + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + + protected String currentOrNull() { + String returnVal = currentText.toString().trim(); + return returnVal.equals("") ? null : returnVal; + } + + private InetAddress parseInetAddress(String string) { + String[] byteStrings = string.split("\\."); + byte[] bytes = new byte[4]; + for (int i = 0; i < 4; i++) { + bytes[i] = (byte) Integer.parseInt(byteStrings[i]); + } + try { + return InetAddress.getByAddress(bytes); + } catch (UnknownHostException e) { + logger.warn(e, "error parsing ipAddress", currentText); + } + return null; + } +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java index 454c0eadc6..c842f56139 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java @@ -56,6 +56,7 @@ import org.jclouds.vcloud.filters.SetVCloudTokenCookie; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import org.jclouds.vcloud.xml.CatalogHandler; import org.jclouds.vcloud.xml.CatalogItemHandler; +import org.jclouds.vcloud.xml.NetworkHandler; import org.jclouds.vcloud.xml.OrgHandler; import org.jclouds.vcloud.xml.TaskHandler; import org.jclouds.vcloud.xml.TasksListHandler; @@ -105,8 +106,8 @@ public class VCloudAsyncClientTest extends RestClientTest { String.class, String.class, String.class, Array.newInstance( InstantiateVAppTemplateOptions.class, 0).getClass()); GeneratedHttpRequest httpMethod = processor.createRequest(method, "1", - "CentOS 01", 3 + "", processorCount(1).memory(512).disk(1024) - .inNetwork(URI.create("https://vcloud.safesecureweb.com/network/1990"))); + "CentOS 01", 3 + "", processorCount(1).memory(512).disk(1024).inNetwork( + URI.create("https://vcloud.safesecureweb.com/network/1990"))); assertRequestLineEquals(httpMethod, "POST http://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); @@ -153,6 +154,21 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(httpMethod); } + public void testNetwork() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("getNetwork", String.class); + GeneratedHttpRequest httpMethod = processor.createRequest(method, "2"); + + assertRequestLineEquals(httpMethod, "GET http://vcloud/network/2 HTTP/1.1"); + assertHeadersEqual(httpMethod, "Accept: application/vnd.vmware.vcloud.network+xml\n"); + assertPayloadEquals(httpMethod, null); + + assertResponseParserClassEquals(method, httpMethod, ParseSax.class); + assertSaxResponseParserClassEquals(method, NetworkHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpMethod); + } + public void testCatalogItem() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalogItem", String.class); GeneratedHttpRequest httpMethod = processor.createRequest(method, "2"); diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java index af97db60a3..28c70526f9 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java @@ -33,6 +33,7 @@ import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.CatalogItem; import org.jclouds.vcloud.domain.NamedResource; +import org.jclouds.vcloud.domain.Network; import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; @@ -72,7 +73,18 @@ public class VCloudClientLiveTest { assert response.size() > 0; } - @Test(enabled = true) + @Test + public void testGetNetwork() throws Exception { + VDC response = connection.getDefaultVDC(); + for (NamedResource resource : response.getAvailableNetworks().values()) { + if (resource.getType().equals(VCloudMediaType.NETWORK_XML)) { + Network item = connection.getNetwork(resource.getId()); + assertNotNull(item); + } + } + } + + @Test public void testGetCatalogItem() throws Exception { Catalog response = connection.getCatalog(); for (NamedResource resource : response.values()) { @@ -88,7 +100,7 @@ public class VCloudClientLiveTest { } } - @Test(enabled = true) + @Test public void testGetVAppTemplate() throws Exception { Catalog response = connection.getCatalog(); for (NamedResource resource : response.values()) { @@ -133,7 +145,7 @@ public class VCloudClientLiveTest { assertEquals(connection.getTask(task.getId()).getLocation(), task.getLocation()); } - @Test(enabled = true) + @Test public void testGetVApp() throws Exception { VDC response = connection.getDefaultVDC(); for (NamedResource item : response.getResourceEntities().values()) { diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/xml/NetworkHandlerTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/NetworkHandlerTest.java new file mode 100644 index 0000000000..62db7c7f65 --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/NetworkHandlerTest.java @@ -0,0 +1,86 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.Factory; +import org.jclouds.http.functions.config.ParserModule; +import org.jclouds.vcloud.domain.FenceMode; +import org.jclouds.vcloud.domain.FirewallRule; +import org.jclouds.vcloud.domain.NatRule; +import org.jclouds.vcloud.domain.Network; +import org.jclouds.vcloud.domain.internal.NetworkImpl; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Tests behavior of {@code NetworkHandler} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "vcloud.NetworkHandlerTest") +public class NetworkHandlerTest { + + private Injector injector; + + private Factory factory; + + public void testTerremark() throws UnknownHostException { + InputStream is = getClass().getResourceAsStream("/network-terremark.xml"); + injector = Guice.createInjector(new ParserModule()); + factory = injector.getInstance(ParseSax.Factory.class); + Network result = factory.create(injector.getInstance(NetworkHandler.class)).parse(is); + assertEquals(result, new NetworkImpl("1708", "10.114.34.128/26", URI + .create("https://services.vcloudexpress.terremark.com/api/v0.8/network/1708"), null, + ImmutableSet. of(), InetAddress.getByName("10.114.34.129"), InetAddress + .getByName("255.255.255.192"), ImmutableSet + . of(FenceMode.ISOLATED), null, ImmutableSet. of(), + ImmutableSet. of())); + } + + public void testHosting() throws UnknownHostException { + InputStream is = getClass().getResourceAsStream("/network-hosting.xml"); + injector = Guice.createInjector(new ParserModule()); + factory = injector.getInstance(ParseSax.Factory.class); + Network result = (Network) factory.create(injector.getInstance(NetworkHandler.class)).parse( + is); + assertEquals(result, new NetworkImpl("1183", "188849 trust", URI + .create("https://vcloud.safesecureweb.com/api/v0.8/network/1183"), "188849 trust", + ImmutableSet. of(InetAddress.getByName("76.12.32.110"), InetAddress + .getByName("208.112.89.187")), InetAddress.getByName("204.12.53.89"), + InetAddress.getByName("255.255.255.248"), ImmutableSet. of(), null, + ImmutableSet. of(), ImmutableSet. of())); + } + +} diff --git a/vcloud/core/src/test/resources/network-hosting.xml b/vcloud/core/src/test/resources/network-hosting.xml new file mode 100644 index 0000000000..20fc2f1ef4 --- /dev/null +++ b/vcloud/core/src/test/resources/network-hosting.xml @@ -0,0 +1,16 @@ + + + + 188849 trust + + + 76.12.32.110 + 208.112.89.187 + 204.12.53.89 + 255.255.255.248 + + \ No newline at end of file diff --git a/vcloud/core/src/test/resources/network-terremark.xml b/vcloud/core/src/test/resources/network-terremark.xml new file mode 100644 index 0000000000..df465f2943 --- /dev/null +++ b/vcloud/core/src/test/resources/network-terremark.xml @@ -0,0 +1,10 @@ + + + + 10.114.34.129 + 255.255.255.192 + + + isolated + + \ No newline at end of file diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java index 94f4accf6c..a962582ba7 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java @@ -105,8 +105,8 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest { for (NamedResource resource : response.values()) { if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) { CatalogItem item = connection.getCatalogItem(resource.getId()); - SortedSet options = tmClient - .getComputeOptionsOfCatalogItem(item.getId()); + SortedSet options = tmClient.getComputeOptionsOfCatalogItem(item + .getId()); assert options.size() == 32 || options.size() == 20 : item.getId() + ": " + options.size(); assert tmClient.getCustomizationOptionsOfCatalogItem(item.getId()) != null;