mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of https://github.com/kedardave/jclouds
* 'master' of https://github.com/kedardave/jclouds: added compute service live test for savvis added vdc,vapp,network handling for savvis
This commit is contained in:
commit
705889d80a
|
@ -98,16 +98,16 @@ public class VDCHandler extends ParseSax.HandlerWithResult<VDC> {
|
||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
||||||
Map<String, String> attributes = cleanseAttributes(attrs);
|
Map<String, String> attributes = cleanseAttributes(attrs);
|
||||||
if (qName.equals("Vdc")) {
|
if (qName.endsWith("Vdc")) {
|
||||||
vDC = newReferenceType(attributes);
|
vDC = newReferenceType(attributes);
|
||||||
String status = attributes.get("status");
|
String status = attributes.get("status");
|
||||||
if (status != null)
|
if (status != null)
|
||||||
this.status = VDCStatus.fromValue(Integer.parseInt(status));
|
this.status = VDCStatus.fromValue(Integer.parseInt(status));
|
||||||
} else if (qName.equals("Network")) {
|
} else if (qName.endsWith("Network")) {
|
||||||
putReferenceType(availableNetworks, attributes);
|
putReferenceType(availableNetworks, attributes);
|
||||||
} else if (qName.equals("ResourceEntity")) {
|
} else if (qName.endsWith("ResourceEntity")) {
|
||||||
putReferenceType(resourceEntities, attributes);
|
putReferenceType(resourceEntities, attributes);
|
||||||
} else if (qName.equals("Link") && "up".equals(attributes.get("rel"))) {
|
} else if (qName.endsWith("Link") && "up".equals(attributes.get("rel"))) {
|
||||||
org = newReferenceType(attributes);
|
org = newReferenceType(attributes);
|
||||||
} else {
|
} else {
|
||||||
taskHandler.startElement(uri, localName, qName, attrs);
|
taskHandler.startElement(uri, localName, qName, attrs);
|
||||||
|
|
|
@ -29,11 +29,21 @@ import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.vcloud.CommonVCloudClient;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
import org.jclouds.vcloud.VCloudExpressAsyncClient;
|
import org.jclouds.vcloud.VCloudExpressAsyncClient;
|
||||||
import org.jclouds.vcloud.domain.Org;
|
import org.jclouds.vcloud.domain.Org;
|
||||||
|
import org.jclouds.vcloud.domain.VCloudExpressVApp;
|
||||||
|
import org.jclouds.vcloud.domain.VDC;
|
||||||
|
import org.jclouds.vcloud.domain.network.OrgNetwork;
|
||||||
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
||||||
|
import org.jclouds.vcloud.functions.OrgNameAndVDCNameToEndpoint;
|
||||||
import org.jclouds.vcloud.functions.OrgNameToEndpoint;
|
import org.jclouds.vcloud.functions.OrgNameToEndpoint;
|
||||||
|
import org.jclouds.vcloud.functions.OrgNameVDCNameResourceEntityNameToEndpoint;
|
||||||
|
import org.jclouds.vcloud.savvis.xml.SymphonyVPDCNetworkHandler;
|
||||||
|
import org.jclouds.vcloud.savvis.xml.SymphonyVPDCVAppHandler;
|
||||||
import org.jclouds.vcloud.xml.OrgHandler;
|
import org.jclouds.vcloud.xml.OrgHandler;
|
||||||
|
import org.jclouds.vcloud.xml.VDCHandler;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
@ -67,4 +77,69 @@ public interface SymphonyVPDCAsyncClient extends VCloudExpressAsyncClient {
|
||||||
@XMLResponseParser(OrgHandler.class)
|
@XMLResponseParser(OrgHandler.class)
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Org> getOrg(@EndpointParam URI orgId);
|
ListenableFuture<? extends Org> getOrg(@EndpointParam URI orgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CommonVCloudClient#getVDC(URI)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(VDCHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends VDC> getVDC(@EndpointParam URI vdc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CommonVCloudClient#findVDCInOrgNamed(String, String)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(VDCHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends VDC> findVDCInOrgNamed(
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String orgName,
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String vdcName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CommonVCloudClient#findNetworkInOrgVDCNamed
|
||||||
|
*//*
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends OrgNetwork> findNetworkInOrgVDCNamed(
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
|
||||||
|
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName);
|
||||||
|
|
||||||
|
*//**
|
||||||
|
* @see CommonVCloudClient#getNetwork
|
||||||
|
*//*
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends OrgNetwork> getNetwork(@EndpointParam URI network);*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CommonVCloudClient#findNetworkInOrgVDCNamed
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(SymphonyVPDCNetworkHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends OrgNetwork> findNetworkInOrgVDCNamed(
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
|
||||||
|
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
|
||||||
|
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CommonVCloudClient#getNetwork
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(SymphonyVPDCNetworkHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends OrgNetwork> getNetwork(@EndpointParam URI network);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VCloudClient#getVApp
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@XMLResponseParser(SymphonyVPDCVAppHandler.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<? extends VCloudExpressVApp> getVApp(@EndpointParam URI vApp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package org.jclouds.savvis.config;
|
package org.jclouds.savvis.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
@ -31,6 +33,7 @@ import org.jclouds.savvis.handlers.SymphonyVPDCErrorHandler;
|
||||||
import org.jclouds.vcloud.VCloudExpressAsyncClient;
|
import org.jclouds.vcloud.VCloudExpressAsyncClient;
|
||||||
import org.jclouds.vcloud.VCloudExpressClient;
|
import org.jclouds.vcloud.VCloudExpressClient;
|
||||||
import org.jclouds.vcloud.config.BaseVCloudExpressRestClientModule;
|
import org.jclouds.vcloud.config.BaseVCloudExpressRestClientModule;
|
||||||
|
import org.jclouds.vcloud.domain.Org;
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
@ -53,6 +56,14 @@ public class SymphonyVPDCRestClientModule extends
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected URI provideDefaultTasksList(Org org) {
|
||||||
|
if(org.getTasksList() != null){
|
||||||
|
return org.getTasksList().getHref();
|
||||||
|
}else{
|
||||||
|
return URI.create("https://api.symphonyVPDC.savvis.net/rest/api/v0.8/tasksList");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.vcloud.domain.network;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.vcloud.domain.ReferenceType;
|
||||||
|
import org.jclouds.vcloud.domain.network.firewall.FirewallRule;
|
||||||
|
import org.jclouds.vcloud.domain.network.nat.rules.PortForwardingRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A network that is available in a vDC.
|
||||||
|
*
|
||||||
|
* @author Kedar Dave
|
||||||
|
*/
|
||||||
|
public interface SymphonyVPDCNetwork extends ReferenceType {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return Description of the network
|
||||||
|
*/
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IP addresses of the network’s DNS servers.
|
||||||
|
*/
|
||||||
|
Set<String> getDnsServers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return The IP address of the network’s primary gateway
|
||||||
|
*/
|
||||||
|
String getGateway();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *
|
||||||
|
*
|
||||||
|
* @return the network’s subnet mask
|
||||||
|
*/
|
||||||
|
String getNetmask();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the network’s fence modes.
|
||||||
|
*/
|
||||||
|
Set<FenceMode> getFenceModes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return True if the network provides DHCP services
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Boolean isDhcp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return Network Address Translation rules for the network
|
||||||
|
*/
|
||||||
|
Set<PortForwardingRule> getNatRules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Firewall rules for the network
|
||||||
|
*/
|
||||||
|
Set<FirewallRule> getFirewallRules();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,205 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.vcloud.domain.network.internal;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.vcloud.domain.ReferenceType;
|
||||||
|
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
|
||||||
|
import org.jclouds.vcloud.domain.network.FenceMode;
|
||||||
|
import org.jclouds.vcloud.domain.network.SymphonyVPDCNetwork;
|
||||||
|
import org.jclouds.vcloud.domain.network.firewall.FirewallRule;
|
||||||
|
import org.jclouds.vcloud.domain.network.nat.rules.PortForwardingRule;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locations of resources in vCloud
|
||||||
|
*
|
||||||
|
* @author Kedar Dave
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SymphonyVPDCNetworkImpl extends ReferenceTypeImpl implements SymphonyVPDCNetwork {
|
||||||
|
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 8464716396538298809L;
|
||||||
|
protected final String description;
|
||||||
|
protected final Set<String> dnsServers = Sets.newHashSet();
|
||||||
|
protected final String gateway;
|
||||||
|
protected final String netmask;
|
||||||
|
protected final Set<FenceMode> fenceModes = Sets.newHashSet();
|
||||||
|
@Nullable
|
||||||
|
protected final Boolean dhcp;
|
||||||
|
protected final Set<PortForwardingRule> natRules = Sets.newHashSet();
|
||||||
|
protected final Set<FirewallRule> firewallRules = Sets.newHashSet();
|
||||||
|
|
||||||
|
public SymphonyVPDCNetworkImpl(String name, String type, URI id, String description, Set<String> dnsServers,
|
||||||
|
String gateway, String netmask, Set<FenceMode> fenceModes, Boolean dhcp, Set<PortForwardingRule> natRules,
|
||||||
|
Set<FirewallRule> firewallRules) {
|
||||||
|
super(name, type, id);
|
||||||
|
this.description = description;
|
||||||
|
this.dnsServers.addAll(dnsServers);
|
||||||
|
this.gateway = gateway;
|
||||||
|
this.netmask = netmask;
|
||||||
|
this.fenceModes.addAll(fenceModes);
|
||||||
|
this.dhcp = dhcp;
|
||||||
|
this.natRules.addAll(natRules);
|
||||||
|
this.firewallRules.addAll(firewallRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Set<String> getDnsServers() {
|
||||||
|
return dnsServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String getGateway() {
|
||||||
|
return gateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String getNetmask() {
|
||||||
|
return netmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Set<FenceMode> getFenceModes() {
|
||||||
|
return fenceModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Boolean isDhcp() {
|
||||||
|
return dhcp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Set<PortForwardingRule> getNatRules() {
|
||||||
|
return natRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Set<FirewallRule> getFirewallRules() {
|
||||||
|
return firewallRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ReferenceType o) {
|
||||||
|
return (this == o) ? 0 : getHref().compareTo(o.getHref());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||||
|
result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode());
|
||||||
|
result = prime * result + ((dnsServers == null) ? 0 : dnsServers.hashCode());
|
||||||
|
result = prime * result + ((fenceModes == null) ? 0 : fenceModes.hashCode());
|
||||||
|
result = prime * result + ((firewallRules == null) ? 0 : firewallRules.hashCode());
|
||||||
|
result = prime * result + ((gateway == null) ? 0 : gateway.hashCode());
|
||||||
|
result = prime * result + ((natRules == null) ? 0 : natRules.hashCode());
|
||||||
|
result = prime * result + ((netmask == null) ? 0 : netmask.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
VCloudExpressNetworkImpl other = (VCloudExpressNetworkImpl) obj;
|
||||||
|
if (description == null) {
|
||||||
|
if (other.description != null)
|
||||||
|
return false;
|
||||||
|
} else if (!description.equals(other.description))
|
||||||
|
return false;
|
||||||
|
if (dhcp == null) {
|
||||||
|
if (other.dhcp != null)
|
||||||
|
return false;
|
||||||
|
} else if (!dhcp.equals(other.dhcp))
|
||||||
|
return false;
|
||||||
|
if (dnsServers == null) {
|
||||||
|
if (other.dnsServers != null)
|
||||||
|
return false;
|
||||||
|
} else if (!dnsServers.equals(other.dnsServers))
|
||||||
|
return false;
|
||||||
|
if (fenceModes == null) {
|
||||||
|
if (other.fenceModes != null)
|
||||||
|
return false;
|
||||||
|
} else if (!fenceModes.equals(other.fenceModes))
|
||||||
|
return false;
|
||||||
|
if (firewallRules == null) {
|
||||||
|
if (other.firewallRules != null)
|
||||||
|
return false;
|
||||||
|
} else if (!firewallRules.equals(other.firewallRules))
|
||||||
|
return false;
|
||||||
|
if (gateway == null) {
|
||||||
|
if (other.gateway != null)
|
||||||
|
return false;
|
||||||
|
} else if (!gateway.equals(other.gateway))
|
||||||
|
return false;
|
||||||
|
if (natRules == null) {
|
||||||
|
if (other.natRules != null)
|
||||||
|
return false;
|
||||||
|
} else if (!natRules.equals(other.natRules))
|
||||||
|
return false;
|
||||||
|
if (netmask == null) {
|
||||||
|
if (other.netmask != null)
|
||||||
|
return false;
|
||||||
|
} else if (!netmask.equals(other.netmask))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[id=" + getHref() + ", name=" + getName() + ", type=" + getType() + ", description=" + description
|
||||||
|
+ ", dhcp=" + dhcp + ", dnsServers=" + dnsServers + ", fenceModes=" + fenceModes + ", firewallRules="
|
||||||
|
+ firewallRules + ", gateway=" + gateway + ", natRules=" + natRules + ", netmask=" + netmask + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.vcloud.savvis.xml;
|
||||||
|
|
||||||
|
import static org.jclouds.vcloud.util.Utils.cleanseAttributes;
|
||||||
|
import static org.jclouds.vcloud.util.Utils.newReferenceType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.vcloud.domain.ReferenceType;
|
||||||
|
import org.jclouds.vcloud.domain.network.FenceMode;
|
||||||
|
import org.jclouds.vcloud.domain.network.SymphonyVPDCNetwork;
|
||||||
|
import org.jclouds.vcloud.domain.network.firewall.FirewallPolicy;
|
||||||
|
import org.jclouds.vcloud.domain.network.firewall.FirewallRule;
|
||||||
|
import org.jclouds.vcloud.domain.network.internal.SymphonyVPDCNetworkImpl;
|
||||||
|
import org.jclouds.vcloud.domain.network.nat.NatProtocol;
|
||||||
|
import org.jclouds.vcloud.domain.network.nat.rules.PortForwardingRule;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kedar Dave
|
||||||
|
*/
|
||||||
|
public class SymphonyVPDCNetworkHandler extends ParseSax.HandlerWithResult<SymphonyVPDCNetwork>{
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private ReferenceType ips;
|
||||||
|
private ReferenceType extension;
|
||||||
|
|
||||||
|
protected StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
protected ReferenceType network;
|
||||||
|
|
||||||
|
protected String description;
|
||||||
|
|
||||||
|
protected Set<String> dnsServers = Sets.newLinkedHashSet();
|
||||||
|
protected String gateway;
|
||||||
|
protected String netmask;
|
||||||
|
protected Set<FenceMode> fenceModes = Sets.newLinkedHashSet();
|
||||||
|
protected Boolean dhcp;
|
||||||
|
protected Set<PortForwardingRule> natRules = Sets.newLinkedHashSet();
|
||||||
|
protected Set<FirewallRule> firewallRules = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
|
protected String externalIP;
|
||||||
|
protected Integer externalPort;
|
||||||
|
protected String internalIP;
|
||||||
|
protected Integer internalPort;
|
||||||
|
|
||||||
|
protected FirewallPolicy policy;
|
||||||
|
protected String sourceIP;
|
||||||
|
protected int sourcePort;
|
||||||
|
|
||||||
|
public SymphonyVPDCNetwork getResult() {
|
||||||
|
return new SymphonyVPDCNetworkImpl(network.getName(), network.getType(), network.getHref(), description,
|
||||||
|
dnsServers, gateway, netmask, fenceModes, dhcp, natRules, firewallRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
||||||
|
Map<String, String> attributes = cleanseAttributes(attrs);
|
||||||
|
if (qName.endsWith("Network")) {
|
||||||
|
network = newReferenceType(attributes);
|
||||||
|
} else if (qName.endsWith("Link")) {
|
||||||
|
if ("IP Addresses".equals(attributes.get("name"))) {
|
||||||
|
ips = newReferenceType(attributes);
|
||||||
|
} else if ("down".equals(attributes.get("rel"))) {
|
||||||
|
extension = newReferenceType(attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
if (qName.equals("Description")) {
|
||||||
|
description = currentOrNull();
|
||||||
|
} else if (qName.equals("Dns")) {
|
||||||
|
dnsServers.add(currentOrNull());
|
||||||
|
} else if (qName.equals("Gateway")) {
|
||||||
|
gateway = currentOrNull();
|
||||||
|
} else if (qName.equals("Netmask")) {
|
||||||
|
netmask = currentOrNull();
|
||||||
|
} else if (qName.equals("FenceMode")) {
|
||||||
|
try {
|
||||||
|
fenceModes.add(FenceMode.fromValue(currentOrNull()));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
fenceModes.add(FenceMode.BRIDGED);
|
||||||
|
}
|
||||||
|
} else if (qName.equals("Dhcp")) {
|
||||||
|
dhcp = new Boolean(currentOrNull());
|
||||||
|
} else if (qName.equals("NatRule")) {
|
||||||
|
natRules.add(new PortForwardingRule(externalIP, externalPort, internalIP, internalPort, NatProtocol.TCP_UDP));
|
||||||
|
externalIP = null;
|
||||||
|
externalPort = null;
|
||||||
|
internalIP = null;
|
||||||
|
internalPort = null;
|
||||||
|
} else if (qName.equals("ExternalIP")) {
|
||||||
|
externalIP = currentOrNull();
|
||||||
|
} else if (qName.equals("ExternalPort")) {
|
||||||
|
externalPort = Integer.parseInt(currentOrNull());
|
||||||
|
} else if (qName.equals("InternalIP")) {
|
||||||
|
internalIP = currentOrNull();
|
||||||
|
} else if (qName.equals("InternalPort")) {
|
||||||
|
internalPort = Integer.parseInt(currentOrNull());
|
||||||
|
} else if (qName.equals("FirewallRule")) {
|
||||||
|
firewallRules.add(new FirewallRule(true, null, policy, null, sourcePort, sourceIP));
|
||||||
|
policy = null;
|
||||||
|
sourceIP = null;
|
||||||
|
sourcePort = -1;
|
||||||
|
} else if (qName.equals("Policy")) {
|
||||||
|
policy = FirewallPolicy.fromValue(currentOrNull());
|
||||||
|
} else if (qName.equals("SourceIp")) {
|
||||||
|
sourceIP = currentOrNull();
|
||||||
|
} else if (qName.equals("SourcePort")) {
|
||||||
|
sourcePort = Integer.parseInt(currentOrNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String currentOrNull() {
|
||||||
|
String returnVal = currentText.toString().trim();
|
||||||
|
return returnVal.equals("") ? null : returnVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.vcloud.savvis.xml;
|
||||||
|
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.vcloud.util.Utils.cleanseAttributes;
|
||||||
|
import static org.jclouds.vcloud.util.Utils.newReferenceType;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.vcloud.VCloudExpressMediaType;
|
||||||
|
import org.jclouds.vcloud.domain.ReferenceType;
|
||||||
|
import org.jclouds.vcloud.domain.Status;
|
||||||
|
import org.jclouds.vcloud.domain.VCloudExpressVApp;
|
||||||
|
import org.jclouds.vcloud.domain.internal.VCloudExpressVAppImpl;
|
||||||
|
import org.jclouds.vcloud.domain.ovf.ResourceAllocation;
|
||||||
|
import org.jclouds.vcloud.domain.ovf.System;
|
||||||
|
import org.jclouds.vcloud.xml.ovf.ResourceAllocationHandler;
|
||||||
|
import org.jclouds.vcloud.xml.ovf.SystemHandler;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.ListMultimap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kedar Dave
|
||||||
|
*/
|
||||||
|
public class SymphonyVPDCVAppHandler extends ParseSax.HandlerWithResult<VCloudExpressVApp> {
|
||||||
|
private final String apiVersion;
|
||||||
|
private final SystemHandler systemHandler;
|
||||||
|
private final ResourceAllocationHandler allocationHandler;
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SymphonyVPDCVAppHandler(@Named(PROPERTY_API_VERSION) String apiVersion, SystemHandler systemHandler,
|
||||||
|
ResourceAllocationHandler allocationHandler) {
|
||||||
|
this.apiVersion = apiVersion;
|
||||||
|
this.systemHandler = systemHandler;
|
||||||
|
this.allocationHandler = allocationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected System system;
|
||||||
|
protected Set<ResourceAllocation> allocations = Sets.newLinkedHashSet();
|
||||||
|
protected Status status;
|
||||||
|
protected final ListMultimap<String, String> networkToAddresses = ArrayListMultimap.create();
|
||||||
|
protected StringBuilder currentText = new StringBuilder();
|
||||||
|
protected String operatingSystemDescription;
|
||||||
|
protected boolean inOs;
|
||||||
|
protected String networkName;
|
||||||
|
protected String name;
|
||||||
|
protected Integer osType;
|
||||||
|
protected URI location;
|
||||||
|
protected Long size;
|
||||||
|
protected ReferenceType vDC;
|
||||||
|
|
||||||
|
public VCloudExpressVApp getResult() {
|
||||||
|
return new VCloudExpressVAppImpl(name, location, status, size, vDC, networkToAddresses, osType,
|
||||||
|
operatingSystemDescription, system, allocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
||||||
|
Map<String, String> attributes = cleanseAttributes(attrs);
|
||||||
|
if (qName.endsWith("VApp")) {
|
||||||
|
ReferenceType resource = newReferenceType(attributes);
|
||||||
|
name = resource.getName();
|
||||||
|
location = resource.getHref();
|
||||||
|
String statusString = attributes.get("status");
|
||||||
|
if (apiVersion.indexOf("0.8") != -1 && "2".equals(statusString))
|
||||||
|
status = Status.OFF;
|
||||||
|
else
|
||||||
|
status = Status.fromValue(statusString);
|
||||||
|
if (attributes.containsKey("size"))
|
||||||
|
size = new Long(attributes.get("size"));
|
||||||
|
} else if (qName.equals("Link")) { // type should never be missing
|
||||||
|
if (attributes.containsKey("type") && attributes.get("type").equals(VCloudExpressMediaType.VDC_XML)) {
|
||||||
|
vDC = newReferenceType(attributes);
|
||||||
|
}
|
||||||
|
} else if (qName.endsWith("OperatingSystemSection")) {
|
||||||
|
inOs = true;
|
||||||
|
if (attributes.containsKey("id"))
|
||||||
|
osType = Integer.parseInt(attributes.get("id"));
|
||||||
|
} else if (qName.endsWith("NetworkConnection")) {
|
||||||
|
networkName = attributes.get("Network");
|
||||||
|
} else {
|
||||||
|
systemHandler.startElement(uri, localName, qName, attrs);
|
||||||
|
allocationHandler.startElement(uri, localName, qName, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.endsWith("OperatingSystemSection")) {
|
||||||
|
inOs = false;
|
||||||
|
} else if (inOs && qName.endsWith("Description")) {
|
||||||
|
operatingSystemDescription = currentText.toString().trim();
|
||||||
|
} else if (qName.endsWith("IpAddress")) {
|
||||||
|
networkToAddresses.put(networkName, currentText.toString().trim());
|
||||||
|
} else if (qName.equals("System")) {
|
||||||
|
systemHandler.endElement(uri, localName, qName);
|
||||||
|
system = systemHandler.getResult();
|
||||||
|
} else if (qName.equals("Item")) {
|
||||||
|
allocationHandler.endElement(uri, localName, qName);
|
||||||
|
allocations.add(allocationHandler.getResult());
|
||||||
|
} else {
|
||||||
|
systemHandler.endElement(uri, localName, qName);
|
||||||
|
allocationHandler.endElement(uri, localName, qName);
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
systemHandler.characters(ch, start, length);
|
||||||
|
allocationHandler.characters(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -50,9 +50,14 @@ public class SymphonyVPDCClientLiveTest extends VCloudExpressClientLiveTest {
|
||||||
context = new ComputeServiceContextFactory(restProperties).createContext(provider,
|
context = new ComputeServiceContextFactory(restProperties).createContext(provider,
|
||||||
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
|
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
|
||||||
|
|
||||||
System.out.println(context);
|
|
||||||
|
|
||||||
connection = context.getApi();
|
connection = context.getApi();
|
||||||
System.out.println(connection);
|
|
||||||
|
System.out.println(context);
|
||||||
|
/*System.out.println(connection);
|
||||||
|
Org org = connection.getOrg(URI.create("https://api.symphonyVPDC.savvis.net/rest/api/v0.8/org/607968.0"));
|
||||||
|
System.out.println(connection.getVDC(URI.create("https://api.symphonyVPDC.savvis.net/rest/api/v0.8/org/607968.0/vdc/2826")).getAvailableNetworks());
|
||||||
|
System.out.println(org.getVDCs().get(0));
|
||||||
|
System.out.println(org.getTasksList());
|
||||||
|
System.out.println(org.getTasks());*/
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.vcloud.savvis.compute;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||||
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
|
import org.jclouds.compute.domain.ComputeType;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.savvis.SymphonyVPDCAsyncClient;
|
||||||
|
import org.jclouds.savvis.SymphonyVPDCClient;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
|
import org.jclouds.vcloud.domain.VCloudExpressVApp;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Kedar Dave
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", enabled = true, sequential = true)
|
||||||
|
public class SymphonyVPDCComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
public SymphonyVPDCComputeServiceLiveTest() {
|
||||||
|
provider = "savvis-symphony-vpdc";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setServiceDefaults() {
|
||||||
|
group = "savvis.jclouds";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilder() {
|
||||||
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.5");
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||||
|
assert defaultTemplate.getLocation().getDescription() != null;// different per org
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAssignability() throws Exception {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
RestContext<SymphonyVPDCClient, SymphonyVPDCAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||||
|
.createContext(provider, identity, credential).getProviderSpecificContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||||
|
Template template = super.buildTemplate(templateBuilder);
|
||||||
|
Image image = template.getImage();
|
||||||
|
assert image.getDefaultCredentials() != null && image.getDefaultCredentials().identity != null : image;
|
||||||
|
assert image.getDefaultCredentials() != null && image.getDefaultCredentials().credential != null : image;
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
// currently, the wrong CIM OSType data is coming back.
|
||||||
|
@Override
|
||||||
|
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
||||||
|
if (node.getOperatingSystem() != null)
|
||||||
|
assertEquals(node.getOperatingSystem().getFamily(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testListImages() throws Exception {
|
||||||
|
for (Image image : client.listImages()) {
|
||||||
|
assert image.getProviderId() != null : image;
|
||||||
|
// image.getLocationId() can be null, if it is a location-free image
|
||||||
|
assertEquals(image.getType(), ComputeType.IMAGE);
|
||||||
|
if (image.getOperatingSystem().getFamily() != OsFamily.WINDOWS
|
||||||
|
&& image.getOperatingSystem().getFamily() != OsFamily.SOLARIS) {
|
||||||
|
assert image.getDefaultCredentials() != null && image.getDefaultCredentials().identity != null : image;
|
||||||
|
assert image.getDefaultCredentials().credential != null : image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testListNodes() throws Exception {
|
||||||
|
for (ComputeMetadata node : client.listNodes()) {
|
||||||
|
assert node.getProviderId() != null;
|
||||||
|
assert node.getLocation() != null;
|
||||||
|
assertEquals(node.getType(), ComputeType.NODE);
|
||||||
|
NodeMetadata allData = client.getNodeMetadata(node.getId());
|
||||||
|
System.out.println(allData.getHardware());
|
||||||
|
RestContext<SymphonyVPDCClient, SymphonyVPDCClient> tmContext = new ComputeServiceContextFactory()
|
||||||
|
.createContext(provider, identity, credential).getProviderSpecificContext();
|
||||||
|
VCloudExpressVApp vApp = tmContext.getApi().findVAppInOrgVDCNamed(null, null, allData.getName());
|
||||||
|
assertEquals(vApp.getName(), allData.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testDestroyNodes() {
|
||||||
|
super.testDestroyNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JschSshClientModule getSshModule() {
|
||||||
|
return new JschSshClientModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue