From a1e87782116671521f73a23bb36fd788345366cb Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 19 Mar 2015 15:37:08 +0100 Subject: [PATCH] First piece of the refactor of the CitrisResourceBase - The same pattern will be used by the other subclasses of the ServerResource interface. --- .../com/cloud/resource/CommandWrapper.java | 34 +++++ .../com/cloud/resource/RequestWrapper.java | 32 ++++ .../resource/CitrixResourceBase.java | 6 +- .../resource/XenServer56Resource.java | 141 +++++++++--------- .../CitrixRebootRouterCommandWrapper.java | 50 +++++++ .../wrapper/CitrixRequestWrapper.java | 63 ++++++++ .../wrapper/CitrixRequestWrapperTest.java | 52 +++++++ 7 files changed, 304 insertions(+), 74 deletions(-) create mode 100644 core/src/com/cloud/resource/CommandWrapper.java create mode 100644 core/src/com/cloud/resource/RequestWrapper.java create mode 100644 plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java create mode 100644 plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java create mode 100644 plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java diff --git a/core/src/com/cloud/resource/CommandWrapper.java b/core/src/com/cloud/resource/CommandWrapper.java new file mode 100644 index 00000000000..f68e92a2327 --- /dev/null +++ b/core/src/com/cloud/resource/CommandWrapper.java @@ -0,0 +1,34 @@ +// +// 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.resource; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + + +public abstract class CommandWrapper { + + /** + * @param T is the command to be used. + * @param R is the resource base to be used. + * @return A and the Answer from the command. + */ + public abstract A execute(T command, R serverResource); +} \ No newline at end of file diff --git a/core/src/com/cloud/resource/RequestWrapper.java b/core/src/com/cloud/resource/RequestWrapper.java new file mode 100644 index 00000000000..6fd1c668855 --- /dev/null +++ b/core/src/com/cloud/resource/RequestWrapper.java @@ -0,0 +1,32 @@ +// +// 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.resource; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public abstract class RequestWrapper { + + /** + * @param command to be executed. + * @return an Answer for the executed command. + */ + public abstract Answer execute(Command command, ServerResource serverResource); +} \ No newline at end of file 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 96374e4ca8d..73f11c22e89 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 @@ -2047,7 +2047,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { + public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { if (option.equals("get")) { return "0:0"; } @@ -3096,7 +3096,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected Answer execute(final RebootRouterCommand cmd) { + public Answer execute(final RebootRouterCommand cmd) { final Connection conn = getConnection(); final RebootAnswer answer = execute((RebootCommand)cmd); if (answer.getResult()) { @@ -3630,7 +3630,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return msg; } - protected String connect(final Connection conn, final String vmname, final String ipAddress) { + public String connect(final Connection conn, final String vmname, final String ipAddress) { return connect(conn, vmname, ipAddress, 3922); } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java index eec972e6b64..a8e9efac9aa 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java @@ -26,15 +26,6 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Types.IpConfigurationMode; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; @@ -49,13 +40,21 @@ import com.cloud.utils.ExecutionResult; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SSHCmdHelper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.IpConfigurationMode; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { private final static Logger s_logger = Logger.getLogger(XenServer56Resource.class); @Override - public Answer executeRequest(Command cmd) { + public Answer executeRequest(final Command cmd) { if (cmd instanceof FenceCommand) { return execute((FenceCommand)cmd); } else if (cmd instanceof NetworkUsageCommand) { @@ -68,63 +67,63 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } @Override - protected void disableVlanNetwork(Connection conn, Network network) { + protected void disableVlanNetwork(final Connection conn, final Network network) { try { - Network.Record networkr = network.getRecord(conn); + final Network.Record networkr = network.getRecord(conn); if (!networkr.nameLabel.startsWith("VLAN")) { return; } - String bridge = networkr.bridge.trim(); - for (PIF pif : networkr.PIFs) { - PIF.Record pifr = pif.getRecord(conn); + final String bridge = networkr.bridge.trim(); + for (final PIF pif : networkr.PIFs) { + final PIF.Record pifr = pif.getRecord(conn); if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.uuid)) { continue; } - VLAN vlan = pifr.VLANMasterOf; + final VLAN vlan = pifr.VLANMasterOf; if (vlan != null) { - String vlannum = pifr.VLAN.toString(); - String device = pifr.device.trim(); + final String vlannum = pifr.VLAN.toString(); + final String device = pifr.device.trim(); if (vlannum.equals("-1")) { return; } try { vlan.destroy(conn); - Host host = Host.getByUuid(conn, _host.uuid); + final Host host = Host.getByUuid(conn, _host.uuid); host.forgetDataSourceArchives(conn, "pif_" + bridge + "_tx"); host.forgetDataSourceArchives(conn, "pif_" + bridge + "_rx"); host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx"); host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx"); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.uuid + " due to " + e.toString()); } } return; } - } catch (XenAPIException e) { - String msg = "Unable to disable VLAN network due to " + e.toString(); + } catch (final XenAPIException e) { + final String msg = "Unable to disable VLAN network due to " + e.toString(); s_logger.warn(msg, e); - } catch (Exception e) { - String msg = "Unable to disable VLAN network due to " + e.getMessage(); + } catch (final Exception e) { + final String msg = "Unable to disable VLAN network due to " + e.getMessage(); s_logger.warn(msg, e); } } @Override - protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { + public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { String args = ""; if (option.equals("get")) { args += "-g"; @@ -143,18 +142,18 @@ public class XenServer56Resource extends CitrixResourceBase { return executeInVR(privateIpAddress, "netusage.sh", args).getDetails(); } - protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { + protected NetworkUsageAnswer VPCNetworkUsage(final NetworkUsageCommand cmd) { try { - Connection conn = getConnection(); - String option = cmd.getOption(); - String publicIp = cmd.getGatewayIP(); + final Connection conn = getConnection(); + final String option = cmd.getOption(); + final String publicIp = cmd.getGatewayIP(); String args = " -l " + publicIp + " "; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { args += "-c"; - String vpcCIDR = cmd.getVpcCIDR(); + final String vpcCIDR = cmd.getVpcCIDR(); args += " -v " + vpcCIDR; } else if (option.equals("reset")) { args += "-r"; @@ -166,67 +165,67 @@ public class XenServer56Resource extends CitrixResourceBase { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - ExecutionResult result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args); - String detail = result.getDetails(); + final ExecutionResult result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args); + final String detail = result.getDetails(); if (!result.isSuccess()) { throw new Exception(" vpc network usage plugin call failed "); } if (option.equals("get") || option.equals("vpn")) { - long[] stats = new long[2]; + final long[] stats = new long[2]; if (detail != null) { - String[] splitResult = detail.split(":"); + final String[] splitResult = detail.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += new Long(splitResult[i++]).longValue(); + stats[1] += new Long(splitResult[i++]).longValue(); } return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); } } return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.warn("Failed to get network usage stats due to ", ex); return new NetworkUsageAnswer(cmd, ex); } } - protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { + protected NetworkUsageAnswer execute(final NetworkUsageCommand cmd) { if (cmd.isForVpc()) { return VPCNetworkUsage(cmd); } try { - Connection conn = getConnection(); + final Connection conn = getConnection(); if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } - long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); + final long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); return answer; - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.warn("Failed to get network usage stats due to ", ex); return new NetworkUsageAnswer(cmd, ex); } } - protected Boolean check_heartbeat(String hostuuid) { - com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.ip, 22); + protected Boolean check_heartbeat(final String hostuuid) { + final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.ip, 22); try { sshConnection.connect(null, 60000, 60000); if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { throw new CloudRuntimeException("Unable to authenticate"); } - String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " - + Integer.toString(_heartbeatInterval * 2); + final String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " + + Integer.toString(_heartbeatInterval * 2); if (!SSHCmdHelper.sshExecuteCmd(sshConnection, shcmd)) { s_logger.debug("Heart beat is gone so dead."); return false; } s_logger.debug("Heart beat is still going"); return true; - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("health check failed due to catch exception " + e.toString()); return null; } finally { @@ -234,10 +233,10 @@ public class XenServer56Resource extends CitrixResourceBase { } } - protected FenceAnswer execute(FenceCommand cmd) { - Connection conn = getConnection(); + protected FenceAnswer execute(final FenceCommand cmd) { + final Connection conn = getConnection(); try { - Boolean alive = check_heartbeat(cmd.getHostGuid()); + final Boolean alive = check_heartbeat(cmd.getHostGuid()); if ( alive == null ) { s_logger.debug("Failed to check heartbeat, so unable to fence"); return new FenceAnswer(cmd, false, "Failed to check heartbeat, so unable to fence"); @@ -246,17 +245,17 @@ public class XenServer56Resource extends CitrixResourceBase { s_logger.debug("Heart beat is still going so unable to fence"); return new FenceAnswer(cmd, false, "Heartbeat is still going on unable to fence"); } - Set vms = VM.getByNameLabel(conn, cmd.getVmName()); - for (VM vm : vms) { + final Set vms = VM.getByNameLabel(conn, cmd.getVmName()); + for (final VM vm : vms) { s_logger.info("Fence command for VM " + cmd.getVmName()); vm.powerStateReset(conn); vm.destroy(conn); } return new FenceAnswer(cmd); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.warn("Unable to fence", e); return new FenceAnswer(cmd, false, e.getMessage()); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.warn("Unable to fence", e); return new FenceAnswer(cmd, false, e.getMessage()); } @@ -264,11 +263,11 @@ public class XenServer56Resource extends CitrixResourceBase { @Override - protected boolean transferManagementNetwork(Connection conn, Host host, PIF src, PIF.Record spr, PIF dest) throws XmlRpcException, XenAPIException { + protected 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; - int count = 0; + final int count = 0; while (count < 10) { try { Thread.sleep(10000); @@ -276,11 +275,11 @@ public class XenServer56Resource extends CitrixResourceBase { if (hostUuid != null) { break; } - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { s_logger.debug("Gotta run"); return false; } @@ -297,21 +296,21 @@ public class XenServer56Resource extends CitrixResourceBase { @Override public StartupCommand[] initialize() { pingXAPI(); - StartupCommand[] cmds = super.initialize(); + final StartupCommand[] cmds = super.initialize(); return cmds; } @Override - protected CheckOnHostAnswer execute(CheckOnHostCommand cmd) { - Boolean alive = check_heartbeat(cmd.getHost().getGuid()); + protected CheckOnHostAnswer execute(final CheckOnHostCommand cmd) { + final Boolean alive = check_heartbeat(cmd.getHost().getGuid()); String msg = ""; if (alive == null) { - msg = " cannot determine "; + msg = " cannot determine "; } else if ( alive == true) { - msg = "Heart beat is still going"; + msg = "Heart beat is still going"; } else { - msg = "Heart beat is gone so dead."; + msg = "Heart beat is gone so dead."; } s_logger.debug(msg); return new CheckOnHostAnswer(cmd, alive, msg); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java new file mode 100644 index 00000000000..c244335119c --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java @@ -0,0 +1,50 @@ +// +// 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 com.cloud.agent.api.Answer; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixRebootRouterCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final RebootRouterCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + final RebootAnswer answer = citrixResourceBase.execute((RebootCommand)command); + + if (answer.getResult()) { + final String cnct = citrixResourceBase.connect(conn, command.getVmName(), command.getPrivateIpAddress()); + citrixResourceBase.networkUsage(conn, command.getPrivateIpAddress(), "create", null); + + if (cnct == null) { + return answer; + } else { + return new Answer(command, false, cnct); + } + } + return answer; + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..124b2973844 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java @@ -0,0 +1,63 @@ +// +// 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.Hashtable; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.RequestWrapper; +import com.cloud.resource.ServerResource; + +public class CitrixRequestWrapper extends RequestWrapper { + + private static CitrixRequestWrapper instance; + + static { + instance = new CitrixRequestWrapper(); + } + + @SuppressWarnings("rawtypes") + private final Hashtable, CommandWrapper> map; + + @SuppressWarnings("rawtypes") + private CitrixRequestWrapper() { + map = new Hashtable, CommandWrapper>(); + init(); + } + + private void init() { + map.put(RebootRouterCommand.class, new CitrixRebootRouterCommandWrapper()); + } + + public static CitrixRequestWrapper getInstance() { + return instance; + } + + @Override + public Answer execute(final Command command, final ServerResource serverResource) { + @SuppressWarnings("unchecked") + final CommandWrapper commandWrapper = map.get(command.getClass()); + + return commandWrapper.execute(command, serverResource); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..aa4ebb9f100 --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java @@ -0,0 +1,52 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; + +@RunWith(MockitoJUnitRunner.class) +public class CitrixRequestWrapperTest { + + @Mock + protected CitrixResourceBase citrixResourceBase; + @Mock + protected RebootAnswer rebootAnswer; + + @Test + public void testWrapperInstance() { + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + } + + @Test + public void testExecuteRebootRouterCommand() { + final RebootRouterCommand rebootCommand = new RebootRouterCommand("", ""); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + doReturn(rebootAnswer).when(citrixResourceBase).execute((RebootCommand)rebootCommand); + doReturn(false).when(rebootAnswer).getResult(); + + final Answer answer = wrapper.execute(rebootCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).execute((RebootCommand)rebootCommand); + + assertFalse(rebootAnswer.getResult()); + assertEquals(answer, rebootAnswer); + } +} \ No newline at end of file