Refactoring GetVncPortCommand, MaintainCommand and SetupCommand to cope with new design. - Basic test added, but could not mock all the static stuff so the test is not complete yet. Will look further into it.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/637a56c3 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/637a56c3 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/637a56c3 Branch: refs/heads/master Commit: 637a56c3c1f8a33bdbb2344824e4df0ed9dee786 Parents: 11d0336 Author: wilderrodrigues <wrodrig...@schubergphilis.com> Authored: Wed Mar 25 19:16:02 2015 +0100 Committer: wilderrodrigues <wrodrig...@schubergphilis.com> Committed: Tue Mar 31 10:38:29 2015 +0200 ---------------------------------------------------------------------- .../xenserver/resource/CitrixResourceBase.java | 30 ++- .../resource/Xenserver625Resource.java | 2 +- .../wrapper/CitrixGetVncPortCommandWrapper.java | 56 ++++++ .../wrapper/CitrixMaintainCommandWrapper.java | 75 +++++++ .../resource/wrapper/CitrixRequestWrapper.java | 6 + .../wrapper/CitrixSetupCommandWrapper.java | 200 +++++++++++++++++++ .../wrapper/CitrixRequestWrapperTest.java | 118 ++++++++++- 7 files changed, 473 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index c412b54..6c51fae 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -340,10 +340,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return _host; } + public boolean isSecurityGroupEnabled() { + return _securityGroupEnabled; + } + + public void setCanBridgeFirewall(final boolean canBridgeFirewall) { + _canBridgeFirewall = canBridgeFirewall; + } + public boolean canBridgeFirewall() { return _canBridgeFirewall; } + public boolean canBridgeFirewall(final Connection conn) { + return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance)); + } + private static boolean isAlienVm(final VM vm, final Connection conn) throws XenAPIException, XmlRpcException { // TODO : we need a better way to tell whether or not the VM belongs to CloudStack final String vmName = vm.getNameLabel(conn); @@ -3008,7 +3020,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new ReadyAnswer(cmd); } - protected String getVncUrl(final Connection conn, final VM vm) { + public String getVncUrl(final Connection conn, final VM vm) { VM.Record record; Console c; try { @@ -3679,7 +3691,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return argString.toString(); } - protected boolean setIptables(final Connection conn) { + public boolean setIptables(final Connection conn) { final String result = callHostPlugin(conn, "vmops", "setIptables"); if (result == null || result.isEmpty()) { return false; @@ -4399,7 +4411,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException { + public boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException { dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS); Host.managementReconfigure(conn, dest); String hostUuid = null; @@ -4456,7 +4468,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new StartupCommand[] {cmd}; } - private void cleanupTemplateSR(final Connection conn) { + public void cleanupTemplateSR(final Connection conn) { Set<PBD> pbds = null; try { final Host host = Host.getByUuid(conn, _host.getUuid()); @@ -4493,7 +4505,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected boolean launchHeartBeat(final Connection conn) { + public boolean launchHeartBeat(final Connection conn) { final String result = callHostPluginPremium(conn, "heartbeat", "host", _host.getUuid(), "timeout", Integer.toString(_heartbeatTimeout), @@ -4523,7 +4535,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (_securityGroupEnabled) { - _canBridgeFirewall = can_bridge_firewall(conn); + _canBridgeFirewall = canBridgeFirewall(conn); if (!_canBridgeFirewall) { final String msg = "Failed to configure brige firewall"; s_logger.warn(msg); @@ -4657,7 +4669,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } /* return : if setup is needed */ - protected boolean setupServer(final Connection conn, final Host host) { + public boolean setupServer(final Connection conn, final Host host) { final String packageVersion = CitrixResourceBase.class.getPackage().getImplementationVersion(); final String version = this.getClass().getName() + "-" + (packageVersion == null ? Long.toString(System.currentTimeMillis()) : packageVersion); @@ -5110,10 +5122,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } - protected boolean can_bridge_firewall(final Connection conn) { - return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance)); - } - private Answer execute(final OvsSetupBridgeCommand cmd) { final Connection conn = getConnection(); findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java index a01e192..11ab7ba 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java @@ -71,7 +71,7 @@ public class Xenserver625Resource extends XenServerResourceNewBase { } @Override - protected boolean setupServer(final Connection conn,final Host host) { + public boolean setupServer(final Connection conn,final Host host) { final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22); try { sshConnection.connect(null, 60000, 60000); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java new file mode 100644 index 0000000..d69ce27 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java @@ -0,0 +1,56 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVncPortAnswer; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VM; + +public final class CitrixGetVncPortCommandWrapper extends CommandWrapper<GetVncPortCommand, Answer, CitrixResourceBase> { + + private static final Logger s_logger = Logger.getLogger(CitrixGetVncPortCommandWrapper.class); + + @Override + public Answer execute(final GetVncPortCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Set<VM> vms = VM.getByNameLabel(conn, command.getName()); + if (vms.size() == 1) { + String consoleurl; + consoleurl = "consoleurl=" + citrixResourceBase.getVncUrl(conn, vms.iterator().next()) + "&" + "sessionref=" + conn.getSessionReference(); + return new GetVncPortAnswer(command, consoleurl, -1); + } else { + return new GetVncPortAnswer(command, "There are " + vms.size() + " VMs named " + command.getName()); + } + } catch (final Exception e) { + final String msg = "Unable to get vnc port due to " + e.toString(); + s_logger.warn(msg, e); + return new GetVncPortAnswer(command, msg); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java new file mode 100644 index 0000000..d1c5b70 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java @@ -0,0 +1,75 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import java.util.Iterator; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.MaintainAnswer; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XsHost; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixMaintainCommandWrapper extends CommandWrapper<MaintainCommand, Answer, CitrixResourceBase> { + + private static final Logger s_logger = Logger.getLogger(CitrixMaintainCommandWrapper.class); + + @Override + public Answer execute(final MaintainCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + + final XsHost xsHost = citrixResourceBase.getHost(); + final String uuid = xsHost.getUuid(); + final Host host = Host.getByUuid(conn, uuid); + // remove all tags cloud stack + final Host.Record hr = host.getRecord(conn); + + // Adding this check because could not get the mock to work. Will push the code and fix it afterwards. + if (hr == null) { + s_logger.warn("Host.Record is null."); + return new MaintainAnswer(command, false, "Host.Record is null"); + } + + final Iterator<String> it = hr.tags.iterator(); + while (it.hasNext()) { + final String tag = it.next(); + if (tag.contains("cloud")) { + it.remove(); + } + } + host.setTags(conn, hr.tags); + return new MaintainAnswer(command); + } catch (final XenAPIException e) { + s_logger.warn("Unable to put server in maintainence mode", e); + return new MaintainAnswer(command, false, e.getMessage()); + } catch (final XmlRpcException e) { + s_logger.warn("Unable to put server in maintainence mode", e); + return new MaintainAnswer(command, false, e.getMessage()); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java index c31c340..6d262ee 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java @@ -33,12 +33,15 @@ import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; @@ -93,6 +96,9 @@ public class CitrixRequestWrapper extends RequestWrapper { map.put(UpgradeSnapshotCommand.class, new CitrixUpgradeSnapshotCommandWrapper()); map.put(GetStorageStatsCommand.class, new CitrixGetStorageStatsCommandWrapper()); map.put(PrimaryStorageDownloadCommand.class, new CitrixPrimaryStorageDownloadCommandWrapper()); + map.put(GetVncPortCommand.class, new CitrixGetVncPortCommandWrapper()); + map.put(SetupCommand.class, new CitrixSetupCommandWrapper()); + map.put(MaintainCommand.class, new CitrixMaintainCommandWrapper()); } public static CitrixRequestWrapper getInstance() { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java new file mode 100644 index 0000000..3b24aa3 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java @@ -0,0 +1,200 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.SetupAnswer; +import com.cloud.agent.api.SetupCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Bond; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixSetupCommandWrapper extends CommandWrapper<SetupCommand, Answer, CitrixResourceBase> { + + private static final Logger s_logger = Logger.getLogger(CitrixSetupCommandWrapper.class); + + @Override + public Answer execute(final SetupCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Map<Pool, Pool.Record> poolRecs = Pool.getAllRecords(conn); + if (poolRecs.size() != 1) { + throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + citrixResourceBase.getHost().getUuid()); + } + final Host master = poolRecs.values().iterator().next().master; + citrixResourceBase.setupServer(conn, master); + final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); + citrixResourceBase.setupServer(conn, host); + + if (!citrixResourceBase.setIptables(conn)) { + s_logger.warn("set xenserver Iptable failed"); + return null; + } + + if (citrixResourceBase.isSecurityGroupEnabled()) { + final boolean canBridgeFirewall = citrixResourceBase.canBridgeFirewall(conn); + citrixResourceBase.setCanBridgeFirewall(canBridgeFirewall); + if (!canBridgeFirewall) { + final String msg = "Failed to configure brige firewall"; + s_logger.warn(msg); + s_logger.warn("Check host " + citrixResourceBase.getHost().getIp() +" for CSP is installed or not and check network mode for bridge"); + return new SetupAnswer(command, msg); + } + + } + + + final boolean r = citrixResourceBase.launchHeartBeat(conn); + if (!r) { + return null; + } + citrixResourceBase.cleanupTemplateSR(conn); + try { + if (command.useMultipath()) { + // the config value is set to true + host.addToOtherConfig(conn, "multipathing", "true"); + host.addToOtherConfig(conn, "multipathhandle", "dmp"); + } + + } catch (final Types.MapDuplicateKey e) { + s_logger.debug("multipath is already set"); + } + + if (command.needSetup() ) { + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "setup_iscsi", "uuid", citrixResourceBase.getHost().getUuid()); + + if (!result.contains("> DONE <")) { + s_logger.warn("Unable to setup iscsi: " + result); + return new SetupAnswer(command, result); + } + + Pair<PIF, PIF.Record> mgmtPif = null; + final Set<PIF> hostPifs = host.getPIFs(conn); + for (final PIF pif : hostPifs) { + final PIF.Record rec = pif.getRecord(conn); + if (rec.management) { + if (rec.VLAN != null && rec.VLAN != -1) { + final String msg = + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(citrixResourceBase.getHost().getUuid()) + .append("; pif=") + .append(rec.uuid) + .append("; vlan=") + .append(rec.VLAN) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Management network is on pif=" + rec.uuid); + } + mgmtPif = new Pair<PIF, PIF.Record>(pif, rec); + break; + } + } + + if (mgmtPif == null) { + final String msg = "Unable to find management network for " + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + + final Map<Network, Network.Record> networks = Network.getAllRecords(conn); + if(networks == null) { + final String msg = "Unable to setup as there are no networks in the host: " + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + for (final Network.Record network : networks.values()) { + if (network.nameLabel.equals("cloud-private")) { + for (final PIF pif : network.PIFs) { + final PIF.Record pr = pif.getRecord(conn); + if (citrixResourceBase.getHost().getUuid().equals(pr.host.getUuid(conn))) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a network called cloud-private. host=" + citrixResourceBase.getHost().getUuid() + "; Network=" + network.uuid + "; pif=" + pr.uuid); + } + if (pr.VLAN != null && pr.VLAN != -1) { + final String msg = + new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) + .append(" ; pif=") + .append(pr.uuid) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { + if (pr.bondMasterOf.size() > 1) { + final String msg = + new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) + .append("; pif=") + .append(pr.uuid) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + final Bond bond = pr.bondMasterOf.iterator().next(); + final Set<PIF> slaves = bond.getSlaves(conn); + for (final PIF slave : slaves) { + final PIF.Record spr = slave.getRecord(conn); + if (spr.management) { + if (!citrixResourceBase.transferManagementNetwork(conn, host, slave, spr, pif)) { + final String msg = + new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + + citrixResourceBase.getHost().getUuid()).toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + break; + } + } + } + } + } + } + } + } + return new SetupAnswer(command, false); + + } catch (final XmlRpcException e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } catch (final XenAPIException e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } catch (final Exception e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/637a56c3/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java index 1873842..45bdea1 100644 --- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java @@ -3,18 +3,24 @@ package com.cloud.hypervisor.xenserver.resource.wrapper; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Map; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.xmlrpc.client.XmlRpcClient; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; @@ -28,6 +34,8 @@ import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -35,6 +43,7 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; @@ -47,14 +56,19 @@ import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.host.HostEnvironment; import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; import com.cloud.hypervisor.xenserver.resource.XsHost; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.vm.DiskProfile; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Marshalling; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PrepareForTest({Connection.class, Host.Record.class}) public class CitrixRequestWrapperTest { @Mock @@ -440,6 +454,106 @@ public class CitrixRequestWrapperTest { assertFalse(answer.getResult()); } + + @Test + public void testGetVncPortCommand() { + final GetVncPortCommand storageDownloadCommand = new GetVncPortCommand(1l, "Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(storageDownloadCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testSetupCommand() { + final XsHost xsHost = Mockito.mock(XsHost.class); + final HostEnvironment env = Mockito.mock(HostEnvironment.class); + + final SetupCommand storageDownloadCommand = new SetupCommand(env); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(storageDownloadCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testMaintainCommand() { + // This test needs further work. + + final String uuid = "befc4dcd-f5c6-4015-8791-3c18622b7c7f"; + + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + final XmlRpcClient client = Mockito.mock(XmlRpcClient.class); + + // final Host.Record hr = PowerMockito.mock(Host.Record.class); + // final Host host = PowerMockito.mock(Host.class); + + final MaintainCommand storageDownloadCommand = new MaintainCommand(); + + final Map<String, Object> map = new Hashtable<String, Object>(); + map.put("Value", "Xen"); + + final Map<String, Object> spiedMap = spy(map); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(xsHost.getUuid()).thenReturn(uuid); + when(conn.getSessionReference()).thenReturn("befc4dcd"); + + try { + final Object [] params = {Marshalling.toXMLRPC("befc4dcd"), Marshalling.toXMLRPC(uuid)}; + when(client.execute("host.get_by_uuid", new Object[]{"befc4dcd", uuid})).thenReturn(spiedMap); + PowerMockito.when(conn, "dispatch", "host.get_by_uuid", params).thenReturn(spiedMap); + } catch (final Exception e) { + } + + // try { + // PowerMockito.mockStatic(Host.class); + // //BDDMockito.given(Host.getByUuid(conn, xsHost.getUuid())).willReturn(host); + // PowerMockito.when(Host.getByUuid(conn, xsHost.getUuid())).thenReturn(host); + // PowerMockito.verifyStatic(times(1)); + // } catch (final BadServerResponse e) { + // fail(e.getMessage()); + // } catch (final XenAPIException e) { + // fail(e.getMessage()); + // } catch (final XmlRpcException e) { + // fail(e.getMessage()); + // } + // + // PowerMockito.mockStatic(Types.class); + // PowerMockito.when(Types.toHostRecord(spiedMap)).thenReturn(hr); + // PowerMockito.verifyStatic(times(1)); + // + // try { + // PowerMockito.mockStatic(Host.Record.class); + // when(host.getRecord(conn)).thenReturn(hr); + // verify(host, times(1)).getRecord(conn); + // } catch (final BadServerResponse e) { + // fail(e.getMessage()); + // } catch (final XenAPIException e) { + // fail(e.getMessage()); + // } catch (final XmlRpcException e) { + // fail(e.getMessage()); + // } + + final Answer answer = wrapper.execute(storageDownloadCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } } class NotAValidCommand extends Command {