From 40df188c10afceb2b38f07b5830a66bc84a308e5 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 09:26:34 +0000 Subject: [PATCH 1/7] Issue 695: Fix assignment --- .../enterprisecloud/domain/network/AssignedIpAddresses.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/AssignedIpAddresses.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/AssignedIpAddresses.java index 83c3f4a9d3..724e21c102 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/AssignedIpAddresses.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/AssignedIpAddresses.java @@ -41,7 +41,7 @@ public class AssignedIpAddresses extends Resource { public AssignedIpAddresses(URI href, String type, String name, Actions actions, DeviceNetworks networks) { super(href, type, name, Sets.newIdentityHashSet(), actions.getActions()); - checkNotNull(networks,"networks"); + this.networks = checkNotNull(networks,"networks"); } public AssignedIpAddresses() { From a756462bc9fac5d389b74578f4f90b26a6e70179 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 10:58:20 +0000 Subject: [PATCH 2/7] Issue 695: Added rest of NetworkReference object graph+services+tests. Also Networks wrapper. NetworkReference data needed when creating a VM from a template. --- .../TerremarkEnterpriseCloudAsyncClient.java | 6 + .../TerremarkEnterpriseCloudClient.java | 6 + ...remarkEnterpriseCloudRestClientModule.java | 1 + .../domain/network/IpAddress.java | 221 +++++++++++++++++ .../domain/network/IpAddresses.java | 105 ++++++++ .../domain/network/NetworkReference.java | 140 ++++++++++- .../domain/network/Networks.java | 182 ++++++++++++++ .../features/NetworkAsyncClient.java | 63 +++++ .../features/NetworkClient.java | 60 +++++ .../domain/network/NicsTest.java | 2 +- .../features/NetworkClientLiveTest.java | 61 +++++ .../xml/NetworksJAXBParsingTest.java | 156 ++++++++++++ .../src/test/resources/network.xml | 224 ++++++++++++++++++ .../src/test/resources/networks.xml | 16 ++ 14 files changed, 1232 insertions(+), 11 deletions(-) create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddress.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddresses.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkAsyncClient.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClient.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClientLiveTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/resources/network.xml create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/resources/networks.xml diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java index a94a18b70a..b2cefa6521 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java @@ -39,6 +39,12 @@ public interface TerremarkEnterpriseCloudAsyncClient { @Delegate LocationAsyncClient getLocationClient(); + /** + * Provides asynchronous access to Network features. + */ + @Delegate + NetworkAsyncClient getNetworkClient(); + /** * Provides asynchronous access to Resource features. */ diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java index 620a6bf925..e34bbd4469 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java @@ -49,6 +49,12 @@ public interface TerremarkEnterpriseCloudClient { @Delegate ResourceClient getResourceClient(); + /** + * Provides synchronous access to Network features. + */ + @Delegate + NetworkClient getNetworkClient(); + /** * Provides synchronous access to Task features. */ diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java index 2aad56db69..7cc37e56cb 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java @@ -48,6 +48,7 @@ public class TerremarkEnterpriseCloudRestClientModule extends public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() .put(LocationClient.class, LocationAsyncClient.class) + .put(NetworkClient.class, NetworkAsyncClient.class) .put(ResourceClient.class, ResourceAsyncClient.class) .put(TaskClient.class, TaskAsyncClient.class) .put(VirtualMachineClient.class, VirtualMachineAsyncClient.class) diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddress.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddress.java new file mode 100644 index 0000000000..6fdc732ba7 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddress.java @@ -0,0 +1,221 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.network; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.NamedResource; +import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource; +import org.jclouds.tmrk.enterprisecloud.domain.internal.Resource; + +import javax.xml.bind.annotation.XmlElement; +import java.net.URI; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Jason King + */ +public class IpAddress extends Resource { + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder toBuilder() { + return new Builder().fromIpAddress(this); + } + + public static class Builder extends Resource.Builder { + private NamedResource host; + private NamedResource detectedOn; + private NamedResource rnatAddress; + + /** + * @see IpAddress#getHost + */ + public Builder host(NamedResource host) { + this.host = host; + return this; + } + + /** + * @see IpAddress#getDetectedOn + */ + public Builder detectedOn(NamedResource detectedOn) { + this.detectedOn = detectedOn; + return this; + } + + /** + * @see IpAddress#getRnatAddress + */ + public Builder rnatAddress(NamedResource rnatAddress) { + this.rnatAddress = rnatAddress; + return this; + } + + @Override + public IpAddress build() { + return new IpAddress(href, type, name, links, actions, host, detectedOn, rnatAddress); + } + + public Builder fromIpAddress(IpAddress in) { + return fromResource(in).host(in.getHost()).detectedOn(in.getDetectedOn()).rnatAddress(in.getRnatAddress()); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromBaseResource(BaseResource in) { + return Builder.class.cast(super.fromBaseResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromResource(Resource in) { + return Builder.class.cast(super.fromResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(String type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder href(URI href) { + return Builder.class.cast(super.href(href)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder links(Set links) { + return Builder.class.cast(super.links(links)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder actions(Set actions) { + return Builder.class.cast(super.actions(actions)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromAttributes(Map attributes) { + return Builder.class.cast(super.fromAttributes(attributes)); + } + + } + + @XmlElement(name = "Host", required = false) + private NamedResource host; + + @XmlElement(name = "DetectedOn", required = false) + private NamedResource detectedOn; + + @XmlElement(name = "RnatAddress", required = false) + private NamedResource rnatAddress; + + private IpAddress(URI href, String type, String name, Set links,Set actions, + @Nullable NamedResource host,@Nullable NamedResource detectedOn,@Nullable NamedResource rnatAddress) { + super(href, type, name, links, actions); + this.host = host; + this.detectedOn = detectedOn; + this.rnatAddress = rnatAddress; + } + + private IpAddress() { + //For JAXB + } + + public NamedResource getHost() { + return host; + } + + public NamedResource getDetectedOn() { + return detectedOn; + } + + public NamedResource getRnatAddress() { + return rnatAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IpAddress ipAddress = (IpAddress) o; + + if (detectedOn != null ? !detectedOn.equals(ipAddress.detectedOn) : ipAddress.detectedOn != null) + return false; + if (host != null ? !host.equals(ipAddress.host) : ipAddress.host != null) + return false; + if (rnatAddress != null ? !rnatAddress.equals(ipAddress.rnatAddress) : ipAddress.rnatAddress != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (host != null ? host.hashCode() : 0); + result = 31 * result + (detectedOn != null ? detectedOn.hashCode() : 0); + result = 31 * result + (rnatAddress != null ? rnatAddress.hashCode() : 0); + return result; + } + + @Override + public String string() { + return super.string()+", host="+host+", detectedOn="+detectedOn+", rnatAddress="+rnatAddress; + } + +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddresses.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddresses.java new file mode 100644 index 0000000000..c25b512782 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/IpAddresses.java @@ -0,0 +1,105 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.network; + +import com.google.common.collect.Sets; + +import javax.xml.bind.annotation.XmlElement; +import java.util.Collections; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * + * @author Jason King + */ +public class IpAddresses { + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().fromIpAddresses(this); + } + + public static class Builder { + + private Set addresses = Sets.newLinkedHashSet(); + + /** + * @see org.jclouds.tmrk.enterprisecloud.domain.network.IpAddresses#getIpAddresses + */ + public Builder addresses(Set addresses) { + this.addresses = Sets.newLinkedHashSet(checkNotNull(addresses, "addresses")); + return this; + } + + public Builder addIpAddress(IpAddress address) { + addresses.add(checkNotNull(address, "address")); + return this; + } + + public IpAddresses build() { + return new IpAddresses(addresses); + } + + public Builder fromIpAddresses(IpAddresses in) { + return addresses(in.getIpAddresses()); + } + } + + private IpAddresses() { + //For JAXB and builder use + } + + private IpAddresses(Set addresses) { + this.addresses = Sets.newLinkedHashSet(addresses); + } + + @XmlElement(name = "IpAddress") + private Set addresses = Sets.newLinkedHashSet(); + + public Set getIpAddresses() { + return Collections.unmodifiableSet(addresses); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IpAddresses that = (IpAddresses) o; + + if (!addresses.equals(that.addresses)) return false; + + return true; + } + + @Override + public int hashCode() { + return addresses.hashCode(); + } + + public String toString() { + return "["+ addresses.toString()+"]"; + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/NetworkReference.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/NetworkReference.java index 5102392b49..be010907c1 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/NetworkReference.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/NetworkReference.java @@ -19,26 +19,27 @@ package org.jclouds.tmrk.enterprisecloud.domain.network; import org.jclouds.javax.annotation.Nullable; -import org.jclouds.tmrk.enterprisecloud.domain.Action; -import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.NamedResource; import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseNamedResource; import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; +import javax.xml.bind.annotation.XmlRootElement; import java.net.URI; import java.util.Map; -import java.util.Set; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; +import static com.google.common.base.Preconditions.checkNotNull; /** * * @author Jason King * */ +@XmlRootElement(name = "Network") public class NetworkReference extends BaseNamedResource { @XmlEnum public static enum NetworkType { @@ -74,8 +75,21 @@ public class NetworkReference extends BaseNamedResource { public static class Builder extends BaseNamedResource.Builder { + private String address; private NetworkType networkType; - + private String broadcastAddress; + private String gatewayAddress; + private NamedResource rnatAddress; + private IpAddresses ipAddresses; + + /** + * @see NetworkReference#getAddress + */ + public Builder address(String address) { + this.address = address; + return this; + } + /** * @see NetworkReference#getNetworkType */ @@ -84,9 +98,41 @@ public class NetworkReference extends BaseNamedResource { return this; } + /** + * @see NetworkReference#getBroadcastAddress + */ + public Builder broadcastAddress(String broadcastAddress) { + this.broadcastAddress = broadcastAddress; + return this; + } + + /** + * @see NetworkReference#getGatewayAddress + */ + public Builder gatewayAddress(String gatewayAddress) { + this.gatewayAddress = gatewayAddress; + return this; + } + + /** + * @see NetworkReference#getRnatAddress + */ + public Builder rnatAddress(NamedResource rnatAddress) { + this.rnatAddress = rnatAddress; + return this; + } + + /** + * @see NetworkReference#getIpAddresses + */ + public Builder gatewayAddress(IpAddresses ipAddresses) { + this.ipAddresses = ipAddresses; + return this; + } + @Override public NetworkReference build() { - return new NetworkReference(href, type, name, networkType); + return new NetworkReference(href, type, name, address, networkType, broadcastAddress, gatewayAddress, rnatAddress, ipAddresses); } public Builder fromNetworkReference(NetworkReference in) { @@ -142,26 +188,100 @@ public class NetworkReference extends BaseNamedResource { } } - @XmlElement(name = "NetworkType") + @XmlElement(name = "Address", required = false) + private String address; + + @XmlElement(name = "NetworkType", required = true) private NetworkType networkType; - private NetworkReference(URI href, String type, String name,@Nullable NetworkType networkType) { + @XmlElement(name = "BroadcastAddress", required = false) + private String broadcastAddress; + + @XmlElement(name = "GatewayAddress", required = false) + private String gatewayAddress; + + @XmlElement(name = "RnatAddress", required = false) + private NamedResource rnatAddress; + + @XmlElement(name = "IpAddresses", required = false) + private IpAddresses ipAddresses; + + private NetworkReference(URI href, String type, String name,@Nullable String address, NetworkType networkType, + @Nullable String broadcastAddress, @Nullable String gatewayAddress, @Nullable NamedResource rnatAddress, @Nullable IpAddresses ipAddresses) { super(href, type, name); - this.networkType = networkType; + this.address = address; + this.networkType = checkNotNull(networkType,"networkType"); + this.broadcastAddress = broadcastAddress; + this.gatewayAddress = gatewayAddress; + this.rnatAddress = rnatAddress; + this.ipAddresses = ipAddresses; } private NetworkReference() { //For JAXB } - @Nullable + public String getAddress() { + return address; + } + public NetworkType getNetworkType() { return networkType; } + public String getBroadcastAddress() { + return broadcastAddress; + } + + public String getGatewayAddress() { + return gatewayAddress; + } + + public NamedResource getRnatAddress() { + return rnatAddress; + } + + public IpAddresses getIpAddresses() { + return ipAddresses; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + NetworkReference that = (NetworkReference) o; + + if (address != null ? !address.equals(that.address) : that.address != null) + return false; + if (broadcastAddress != null ? !broadcastAddress.equals(that.broadcastAddress) : that.broadcastAddress != null) + return false; + if (gatewayAddress != null ? !gatewayAddress.equals(that.gatewayAddress) : that.gatewayAddress != null) + return false; + if (ipAddresses != null ? !ipAddresses.equals(that.ipAddresses) : that.ipAddresses != null) + return false; + if (networkType != that.networkType) return false; + if (rnatAddress != null ? !rnatAddress.equals(that.rnatAddress) : that.rnatAddress != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + networkType.hashCode(); + result = 31 * result + (broadcastAddress != null ? broadcastAddress.hashCode() : 0); + result = 31 * result + (gatewayAddress != null ? gatewayAddress.hashCode() : 0); + result = 31 * result + (rnatAddress != null ? rnatAddress.hashCode() : 0); + result = 31 * result + (ipAddresses != null ? ipAddresses.hashCode() : 0); + return result; + } @Override public String string() { - return super.string()+", networkType="+networkType; + return super.string()+", address="+address+", networkType="+networkType+", broadcastAddress="+broadcastAddress+", gatewayAddress="+gatewayAddress+", rnatAddress="+rnatAddress+", ipAddresses="+ipAddresses; } } \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java new file mode 100644 index 0000000000..c436a1dfe2 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java @@ -0,0 +1,182 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.network; + +import com.google.common.collect.Sets; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource; +import org.jclouds.tmrk.enterprisecloud.domain.internal.Resource; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Networks is more than a simple wrapper as it extends BaseResource. + * @author Jason King + * + */ +@XmlRootElement(name = "Networks") +public class Networks extends Resource { + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder toBuilder() { + return new Builder().fromTemplates(this); + } + + public static class Builder extends Resource.Builder { + private Set networks = Sets.newLinkedHashSet(); + + /** + * @see Networks#getNetworks + */ + public Builder networks(Set networks) { + this.networks =(checkNotNull(networks,"networks")); + return this; + } + + @Override + public Networks build() { + return new Networks(href, type, name, links, actions, networks); + } + + public Builder fromTemplates(Networks in) { + return fromResource(in).networks(in.getNetworks()); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromBaseResource(BaseResource in) { + return Builder.class.cast(super.fromBaseResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromResource(Resource in) { + return Builder.class.cast(super.fromResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(String type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder href(URI href) { + return Builder.class.cast(super.href(href)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder links(Set links) { + return Builder.class.cast(super.links(links)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder actions(Set actions) { + return Builder.class.cast(super.actions(actions)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromAttributes(Map attributes) { + return Builder.class.cast(super.fromAttributes(attributes)); + } + + } + + @XmlElement(name = "Network", required = false) + private Set networks = Sets.newLinkedHashSet(); + + private Networks(URI href, String type, String name, Set links, Set actions, Set networks) { + super(href, type, name, links, actions); + this.networks = checkNotNull(networks,"networks"); + } + + private Networks() { + //For JAXB + } + + public Set getNetworks() { + return networks; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Networks networks1 = (Networks) o; + + if (!networks.equals(networks1.networks)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + networks.hashCode(); + return result; + } + + @Override + public String string() { + return super.string()+", networks="+networks; + } +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkAsyncClient.java new file mode 100644 index 0000000000..7de6b01f58 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkAsyncClient.java @@ -0,0 +1,63 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import com.google.common.util.concurrent.ListenableFuture; +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.rest.annotations.*; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.tmrk.enterprisecloud.domain.network.NetworkReference; +import org.jclouds.tmrk.enterprisecloud.domain.network.Networks; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import java.net.URI; + +/** + * Provides asynchronous access to various Networks via their REST API. + *

+ * + * @see org.jclouds.tmrk.enterprisecloud.features.NetworkClient + * @see + * @author Jason King + */ +@RequestFilters(BasicAuthentication.class) +@Headers(keys = "x-tmrk-version", values = "{jclouds.api-version}") +public interface NetworkAsyncClient { + + /** + * @see org.jclouds.tmrk.enterprisecloud.features.NetworkClient#getNetworks + */ + @GET + @Consumes("application/vnd.tmrk.cloud.network; type=collection") + @JAXBResponseParser + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + public ListenableFuture getNetworks(@EndpointParam URI uri); + + /** + * @see org.jclouds.tmrk.enterprisecloud.features.NetworkClient#getNetwork + */ + @GET + @Consumes("application/vnd.tmrk.cloud.network") + @JAXBResponseParser + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + public ListenableFuture getNetwork(@EndpointParam URI uri); +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClient.java new file mode 100644 index 0000000000..1403874734 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClient.java @@ -0,0 +1,60 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.tmrk.enterprisecloud.domain.network.NetworkReference; +import org.jclouds.tmrk.enterprisecloud.domain.network.Networks; + +import java.net.URI; +import java.util.concurrent.TimeUnit; + +/** + * Provides synchronous access to various Resources. + *

+ * + * @see org.jclouds.tmrk.enterprisecloud.features.NetworkAsyncClient + * @see + * @author Jason King + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface NetworkClient { + + /** + * The Get Networks call returns information regarding networks in an environment. + + * @param uri the uri of the call based upon the environment + * e.g. /cloudapi/ecloud/networks/environments/{id} + * @return the Networks + */ + public Networks getNetworks(URI uri); + + /** + * The Get Networks by ID call returns information regarding the usage of all + * IP addresses on a specified network defined in an environment. + + * @param uri the uri of the call based upon the network + * e.g. /cloudapi/ecloud/networks/{id} + * @return the NetworkReference + */ + public NetworkReference getNetwork(URI uri); + +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/domain/network/NicsTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/domain/network/NicsTest.java index 23319de659..968e88b82c 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/domain/network/NicsTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/domain/network/NicsTest.java @@ -40,7 +40,7 @@ public class NicsTest { @BeforeMethod() public void setUp() throws URISyntaxException { - networkReference = NetworkReference.builder().href(new URI("/netref")).type("a network ref").name("my network ref").build(); + networkReference = NetworkReference.builder().href(new URI("/netref")).type("a network ref").name("my network ref").networkType(NetworkReference.NetworkType.INTERNAL).build(); nic = VirtualNic.builder().macAddress("aa:bb").name("my nic").network(networkReference).unitNumber(1).build(); nics = Nics.builder().addVirtualNic(nic).build(); } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClientLiveTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClientLiveTest.java new file mode 100644 index 0000000000..321cc1f950 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/NetworkClientLiveTest.java @@ -0,0 +1,61 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import org.jclouds.tmrk.enterprisecloud.domain.network.NetworkReference; +import org.jclouds.tmrk.enterprisecloud.domain.network.Networks; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import java.net.URI; + +import static org.testng.Assert.assertNotNull; + +/** + * Tests behavior of {@code NetworkClient} + * + * @author Jason King + */ +@Test(groups = "live", testName = "NetworkClientLiveTest") +public class NetworkClientLiveTest extends BaseTerremarkEnterpriseCloudClientLiveTest { + @BeforeGroups(groups = { "live" }) + public void setupClient() { + super.setupClient(); + client = context.getApi().getNetworkClient(); + } + + private NetworkClient client; + + public void testGetNetworks() throws Exception { + Networks networks = client.getNetworks(URI.create("/cloudapi/ecloud/networks/environments/77")); + assertNotNull(networks); + for(NetworkReference network: networks.getNetworks()) { + testGetNetwork(network.getHref()); + } + } + + private void testGetNetwork(URI uri) throws Exception { + NetworkReference network = client.getNetwork(uri); + assertNotNull(network); + assertNotNull(network.getAddress()); + assertNotNull(network.getNetworkType()); + assertNotNull(network.getBroadcastAddress()); + assertNotNull(network.getGatewayAddress()); + } +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java new file mode 100644 index 0000000000..e0831f991b --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java @@ -0,0 +1,156 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.xml; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import org.jclouds.crypto.Crypto; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseXMLWithJAXB; +import org.jclouds.logging.config.NullLoggingModule; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.BaseRestClientTest; +import org.jclouds.rest.RestContextSpec; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.tmrk.enterprisecloud.domain.NamedResource; +import org.jclouds.tmrk.enterprisecloud.domain.network.IpAddress; +import org.jclouds.tmrk.enterprisecloud.domain.network.NetworkReference; +import org.jclouds.tmrk.enterprisecloud.domain.network.Networks; +import org.jclouds.tmrk.enterprisecloud.features.LocationAsyncClient; +import org.jclouds.tmrk.enterprisecloud.features.NetworkAsyncClient; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import javax.inject.Named; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.Set; + +import static org.jclouds.io.Payloads.newInputStreamPayload; +import static org.jclouds.rest.RestContextFactory.contextSpec; +import static org.jclouds.rest.RestContextFactory.createContextBuilder; +import static org.testng.Assert.assertNotNull; + +/** + * Tests behavior of JAXB parsing for Network(s) + * + * @author Jason King + */ +@Test(groups = "unit", testName = "NetworksJAXBParsingTest") +public class NetworksJAXBParsingTest extends BaseRestClientTest { + + @BeforeClass + void setupFactory() { + RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "userfoo", + "credentialFoo", String.class, Integer.class, + ImmutableSet. of(new MockModule(), new NullLoggingModule(), new AbstractModule() { + + @Override + protected void configure() {} + + @SuppressWarnings("unused") + @Provides + @Named("exception") + Set exception() { + throw new AuthorizationException(); + } + + })); + + injector = createContextBuilder(contextSpec).buildInjector(); + parserFactory = injector.getInstance(ParseSax.Factory.class); + crypto = injector.getInstance(Crypto.class); + } + + @Test + public void testParseNetworksWithJAXB() throws Exception { + Method method = NetworkAsyncClient.class.getMethod("getNetworks",URI.class); + HttpRequest request = factory(LocationAsyncClient.class).createRequest(method, new URI("/1")); + assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); + + Function parser = (Function) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + InputStream is = getClass().getResourceAsStream("/networks.xml"); + Networks networks = parser.apply(new HttpResponse(200, "ok", newInputStreamPayload(is))); + assertNotNull(networks); + for(NetworkReference network: networks.getNetworks()) { + assertNetworkFromNetworks(network); + } + } + + @Test + public void testParseNetworkWithJAXB() throws Exception { + Method method = NetworkAsyncClient.class.getMethod("getNetwork",URI.class); + HttpRequest request = factory(LocationAsyncClient.class).createRequest(method, new URI("/1")); + assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); + + Function parser = (Function) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + InputStream is = getClass().getResourceAsStream("/network.xml"); + NetworkReference network = parser.apply(new HttpResponse(200, "ok", newInputStreamPayload(is))); + assertNotNull(network.getAddress()); + assertNotNull(network.getNetworkType()); + assertNotNull(network.getBroadcastAddress()); + assertNotNull(network.getGatewayAddress()); + assertRnatAddress(network.getRnatAddress()); + for(IpAddress address:network.getIpAddresses().getIpAddresses()) { + assertIpAddress(address); + } + } + + private void assertRnatAddress(NamedResource rnatAddress) { + assertNotNull(rnatAddress); + assertNotNull(rnatAddress.getHref()); + assertNotNull(rnatAddress.getName()); + assertNotNull(rnatAddress.getType()); + } + + private void assertIpAddress(IpAddress address) { + assertNotNull(address); + assertNotNull(address.getName()); + if( address.getHost() != null) { + assertNamedResource(address.getHost()); + } + if( address.getDetectedOn() != null) { + assertNamedResource(address.getDetectedOn()); + } + if( address.getRnatAddress() != null) { + assertNamedResource(address.getRnatAddress()); + } + } + + private void assertNamedResource(NamedResource resource) { + assertNotNull(resource.getName()); + } + + private void assertNetworkFromNetworks(NetworkReference network) { + assertNotNull(network.getHref()); + assertNotNull(network.getType()); + assertNotNull(network.getName()); + assertNotNull(network.getNetworkType()); + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/resources/network.xml b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/network.xml new file mode 100644 index 0000000000..3cb69a35d7 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/network.xml @@ -0,0 +1,224 @@ + + + + +

10.146.204.64
+ Internal + 10.146.204.79 + 10.146.204.65 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/resources/networks.xml b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/networks.xml new file mode 100644 index 0000000000..fcd6ea4249 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/networks.xml @@ -0,0 +1,16 @@ + + + + + + Internal + + + Dmz + + \ No newline at end of file From 97ef14077682fd01b8c4e8e97d2676def62258ec Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 12:59:12 +0000 Subject: [PATCH 3/7] Issue 695: Fixed javadoc and incorrect class in JAXB parsing test --- .../jclouds/tmrk/enterprisecloud/domain/network/Networks.java | 2 +- .../tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java index c436a1dfe2..a888dd2f84 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/network/Networks.java @@ -33,7 +33,7 @@ import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; /** - * Networks is more than a simple wrapper as it extends BaseResource. + * Networks is more than a simple wrapper as it extends Resource. * @author Jason King * */ diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java index e0831f991b..623ada1689 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/NetworksJAXBParsingTest.java @@ -87,7 +87,7 @@ public class NetworksJAXBParsingTest extends BaseRestClientTest { @Test public void testParseNetworksWithJAXB() throws Exception { Method method = NetworkAsyncClient.class.getMethod("getNetworks",URI.class); - HttpRequest request = factory(LocationAsyncClient.class).createRequest(method, new URI("/1")); + HttpRequest request = factory(NetworkAsyncClient.class).createRequest(method, new URI("/1")); assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); Function parser = (Function) RestAnnotationProcessor @@ -104,7 +104,7 @@ public class NetworksJAXBParsingTest extends BaseRestClientTest { @Test public void testParseNetworkWithJAXB() throws Exception { Method method = NetworkAsyncClient.class.getMethod("getNetwork",URI.class); - HttpRequest request = factory(LocationAsyncClient.class).createRequest(method, new URI("/1")); + HttpRequest request = factory(NetworkAsyncClient.class).createRequest(method, new URI("/1")); assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); Function parser = (Function) RestAnnotationProcessor From 9b0ea8f16f5d63c467b8c41345d2572d4cdff2a0 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 13:01:06 +0000 Subject: [PATCH 4/7] Issue 695: Implemented ssh key GET requests. Added Entity to prevent duplication of tasks (similar to Resource). --- .../TerremarkEnterpriseCloudAsyncClient.java | 6 + .../TerremarkEnterpriseCloudClient.java | 6 + ...remarkEnterpriseCloudRestClientModule.java | 1 + .../domain/internal/Entity.java | 158 ++++++++++++ .../enterprisecloud/domain/keys/SshKey.java | 239 ++++++++++++++++++ .../enterprisecloud/domain/keys/SshKeys.java | 182 +++++++++++++ .../features/SshKeyAsyncClient.java | 63 +++++ .../features/SshKeyClient.java | 59 +++++ .../features/SSHKeyAsyncClientTest.java | 76 ++++++ .../features/SSHKeyClientLiveTest.java | 58 +++++ .../xml/SSHKeysJAXBParsingTest.java | 153 +++++++++++ .../src/test/resources/sshKey.xml | 17 ++ .../src/test/resources/sshKeys.xml | 48 ++++ 13 files changed, 1066 insertions(+) create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/internal/Entity.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKey.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKeys.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/SSHKeysJAXBParsingTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKey.xml create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKeys.xml diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java index b2cefa6521..2f39b543d1 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudAsyncClient.java @@ -57,6 +57,12 @@ public interface TerremarkEnterpriseCloudAsyncClient { @Delegate TaskAsyncClient getTaskClient(); + /** + * Provides asynchronous access to SSH Key features. + */ + @Delegate + SSHKeyAsyncClient getSSHKeyClient(); + /** * Provides asynchronous access to VirtualMachine features. */ diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java index e34bbd4469..3ab006f338 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/TerremarkEnterpriseCloudClient.java @@ -55,6 +55,12 @@ public interface TerremarkEnterpriseCloudClient { @Delegate NetworkClient getNetworkClient(); + /** + * Provides synchronous access to SSH Key features. + */ + @Delegate + SSHKeyClient getSSHKeyClient(); + /** * Provides synchronous access to Task features. */ diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java index 7cc37e56cb..bedc975b83 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java @@ -51,6 +51,7 @@ public class TerremarkEnterpriseCloudRestClientModule extends .put(NetworkClient.class, NetworkAsyncClient.class) .put(ResourceClient.class, ResourceAsyncClient.class) .put(TaskClient.class, TaskAsyncClient.class) + .put(SSHKeyClient.class, SSHKeyAsyncClient.class) .put(VirtualMachineClient.class, VirtualMachineAsyncClient.class) .put(TemplateClient.class, TemplateAsyncClient.class) .build(); diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/internal/Entity.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/internal/Entity.java new file mode 100644 index 0000000000..df8f2707b5 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/internal/Entity.java @@ -0,0 +1,158 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.internal; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.Task; +import org.jclouds.tmrk.enterprisecloud.domain.Tasks; + +import javax.xml.bind.annotation.XmlElement; +import java.net.URI; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Base Entity class. Extends Resource with Tasks + * + * @author Jason King + * + */ +public class Entity> extends Resource { + + public static > Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().fromResource(this); + } + + public static class Builder> extends Resource.Builder { + + protected Set tasks = Sets.newLinkedHashSet(); + + /** + * @see org.jclouds.tmrk.enterprisecloud.domain.internal.Entity#getTasks + */ + public Builder tasks(Set tasks) { + this.tasks = ImmutableSet. copyOf(checkNotNull(tasks, "tasks")); + return this; + } + + /** + * @see Resource#getLinks + */ + public Builder links(Set links) { + return Builder.class.cast(super.links(links)); + } + + /** + * @see Resource#getActions + */ + public Builder actions(Set actions) { + return Builder.class.cast(super.actions(actions)); + } + + /** + * @see Resource#getActions + */ + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + public Entity build() { + return new Entity(href, type, name, links, actions, tasks); + } + + /** + * {@inheritDoc} + */ + public Builder fromBaseResource(BaseResource in) { + return Builder.class.cast(super.fromBaseResource(in)); + } + + /** + * {@inheritDoc} + */ + public Builder fromResource(Resource in) { + return Builder.class.cast(super.fromResource(in)); + } + + public Builder fromEntity(Entity in) { + return fromResource(in).links(in.getLinks()).actions(in.getActions()).name(in.getName()) + .tasks(in.getTasks()); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public Builder fromAttributes(Map attributes) { + return Builder.class.cast(super.fromAttributes(attributes)); + } + } + + @XmlElement(name = "Tasks", required = false) + private Tasks tasks = Tasks.builder().build(); + + protected Entity(URI href, String type, @Nullable String name, Set links, Set actions, Set tasks) { + super(href, type, name, links, actions); + this.tasks = Tasks.builder().tasks(checkNotNull(tasks,"tasks")).build(); + } + + protected Entity() { + //For JAXB + } + + public Set getTasks() { + return Collections.unmodifiableSet(tasks.getTasks()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Entity entity = (Entity) o; + + if (!tasks.equals(entity.tasks)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + tasks.hashCode(); + return result; + } + + @Override + public String string() { + return super.string()+", name="+name+", tasks="+tasks; + } +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKey.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKey.java new file mode 100644 index 0000000000..635844d65f --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKey.java @@ -0,0 +1,239 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.keys; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.Task; +import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource; +import org.jclouds.tmrk.enterprisecloud.domain.internal.Entity; +import org.jclouds.tmrk.enterprisecloud.domain.internal.Resource; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.net.URI; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Jason King + */ +@XmlRootElement(name = "SshKey") +public class SSHKey extends Entity { + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder toBuilder() { + return new Builder().fromSshKey(this); + } + + public static class Builder extends Entity.Builder { + private boolean defaultKey; + private String fingerPrint; + private String privateKey; + + /** + * @see SSHKey#isDefaultKey + */ + public Builder defaultKey(boolean defaultKey) { + this.defaultKey = defaultKey; + return this; + } + + /** + * @see SSHKey#getFingerPrint + */ + public Builder fingerPrint(String fingerPrint) { + this.fingerPrint = fingerPrint; + return this; + } + + /** + * @see SSHKey#getPrivateKey + */ + public Builder privateKey(String privateKey) { + this.privateKey = privateKey; + return this; + } + + @Override + public SSHKey build() { + return new SSHKey(href, type, name, links, actions, tasks, defaultKey, fingerPrint, privateKey); + } + + public Builder fromSshKey(SSHKey in) { + return fromEntity(in).defaultKey(in.isDefaultKey()).fingerPrint(in.getFingerPrint()).privateKey(in.getPrivateKey()); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromBaseResource(BaseResource in) { + return Builder.class.cast(super.fromBaseResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromResource(Resource in) { + return Builder.class.cast(super.fromResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromEntity(Entity in) { + return Builder.class.cast(super.fromEntity(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(String type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder href(URI href) { + return Builder.class.cast(super.href(href)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder links(Set links) { + return Builder.class.cast(super.links(links)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder actions(Set actions) { + return Builder.class.cast(super.actions(actions)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder tasks(Set tasks) { + return Builder.class.cast(super.tasks(tasks)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromAttributes(Map attributes) { + return Builder.class.cast(super.fromAttributes(attributes)); + } + + } + + @XmlElement(name = "Default", required = false) + private boolean defaultKey; + + @XmlElement(name = "FingerPrint", required = false) + private String fingerPrint; + + @XmlElement(name = "PrivateKey", required = false) + private String privateKey; + + private SSHKey(URI href, String type, String name, Set links, Set actions, Set tasks, + boolean defaultKey, @Nullable String fingerPrint, @Nullable String privateKey) { + super(href, type, name, links, actions, tasks); + this.defaultKey = defaultKey; + this.fingerPrint = fingerPrint; + this.privateKey = privateKey; + } + + private SSHKey() { + //For JAXB + } + + public boolean isDefaultKey() { + return defaultKey; + } + + public String getFingerPrint() { + return fingerPrint; + } + + public String getPrivateKey() { + return privateKey; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + SSHKey sshKey = (SSHKey) o; + + if (defaultKey != sshKey.defaultKey) return false; + if (fingerPrint != null ? !fingerPrint.equals(sshKey.fingerPrint) : sshKey.fingerPrint != null) + return false; + if (privateKey != null ? !privateKey.equals(sshKey.privateKey) : sshKey.privateKey != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (defaultKey ? 1 : 0); + result = 31 * result + (fingerPrint != null ? fingerPrint.hashCode() : 0); + result = 31 * result + (privateKey != null ? privateKey.hashCode() : 0); + return result; + } + + @Override + public String string() { + return super.string()+", defaultKey="+defaultKey+", fingerPrint="+fingerPrint+", privateKey="+privateKey; + } + +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKeys.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKeys.java new file mode 100644 index 0000000000..4cebdbe02a --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/domain/keys/SshKeys.java @@ -0,0 +1,182 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.domain.keys; + +import com.google.common.collect.Sets; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource; +import org.jclouds.tmrk.enterprisecloud.domain.internal.Resource; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * SshKeys is more than a simple wrapper as it extends Resource. + * @author Jason King + * + */ +@XmlRootElement(name = "SshKeys") +public class SSHKeys extends Resource { + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder toBuilder() { + return new Builder().fromTemplates(this); + } + + public static class Builder extends Resource.Builder { + private Set sshKeys = Sets.newLinkedHashSet(); + + /** + * @see SSHKeys#getSSHKeys + */ + public Builder sshKeys(Set sshKeys) { + this.sshKeys =(checkNotNull(sshKeys,"sshKeys")); + return this; + } + + @Override + public SSHKeys build() { + return new SSHKeys(href, type, name, links, actions, sshKeys); + } + + public Builder fromTemplates(SSHKeys in) { + return fromResource(in).sshKeys(in.getSSHKeys()); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromBaseResource(BaseResource in) { + return Builder.class.cast(super.fromBaseResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromResource(Resource in) { + return Builder.class.cast(super.fromResource(in)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(String type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder href(URI href) { + return Builder.class.cast(super.href(href)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder links(Set links) { + return Builder.class.cast(super.links(links)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder actions(Set actions) { + return Builder.class.cast(super.actions(actions)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder fromAttributes(Map attributes) { + return Builder.class.cast(super.fromAttributes(attributes)); + } + + } + + @XmlElement(name = "SshKey", required = false) + private Set sshKeys = Sets.newLinkedHashSet(); + + private SSHKeys(URI href, String type, String name, Set links, Set actions, Set sshKeys) { + super(href, type, name, links, actions); + this.sshKeys = checkNotNull(sshKeys,"sshKeys"); + } + + private SSHKeys() { + //For JAXB + } + + public Set getSSHKeys() { + return sshKeys; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + SSHKeys networks1 = (SSHKeys) o; + + if (!sshKeys.equals(networks1.sshKeys)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + sshKeys.hashCode(); + return result; + } + + @Override + public String string() { + return super.string()+", sshKeys="+sshKeys; + } +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java new file mode 100644 index 0000000000..cd8280f6f2 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java @@ -0,0 +1,63 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import com.google.common.util.concurrent.ListenableFuture; +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.rest.annotations.*; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import java.net.URI; + +/** + * Provides asynchronous access to ssh keys via their REST API. + *

+ * + * @see SSHKeyClient + * @see + * @author Jason King + */ +@RequestFilters(BasicAuthentication.class) +@Headers(keys = "x-tmrk-version", values = "{jclouds.api-version}") +public interface SSHKeyAsyncClient { + + /** + * @see SSHKeyClient#getSSHKeys + */ + @GET + @Consumes("application/vnd.tmrk.cloud.admin.sshKey; type=collection") + @JAXBResponseParser + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + public ListenableFuture getSSHKeys(@EndpointParam URI uri); + + /** + * @see SSHKeyClient#getSSHKey + */ + @GET + @Consumes("application/vnd.tmrk.cloud.admin.sshKey") + @JAXBResponseParser + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + public ListenableFuture getSSHKey(@EndpointParam URI uri); +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java new file mode 100644 index 0000000000..f524e6be47 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java @@ -0,0 +1,59 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; + +import java.net.URI; +import java.util.concurrent.TimeUnit; + +/** + * Provides synchronous access to Ssh Key Functions. + *

+ * + * @see SSHKeyAsyncClient + * @see + * @author Jason King + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface SSHKeyClient { + + /** + * The Get SSH Keys call returns information regarding the SSH keys for an organization + * + * @param uri the uri of the call based upon the organization + * e.g. /cloudapi/ecloud/admin/sshkeys/organizations/{id} + * @return the SSHKeys + */ + public SSHKeys getSSHKeys(URI uri); + + /** + * The Get SSH Keys by ID call returns information regarding a specified SSH key for an organization. + * + * @param uri the uri of the call based upon the key + * e.g. /cloudapi/ecloud/admin/sshkeys/{id} + * @return the SSHKey + */ + public SSHKey getSSHKey(URI uri); + +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java new file mode 100644 index 0000000000..99565cd295 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java @@ -0,0 +1,76 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import com.google.inject.TypeLiteral; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseXMLWithJAXB; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Tests annotation parsing of {@code SSHKeyAsyncClientTest} + * + * @author Jason King + */ +@Test(groups = "unit", testName = "SSHKeyAsyncClientTest") +public class SSHKeyAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncClientTest { + + public void testGetSSHKeys() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException { + Method method = SSHKeyAsyncClient.class.getMethod("getSSHKeys", URI.class); + HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/admin/sshkeys/organizations/17")); + + assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/admin/sshkeys/organizations/17 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, + "Accept: application/vnd.tmrk.cloud.admin.sshKey; type=collection\nx-tmrk-version: 2011-07-01\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + } + + public void testGetSSHKey() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException { + Method method = SSHKeyAsyncClient.class.getMethod("getSSHKey", URI.class); + HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/admin/sshkeys/77")); + + assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/admin/sshkeys/77 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, + "Accept: application/vnd.tmrk.cloud.admin.sshKey\nx-tmrk-version: 2011-07-01\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java new file mode 100644 index 0000000000..71d4b79fa6 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java @@ -0,0 +1,58 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.features; + +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import java.net.URI; + +import static org.testng.Assert.assertNotNull; + +/** + * Tests behavior of {@code SSHKeyClient} + * + * @author Jason King + */ +@Test(groups = "live", testName = "SSHKeyClientLiveTest") +public class SSHKeyClientLiveTest extends BaseTerremarkEnterpriseCloudClientLiveTest { + @BeforeGroups(groups = { "live" }) + public void setupClient() { + super.setupClient(); + client = context.getApi().getSSHKeyClient(); + } + + private SSHKeyClient client; + + public void testGetSSHKeys() throws Exception { + //TODO: Remove the hardcoded uri once have access to organization + SSHKeys sshKeys = client.getSSHKeys(URI.create("/cloudapi/ecloud/admin/sshkeys/organizations/17")); + for(SSHKey key: sshKeys.getSSHKeys()) { + testGetSSHKey(key.getHref()); + } + } + + private void testGetSSHKey(URI uri) { + SSHKey sshKey = client.getSSHKey(uri); + assertNotNull(sshKey); + assertNotNull(sshKey.getFingerPrint()); + } +} \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/SSHKeysJAXBParsingTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/SSHKeysJAXBParsingTest.java new file mode 100644 index 0000000000..6ed357bf8f --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/xml/SSHKeysJAXBParsingTest.java @@ -0,0 +1,153 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.xml; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.Provides; +import org.jclouds.crypto.Crypto; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseXMLWithJAXB; +import org.jclouds.logging.config.NullLoggingModule; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.BaseRestClientTest; +import org.jclouds.rest.RestContextSpec; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.tmrk.enterprisecloud.domain.Action; +import org.jclouds.tmrk.enterprisecloud.domain.Link; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; +import org.jclouds.tmrk.enterprisecloud.features.SSHKeyAsyncClient; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import javax.inject.Named; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.Set; + +import static org.jclouds.io.Payloads.newInputStreamPayload; +import static org.jclouds.rest.RestContextFactory.contextSpec; +import static org.jclouds.rest.RestContextFactory.createContextBuilder; +import static org.testng.Assert.*; + +/** + * Tests behavior of JAXB parsing for SSHKey(s) + * + * @author Jason King + */ +@Test(groups = "unit", testName = "SSHKeysJAXBParsingTest") +public class SSHKeysJAXBParsingTest extends BaseRestClientTest { + + @BeforeClass + void setupFactory() { + RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "userfoo", + "credentialFoo", String.class, Integer.class, + ImmutableSet. of(new MockModule(), new NullLoggingModule(), new AbstractModule() { + + @Override + protected void configure() {} + + @SuppressWarnings("unused") + @Provides + @Named("exception") + Set exception() { + throw new AuthorizationException(); + } + + })); + + injector = createContextBuilder(contextSpec).buildInjector(); + parserFactory = injector.getInstance(ParseSax.Factory.class); + crypto = injector.getInstance(Crypto.class); + } + + @Test + public void testParseSSHKeysWithJAXB() throws Exception { + Method method = SSHKeyAsyncClient.class.getMethod("getSSHKeys",URI.class); + HttpRequest request = factory(SSHKeyAsyncClient.class).createRequest(method, new URI("/1")); + assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); + + Function parser = (Function) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + InputStream is = getClass().getResourceAsStream("/sshKeys.xml"); + SSHKeys sshKeys = parser.apply(new HttpResponse(200, "ok", newInputStreamPayload(is))); + assertNotNull(sshKeys); + Link link = Iterables.getOnlyElement(sshKeys.getLinks()); + assertEquals(link.getName(),"Cloudsoft Corporation [Beta]"); + assertEquals(link.getRelationship(), Link.Relationship.UP); + + Action action = Iterables.getOnlyElement(sshKeys.getActions()); + assertEquals(action.getName(),"createSshKey"); + assertEquals(sshKeys.getSSHKeys().size(), 2); + + SSHKey key1 = Iterables.get(sshKeys.getSSHKeys(),0); + assertTrue(key1.isDefaultKey()); + assertEquals(key1.getFingerPrint(),"c8:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5"); + + SSHKey key2= Iterables.get(sshKeys.getSSHKeys(),1); + assertFalse(key2.isDefaultKey()); + assertEquals(key2.getFingerPrint(),"a1:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5"); + } + + @Test + public void testParseSSHKeyWithJAXB() throws Exception { + Method method = SSHKeyAsyncClient.class.getMethod("getSSHKey",URI.class); + HttpRequest request = factory(SSHKeyAsyncClient.class).createRequest(method, new URI("/1")); + assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class); + + Function parser = (Function) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + InputStream is = getClass().getResourceAsStream("/sshKey.xml"); + SSHKey sshKey = parser.apply(new HttpResponse(200, "ok", newInputStreamPayload(is))); + assertEquals(sshKey.getHref(),URI.create("/cloudapi/ecloud/admin/sshkeys/77")); + assertEquals(sshKey.getType(),"application/vnd.tmrk.cloud.admin.sshKey"); + assertEquals(sshKey.getName(),"test"); + + assertEquals(sshKey.getLinks().size(),1); + Link link = Iterables.getOnlyElement(sshKey.getLinks()); + assertEquals(link.getHref(),URI.create("/cloudapi/ecloud/admin/organizations/17")); + assertEquals(link.getType(),"application/vnd.tmrk.cloud.admin.organization"); + assertEquals(link.getName(),"Cloudsoft Corporation [Beta]"); + assertEquals(link.getRelationship(), Link.Relationship.UP); + + assertEquals(sshKey.getActions().size(), 2); + Action action1 = Iterables.get(sshKey.getActions(), 0); + assertEquals(action1.getHref(),URI.create("/cloudapi/ecloud/admin/sshkeys/77")); + assertEquals(action1.getType(),"application/vnd.tmrk.cloud.admin.sshKey"); + assertEquals(action1.getName(),"edit"); + + Action action2 = Iterables.get(sshKey.getActions(), 1); + assertEquals(action2.getHref(),URI.create("/cloudapi/ecloud/admin/sshkeys/77")); + assertNull(action2.getType()); + assertEquals(action2.getName(),"remove"); + assertEquals(action2.getActionDisabled(), Action.ActionDisabled.DISABLED); + + assertEquals(sshKey.isDefaultKey(),true); + assertEquals(sshKey.getFingerPrint(),"c8:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5"); + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKey.xml b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKey.xml new file mode 100644 index 0000000000..d1b65cb605 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKey.xml @@ -0,0 +1,17 @@ + + + + + + + + + true + c8:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5 + \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKeys.xml b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKeys.xml new file mode 100644 index 0000000000..dd80a779d0 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/sshKeys.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + true + c8:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5 + + + + + + + + + + false + a1:3f:41:d6:28:e2:86:37:a6:a3:e6:df:62:d9:31:e5 + + \ No newline at end of file From ab01343a42575f023eb5e6a6c3c82dfeeed1c676 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 13:38:57 +0000 Subject: [PATCH 5/7] Issue 695: Implemented create ssh key request. --- .../features/SshKeyAsyncClient.java | 14 ++++++++++++++ .../features/SshKeyClient.java | 19 +++++++++++++++++++ .../features/SSHKeyAsyncClientTest.java | 16 ++++++++++++++++ .../features/SSHKeyClientLiveTest.java | 11 +++++++++++ 4 files changed, 60 insertions(+) diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java index cd8280f6f2..6fcb5dc17e 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java @@ -27,6 +27,9 @@ import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import java.net.URI; /** @@ -60,4 +63,15 @@ public interface SSHKeyAsyncClient { @JAXBResponseParser @ExceptionParser(ReturnNullOnNotFoundOr404.class) public ListenableFuture getSSHKey(@EndpointParam URI uri); + + /** + * @see SSHKeyClient#createSSHKey + */ + @POST + @Consumes("application/vnd.tmrk.cloud.admin.sshKey") + @JAXBResponseParser + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @Payload("{defaultKey}") + @Produces(MediaType.APPLICATION_XML) + public ListenableFuture createSSHKey(@EndpointParam URI uri, @PayloadParam("name")String name, @PayloadParam("defaultKey")boolean defaultKey); } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java index f524e6be47..a75147159a 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java @@ -55,5 +55,24 @@ public interface SSHKeyClient { * @return the SSHKey */ public SSHKey getSSHKey(URI uri); + + /** + * The createSSHKey call creates a new SSH key. + * If successful, the call returns information regarding the SSH key that was created. + * The name is required. + * Note: The name may not be that of another SSH key and may not exceed fifty characters. + * For the first key being created for an organization default should be true. + * To make the key the default, use true + * + * In the returned SSHKey: + * FingerPrint is the SSH key fingerprint, which is a 16 byte hash of the private key. + * PrivateKey is the actual private key, which has been encoded by base64. + * @param uri the uri of the createSshKey action based upon the organisation + * e.g. /cloudapi/ecloud/admin/sshkeys/organizations/{id}/action/createsshkey + * @param name the desired name of the key + * @param defaultKey to make the key the default one + * @return the ssh key + */ + public SSHKey createSSHKey(URI uri, String name, boolean defaultKey); } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java index 99565cd295..8bbbe90cd5 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java @@ -68,6 +68,22 @@ public class SSHKeyAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncClie checkFilters(httpRequest); } + public void testCreateSSHKey() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException { + Method method = SSHKeyAsyncClient.class.getMethod("createSSHKey", URI.class,String.class,boolean.class); + HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey"),"myKey",true); + + assertRequestLineEquals(httpRequest, "POST https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, + "Accept: application/vnd.tmrk.cloud.admin.sshKey\nx-tmrk-version: 2011-07-01\n"); + String xml = "true"; + assertPayloadEquals(httpRequest, xml, "application/xml", false); + + assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + } + @Override protected TypeLiteral> createTypeLiteral() { return new TypeLiteral>() { diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java index 71d4b79fa6..fc06df6c28 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java @@ -25,6 +25,8 @@ import org.testng.annotations.Test; import java.net.URI; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; /** @@ -55,4 +57,13 @@ public class SSHKeyClientLiveTest extends BaseTerremarkEnterpriseCloudClientLive assertNotNull(sshKey); assertNotNull(sshKey.getFingerPrint()); } + + public void testCreateSSHKey() { + SSHKey sshKey = client.createSSHKey(URI.create("/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey"),"mylivetestkey",false); + assertNotNull(sshKey); + assertEquals(sshKey.getName(),"mylivetestkey"); + assertFalse(sshKey.isDefaultKey()); + assertFalse(sshKey.getFingerPrint().isEmpty()); + assertFalse(sshKey.getPrivateKey().isEmpty()); + } } \ No newline at end of file From ccaac6da5fb798073192d8ef1ac1c47edb7629e7 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 14:54:24 +0000 Subject: [PATCH 6/7] Issue 695: Implemented edit and delete ssh key --- .../binders/BindSSHKeyToXmlPayload.java | 68 +++++++++++++++++++ ...remarkEnterpriseCloudRestClientModule.java | 12 ++++ .../features/SshKeyAsyncClient.java | 28 ++++++-- .../features/SshKeyClient.java | 23 ++++++- .../src/main/resources/editSSHKey.xml | 4 ++ .../features/SSHKeyAsyncClientTest.java | 41 +++++++++++ .../features/SSHKeyClientLiveTest.java | 23 +++++-- 7 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/main/resources/editSSHKey.xml diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java new file mode 100644 index 0000000000..48578fd8d9 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java @@ -0,0 +1,68 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.binders; + +import com.google.common.collect.ImmutableMap; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; +import org.jclouds.rest.binders.BindToStringPayload; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.util.Strings2; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * TODO Tests + * @author Jason King + * + */ +@Singleton +public class BindSSHKeyToXmlPayload implements Binder { + + private final String xmlTemplate; + private final BindToStringPayload stringBinder; + + @Inject + BindSSHKeyToXmlPayload(@Named("EditSSHKey") String xmlTemplate, + BindToStringPayload stringBinder) { + this.xmlTemplate = xmlTemplate; + this.stringBinder = stringBinder; + } + + @Override + public R bindToRequest(R request, Object key) { + checkArgument(checkNotNull(key, "key") instanceof SSHKey, "this binder is only valid for SSHKey instances!"); + checkNotNull(request, "request"); + SSHKey sshKey = SSHKey.class.cast(key); + + String name = sshKey.getName(); + String isDefault = Boolean.toString(sshKey.isDefaultKey()); + String fingerPrint = sshKey.getFingerPrint(); + + String payload = Strings2.replaceTokens(xmlTemplate, + ImmutableMap.of("name", name, "isDefault", isDefault, "fingerPrint", fingerPrint)); + + return stringBinder.bindToRequest(request, payload); + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java index bedc975b83..5cff6ef7aa 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/config/TerremarkEnterpriseCloudRestClientModule.java @@ -18,8 +18,10 @@ */ package org.jclouds.tmrk.enterprisecloud.config; +import java.io.IOException; import java.util.Map; +import com.google.inject.Provides; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.RequiresHttp; @@ -35,6 +37,10 @@ import org.jclouds.tmrk.enterprisecloud.features.*; import org.jclouds.tmrk.enterprisecloud.handlers.TerremarkEnterpriseCloudErrorHandler; import com.google.common.collect.ImmutableMap; +import org.jclouds.util.Strings2; + +import javax.inject.Named; +import javax.inject.Singleton; /** * Configures the TerremarkEnterpriseCloud connection. @@ -77,4 +83,10 @@ public class TerremarkEnterpriseCloudRestClientModule extends bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(BackoffLimitedRetryHandler.class); } + @Singleton + @Provides + @Named("EditSSHKey") + String provideEditSSHKey() throws IOException { + return Strings2.toStringAndClose(getClass().getResourceAsStream("/EditSSHKey.xml")); + } } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java index 6fcb5dc17e..9ad83e597f 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyAsyncClient.java @@ -22,13 +22,12 @@ import com.google.common.util.concurrent.ListenableFuture; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.*; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; +import org.jclouds.tmrk.enterprisecloud.binders.BindSSHKeyToXmlPayload; import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKeys; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Produces; +import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import java.net.URI; @@ -71,7 +70,28 @@ public interface SSHKeyAsyncClient { @Consumes("application/vnd.tmrk.cloud.admin.sshKey") @JAXBResponseParser @ExceptionParser(ReturnNullOnNotFoundOr404.class) + //TODO This would be done better with a template like editSSHKey @Payload("{defaultKey}") @Produces(MediaType.APPLICATION_XML) public ListenableFuture createSSHKey(@EndpointParam URI uri, @PayloadParam("name")String name, @PayloadParam("defaultKey")boolean defaultKey); + + /** + * @see SSHKeyClient#editSSHKey + */ + @PUT + @Consumes("application/vnd.tmrk.cloud.admin.sshKey") + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @JAXBResponseParser + @Produces(MediaType.APPLICATION_XML) + public ListenableFuture editSSHKey(@EndpointParam URI uri, @BinderParam(BindSSHKeyToXmlPayload.class)SSHKey key); + + /** + * @see SSHKeyClient#createSSHKey + * TODO Should map the 204 header to a boolean to indicate that it was sucessful + */ + @DELETE + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + public ListenableFuture deleteSSHKey(@EndpointParam URI uri); + + } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java index a75147159a..3ea252cb9c 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/features/SshKeyClient.java @@ -74,5 +74,26 @@ public interface SSHKeyClient { * @return the ssh key */ public SSHKey createSSHKey(URI uri, String name, boolean defaultKey); - + + + /** + * The editSSHKey call edits the name of the SSH key. + * If successful, the call returns information regarding the SSH key that was modified. + * The name attribute on the sshKey may be changed. + * Note: The name may not be changed to that of another SSH key and may not exceed fifty characters. + * FingerPrint is optional and ignored if sent. + * Note: The default SSH key may not be modified to false. + * Instead, modify the SSH key desired as the default to true and the existing + * default SSH key will be automatically modified to false. + */ + public void editSSHKey(URI uri, SSHKey key); + + /** + * The deleteSSHKey call removes a specified SSH key from an organization. + * //TODO Make this a boolean if sucessful + * @param uri the uri of the ssk key to delete + * e.g. /cloudapi/ecloud/admin/sshkeys/77 + */ + public void deleteSSHKey(URI uri); + } diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/resources/editSSHKey.xml b/sandbox-providers/tmrk-enterprisecloud/src/main/resources/editSSHKey.xml new file mode 100644 index 0000000000..bf23606594 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/resources/editSSHKey.xml @@ -0,0 +1,4 @@ + + {isDefault} + {fingerPrint} + \ No newline at end of file diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java index 8bbbe90cd5..25a600b390 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyAsyncClientTest.java @@ -21,8 +21,11 @@ package org.jclouds.tmrk.enterprisecloud.features; import com.google.inject.TypeLiteral; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseXMLWithJAXB; +import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; import org.testng.annotations.Test; import java.io.IOException; @@ -84,6 +87,44 @@ public class SSHKeyAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncClie checkFilters(httpRequest); } + public void testEditSSHKey() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException { + Method method = SSHKeyAsyncClient.class.getMethod("editSSHKey", URI.class,SSHKey.class); + + SSHKey key = SSHKey.builder().type("application/vnd.tmrk.cloud.admin.sshKey") + .href(URI.create("/cloudapi/ecloud/admin/sshkeys/77")) + .name("newName").defaultKey(false).fingerPrint("123").build(); + + HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/admin/sshkeys/77"),key); + + assertRequestLineEquals(httpRequest, "PUT https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/admin/sshkeys/77 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, + "Accept: application/vnd.tmrk.cloud.admin.sshKey\nx-tmrk-version: 2011-07-01\n"); + String xml = "\n" + + " false\n" + + " 123\n" + + ""; + assertPayloadEquals(httpRequest, xml, "application/xml", false); + + assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + } + + public void testDeleteSSHKey() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException { + Method method = SSHKeyAsyncClient.class.getMethod("deleteSSHKey", URI.class); + HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/admin/sshkeys/77")); + + assertRequestLineEquals(httpRequest, "DELETE https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/admin/sshkeys/77 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest,"x-tmrk-version: 2011-07-01\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class); + assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class); + + checkFilters(httpRequest); + } + @Override protected TypeLiteral> createTypeLiteral() { return new TypeLiteral>() { diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java index fc06df6c28..d379519918 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/features/SSHKeyClientLiveTest.java @@ -25,9 +25,7 @@ import org.testng.annotations.Test; import java.net.URI; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.*; /** * Tests behavior of {@code SSHKeyClient} @@ -59,11 +57,26 @@ public class SSHKeyClientLiveTest extends BaseTerremarkEnterpriseCloudClientLive } public void testCreateSSHKey() { - SSHKey sshKey = client.createSSHKey(URI.create("/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey"),"mylivetestkey",false); + SSHKey sshKey = client.createSSHKey(URI.create("/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey"),"mynewtestkey1",false); assertNotNull(sshKey); - assertEquals(sshKey.getName(),"mylivetestkey"); + assertEquals(sshKey.getName(),"mynewtestkey1"); assertFalse(sshKey.isDefaultKey()); assertFalse(sshKey.getFingerPrint().isEmpty()); assertFalse(sshKey.getPrivateKey().isEmpty()); + client.deleteSSHKey(sshKey.getHref()); + assertNull(client.getSSHKey(sshKey.getHref())); + } + + public void testEditSSHKey() { + SSHKey sshKey = client.createSSHKey(URI.create("/cloudapi/ecloud/admin/sshkeys/organizations/17/action/createsshkey"),"mykeytoedit",false); + assertNotNull(sshKey); + SSHKey newKey = sshKey.toBuilder().name("editedname").defaultKey(false).build(); + client.editSSHKey(sshKey.getHref(),newKey); + + SSHKey result = client.getSSHKey(sshKey.getHref()); + assertEquals(result.getName(),"editedname"); + + client.deleteSSHKey(sshKey.getHref()); + assertNull(client.getSSHKey(sshKey.getHref())); } } \ No newline at end of file From 7f71cb3896b652e7719d41d5fe52b0b7bc9915a7 Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 13 Dec 2011 15:15:10 +0000 Subject: [PATCH 7/7] Issue 695: Added test for BindSSHKeyToXmlPayload --- .../binders/BindSSHKeyToXmlPayload.java | 3 +- .../binders/BindSSHKeyToXmlPayloadTest.java | 75 +++++++++++++++++++ .../src/test/resources/EditSSHKey-test.xml | 4 + 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayloadTest.java create mode 100644 sandbox-providers/tmrk-enterprisecloud/src/test/resources/EditSSHKey-test.xml diff --git a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java index 48578fd8d9..3cbc5f6dc5 100644 --- a/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java +++ b/sandbox-providers/tmrk-enterprisecloud/src/main/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayload.java @@ -33,9 +33,8 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** - * TODO Tests + * * @author Jason King - * */ @Singleton public class BindSSHKeyToXmlPayload implements Binder { diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayloadTest.java b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayloadTest.java new file mode 100644 index 0000000000..f13e59fd36 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/java/org/jclouds/tmrk/enterprisecloud/binders/BindSSHKeyToXmlPayloadTest.java @@ -0,0 +1,75 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.binders; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Provides; +import org.jclouds.http.HttpRequest; +import org.jclouds.tmrk.enterprisecloud.domain.keys.SSHKey; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +import javax.inject.Named; +import javax.inject.Singleton; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import static org.testng.Assert.assertEquals; + +/** + * Tests behavior of {@code BindSSHKeyToXmlPayloadTest} + * @author Jason King + */ +@Test(groups = "unit", testName = "BindSSHKeyToXmlPayloadTest") +public class BindSSHKeyToXmlPayloadTest { + Injector injector = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + } + + @SuppressWarnings("unused") + @Singleton + @Provides + @Named("EditSSHKey") + String provideInstantiateVAppTemplateParams() throws IOException { + InputStream is = getClass().getResourceAsStream("/EditSSHKey.xml"); + return Strings2.toStringAndClose(is); + } + }); + + public void testApplyInputStream() throws IOException { + String expected = Strings2.toStringAndClose(getClass().getResourceAsStream( + "/EditSSHKey-test.xml")); + HttpRequest request = new HttpRequest("GET", URI.create("http://test")); + BindSSHKeyToXmlPayload binder = injector + .getInstance(BindSSHKeyToXmlPayload.class); + + SSHKey key = SSHKey.builder().type("application/vnd.tmrk.cloud.admin.sshKey") + .href(URI.create("/cloudapi/ecloud/admin/sshkeys/77")) + .name("newName") + .defaultKey(false).fingerPrint("123").build(); + + binder.bindToRequest(request, key); + assertEquals(request.getPayload().getRawContent(), expected); + } +} diff --git a/sandbox-providers/tmrk-enterprisecloud/src/test/resources/EditSSHKey-test.xml b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/EditSSHKey-test.xml new file mode 100644 index 0000000000..0da97f1594 --- /dev/null +++ b/sandbox-providers/tmrk-enterprisecloud/src/test/resources/EditSSHKey-test.xml @@ -0,0 +1,4 @@ + + false + 123 + \ No newline at end of file