Refactoring other 8 command wrapper in order to cope with the new design

- Advanced unit tests added for half of the commands
  - Basic unit tests added for the other half
This commit is contained in:
wilderrodrigues 2015-03-30 17:31:09 +02:00
parent fbcae54a5b
commit 24bbfbc1e6
11 changed files with 968 additions and 25 deletions

View File

@ -346,6 +346,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return _instance;
}
public void addToPwdQueue(final String password) {
_password.add(password);
}
public boolean isOvs() {
return _isOvs;
}
@ -467,24 +471,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
if (cmd instanceof NetworkElementCommand) {
return _vrResource.executeRequest((NetworkElementCommand)cmd);
} else if (clazz == UpdateHostPasswordCommand.class) {
return execute((UpdateHostPasswordCommand)cmd);
} else if (cmd instanceof ClusterVMMetaDataSyncCommand) {
return execute((ClusterVMMetaDataSyncCommand)cmd);
} else if (clazz == CheckNetworkCommand.class) {
return execute((CheckNetworkCommand)cmd);
} else if (clazz == PlugNicCommand.class) {
return execute((PlugNicCommand)cmd);
} else if (clazz == UnPlugNicCommand.class) {
return execute((UnPlugNicCommand) cmd);
} else if (cmd instanceof StorageSubSystemCommand) {
return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
} else if (clazz == CreateVMSnapshotCommand.class) {
return execute((CreateVMSnapshotCommand) cmd);
} else if (clazz == DeleteVMSnapshotCommand.class) {
return execute((DeleteVMSnapshotCommand) cmd);
} else if (clazz == RevertToVMSnapshotCommand.class) {
return execute((RevertToVMSnapshotCommand) cmd);
} else if (clazz == NetworkRulesVmSecondaryIpCommand.class) {
return execute((NetworkRulesVmSecondaryIpCommand) cmd);
} else if (clazz == ScaleVmCommand.class) {
@ -798,7 +786,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
protected String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) throws XenAPIException,
public String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) throws XenAPIException,
XmlRpcException {
final String results =
@ -3137,7 +3125,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return false;
}
protected void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
public void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
final long beginTime = System.currentTimeMillis();
if (s_logger.isTraceEnabled()) {
s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
@ -3161,7 +3149,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
protected void checkForSuccess(final Connection c, final Task task) throws XenAPIException, XmlRpcException {
public void checkForSuccess(final Connection c, final Task task) throws XenAPIException, XmlRpcException {
if (task.getStatus(c) == Types.TaskStatusType.SUCCESS) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") completed");
@ -3748,7 +3736,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return null;
}
protected VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException {
public VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException {
final Set<VIF> routerVIFs = router.getVIFs(conn);
mac = mac.trim();
for (final VIF vif : routerVIFs) {
@ -3760,7 +3748,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return null;
}
protected String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) {
public String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) {
String vmName = "";
try {
vmName = vm.getNameLabel(conn);
@ -4811,7 +4799,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
protected boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException {
public boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException {
if (nameTag != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Looking for network setup by name " + nameTag);
@ -6194,7 +6182,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
private long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName) throws BadServerResponse, XenAPIException, XmlRpcException {
public long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName) throws BadServerResponse, XenAPIException, XmlRpcException {
final Set<VDI> allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName());
long size = 0;
for (final VDI vdi : allvolumeVDIs) {
@ -6378,7 +6366,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
private VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List<VolumeObjectTO> listVolumeTo) throws BadServerResponse,
public VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List<VolumeObjectTO> listVolumeTo) throws BadServerResponse,
Types.VmBadPowerState, Types.SrFull,
Types.OperationNotAllowed, XenAPIException, XmlRpcException {
//below is redundant but keeping for consistency and code readabilty
@ -6928,7 +6916,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), vmMetadatum);
}
protected HashMap<String, String> clusterVMMetaDataSync(final Connection conn) {
public HashMap<String, String> clusterVMMetaDataSync(final Connection conn) {
final HashMap<String, String> vmMetaDatum = new HashMap<String, String>();
try {
final Map<VM, VM.Record> vm_map = VM.getAllRecords(conn); //USE THIS TO GET ALL VMS FROM A CLUSTER

View File

@ -0,0 +1,94 @@
//
// 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.List;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.network.PhysicalNetworkSetupInfo;
import com.cloud.resource.CommandWrapper;
import com.xensource.xenapi.Types.XenAPIException;
public final class CitrixCheckNetworkCommandWrapper extends CommandWrapper<CheckNetworkCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixCheckNetworkCommandWrapper.class);
@Override
public Answer execute(final CheckNetworkCommand command, final CitrixResourceBase citrixResourceBase) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Checking if network name setup is done on the resource");
}
final List<PhysicalNetworkSetupInfo> infoList = command.getPhysicalNetworkInfoList();
try {
boolean errorout = false;
String msg = "";
for (final PhysicalNetworkSetupInfo info : infoList) {
if (!citrixResourceBase.isNetworkSetupByName(info.getGuestNetworkName())) {
msg =
"For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " +
info.getGuestNetworkName();
errorout = true;
break;
}
if (!citrixResourceBase.isNetworkSetupByName(info.getPrivateNetworkName())) {
msg =
"For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " +
info.getPrivateNetworkName();
errorout = true;
break;
}
if (!citrixResourceBase.isNetworkSetupByName(info.getPublicNetworkName())) {
msg =
"For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " +
info.getPublicNetworkName();
errorout = true;
break;
}
/*if(!isNetworkSetupByName(info.getStorageNetworkName())){
msg = "For Physical Network id:"+ info.getPhysicalNetworkId() + ", Storage Network is not configured on the backend by name " + info.getStorageNetworkName();
errorout = true;
break;
}*/
}
if (errorout) {
s_logger.error(msg);
return new CheckNetworkAnswer(command, false, msg);
} else {
return new CheckNetworkAnswer(command, true, "Network Setup check by names is done");
}
} catch (final XenAPIException e) {
final String msg = "CheckNetworkCommand failed with XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid();
s_logger.warn(msg, e);
return new CheckNetworkAnswer(command, false, msg);
} catch (final Exception e) {
final String msg = "CheckNetworkCommand failed with Exception:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid();
s_logger.warn(msg, e);
return new CheckNetworkAnswer(command, false, msg);
}
}
}

View File

@ -0,0 +1,57 @@
//
// 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.HashMap;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Host;
import com.xensource.xenapi.Pool;
public final class CitrixClusterVMMetaDataSyncCommandWrapper extends CommandWrapper<ClusterVMMetaDataSyncCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixClusterVMMetaDataSyncCommandWrapper.class);
@Override
public Answer execute(final ClusterVMMetaDataSyncCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
//check if this is master
try {
final Pool pool = Pool.getByUuid(conn, citrixResourceBase.getHost().getPool());
final Pool.Record poolr = pool.getRecord(conn);
final Host.Record hostr = poolr.master.getRecord(conn);
if (!citrixResourceBase.getHost().getUuid().equals(hostr.uuid)) {
return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), null);
}
} catch (final Throwable e) {
s_logger.warn("Check for master failed, failing the Cluster sync VMMetaData command");
return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), null);
}
final HashMap<String, String> vmMetadatum = citrixResourceBase.clusterVMMetaDataSync(conn);
return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), vmMetadatum);
}
}

View File

@ -0,0 +1,188 @@
//
// 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.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreateVMSnapshotAnswer;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.vm.snapshot.VMSnapshot;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Pool;
import com.xensource.xenapi.SR;
import com.xensource.xenapi.Task;
import com.xensource.xenapi.Types;
import com.xensource.xenapi.Types.VmPowerState;
import com.xensource.xenapi.VBD;
import com.xensource.xenapi.VDI;
import com.xensource.xenapi.VM;
public final class CitrixCreateVMSnapshotCommandWrapper extends CommandWrapper<CreateVMSnapshotCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixCreateVMSnapshotCommandWrapper.class);
@Override
public Answer execute(final CreateVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) {
final String vmName = command.getVmName();
final String vmSnapshotName = command.getTarget().getSnapshotName();
final List<VolumeObjectTO> listVolumeTo = command.getVolumeTOs();
VmPowerState vmState = VmPowerState.HALTED;
final String guestOSType = command.getGuestOSType();
final String platformEmulator = command.getPlatformEmulator();
final boolean snapshotMemory = command.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
final long timeout = command.getWait();
final Connection conn = citrixResourceBase.getConnection();
VM vm = null;
VM vmSnapshot = null;
boolean success = false;
try {
// check if VM snapshot already exists
final Set<VM> vmSnapshots = VM.getByNameLabel(conn, command.getTarget().getSnapshotName());
if (vmSnapshots == null || vmSnapshots.size() > 0) {
return new CreateVMSnapshotAnswer(command, command.getTarget(), command.getVolumeTOs());
}
// check if there is already a task for this VM snapshot
Task task = null;
Set<Task> tasks = Task.getByNameLabel(conn, "Async.VM.snapshot");
if(tasks == null) {
tasks = new LinkedHashSet<>();
}
final Set<Task> tasksByName = Task.getByNameLabel(conn, "Async.VM.checkpoint");
if(tasksByName != null) {
tasks.addAll(tasksByName);
}
for (final Task taskItem : tasks) {
if (taskItem.getOtherConfig(conn).containsKey("CS_VM_SNAPSHOT_KEY")) {
final String vmSnapshotTaskName = taskItem.getOtherConfig(conn).get("CS_VM_SNAPSHOT_KEY");
if (vmSnapshotTaskName != null && vmSnapshotTaskName.equals(command.getTarget().getSnapshotName())) {
task = taskItem;
}
}
}
// create a new task if there is no existing task for this VM snapshot
if (task == null) {
try {
vm = citrixResourceBase.getVM(conn, vmName);
vmState = vm.getPowerState(conn);
} catch (final Exception e) {
if (!snapshotMemory) {
vm = citrixResourceBase.createWorkingVM(conn, vmName, guestOSType, platformEmulator, listVolumeTo);
}
}
if (vm == null) {
return new CreateVMSnapshotAnswer(command, false, "Creating VM Snapshot Failed due to can not find vm: " + vmName);
}
// call Xenserver API
if (!snapshotMemory) {
task = vm.snapshotAsync(conn, vmSnapshotName);
} else {
final Set<VBD> vbds = vm.getVBDs(conn);
final Pool pool = Pool.getByUuid(conn, citrixResourceBase.getHost().getPool());
for (final VBD vbd : vbds) {
final VBD.Record vbdr = vbd.getRecord(conn);
if (vbdr.userdevice.equals("0")) {
final VDI vdi = vbdr.VDI;
final SR sr = vdi.getSR(conn);
// store memory image on the same SR with ROOT volume
pool.setSuspendImageSR(conn, sr);
}
}
task = vm.checkpointAsync(conn, vmSnapshotName);
}
task.addToOtherConfig(conn, "CS_VM_SNAPSHOT_KEY", vmSnapshotName);
}
citrixResourceBase.waitForTask(conn, task, 1000, timeout * 1000);
citrixResourceBase.checkForSuccess(conn, task);
final String result = task.getResult(conn);
// extract VM snapshot ref from result
final String ref = result.substring("<value>".length(), result.length() - "</value>".length());
vmSnapshot = Types.toVM(ref);
try {
Thread.sleep(5000);
} catch (final InterruptedException ex) {
}
// calculate used capacity for this VM snapshot
for (final VolumeObjectTO volumeTo : command.getVolumeTOs()) {
final long size = citrixResourceBase.getVMSnapshotChainSize(conn, volumeTo, command.getVmName());
volumeTo.setSize(size);
}
success = true;
return new CreateVMSnapshotAnswer(command, command.getTarget(), command.getVolumeTOs());
} catch (final Exception e) {
String msg = "";
if (e instanceof Types.BadAsyncResult) {
final String licenseKeyWord = "LICENCE_RESTRICTION";
final Types.BadAsyncResult errorResult = (Types.BadAsyncResult)e;
if (errorResult.shortDescription != null && errorResult.shortDescription.contains(licenseKeyWord)) {
msg = licenseKeyWord;
}
} else {
msg = e.toString();
}
s_logger.warn("Creating VM Snapshot " + command.getTarget().getSnapshotName() + " failed due to: " + msg, e);
return new CreateVMSnapshotAnswer(command, false, msg);
} finally {
try {
if (!success) {
if (vmSnapshot != null) {
s_logger.debug("Delete exsisting VM Snapshot " + vmSnapshotName + " after making VolumeTO failed");
final Set<VBD> vbds = vmSnapshot.getVBDs(conn);
for (final VBD vbd : vbds) {
final VBD.Record vbdr = vbd.getRecord(conn);
if (vbdr.type == Types.VbdType.DISK) {
final VDI vdi = vbdr.VDI;
vdi.destroy(conn);
}
}
vmSnapshot.destroy(conn);
}
}
if (vmState == VmPowerState.HALTED) {
if (vm != null) {
vm.destroy(conn);
}
}
} catch (final Exception e2) {
s_logger.error("delete snapshot error due to " + e2.getMessage());
}
}
}
}

View File

@ -0,0 +1,90 @@
//
// 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.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
import com.cloud.agent.api.DeleteVMSnapshotCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.vm.snapshot.VMSnapshot;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Types;
import com.xensource.xenapi.VBD;
import com.xensource.xenapi.VDI;
import com.xensource.xenapi.VM;
public final class CitrixDeleteVMSnapshotCommandWrapper extends CommandWrapper<DeleteVMSnapshotCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixDeleteVMSnapshotCommandWrapper.class);
@Override
public Answer execute(final DeleteVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) {
final String snapshotName = command.getTarget().getSnapshotName();
final Connection conn = citrixResourceBase.getConnection();
try {
final List<VDI> vdiList = new ArrayList<VDI>();
final Set<VM> snapshots = VM.getByNameLabel(conn, snapshotName);
if (snapshots == null || snapshots.size() == 0) {
s_logger.warn("VM snapshot with name " + snapshotName + " does not exist, assume it is already deleted");
return new DeleteVMSnapshotAnswer(command, command.getVolumeTOs());
}
final VM snapshot = snapshots.iterator().next();
final Set<VBD> vbds = snapshot.getVBDs(conn);
for (final VBD vbd : vbds) {
if (vbd.getType(conn) == Types.VbdType.DISK) {
final VDI vdi = vbd.getVDI(conn);
vdiList.add(vdi);
}
}
if (command.getTarget().getType() == VMSnapshot.Type.DiskAndMemory) {
vdiList.add(snapshot.getSuspendVDI(conn));
}
snapshot.destroy(conn);
for (final VDI vdi : vdiList) {
vdi.destroy(conn);
}
try {
Thread.sleep(5000);
} catch (final InterruptedException ex) {
}
// re-calculate used capacify for this VM snapshot
for (final VolumeObjectTO volumeTo : command.getVolumeTOs()) {
final long size = citrixResourceBase.getVMSnapshotChainSize(conn, volumeTo, command.getVmName());
volumeTo.setSize(size);
}
return new DeleteVMSnapshotAnswer(command, command.getVolumeTOs());
} catch (final Exception e) {
s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e);
return new DeleteVMSnapshotAnswer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,92 @@
//
// 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.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.VIF;
import com.xensource.xenapi.VM;
public final class CitrixPlugNicCommandWrapper extends CommandWrapper<PlugNicCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixPlugNicCommandWrapper.class);
@Override
public Answer execute(final PlugNicCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
final String vmName = command.getVmName();
try {
final Set<VM> vms = VM.getByNameLabel(conn, vmName);
if (vms == null || vms.isEmpty()) {
return new PlugNicAnswer(command, false, "Can not find VM " + vmName);
}
final VM vm = vms.iterator().next();
final NicTO nic = command.getNic();
String mac = nic.getMac();
final Set<VIF> routerVIFs = vm.getVIFs(conn);
mac = mac.trim();
int counter = 0;
for (final VIF vif : routerVIFs) {
final String lmac = vif.getMAC(conn);
if (lmac.trim().equals(mac)) {
counter++;
}
}
// We allow 2 routers with the same mac. It's needed for the redundant vpc routers.
// [FIXME] Find a way to identify the type of the router or if it's
// redundant.
if (counter > 2) {
final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists in more than 2 routers.";
s_logger.error(msg);
return new PlugNicAnswer(command, false, msg);
}
// Wilder Rodrigues - replaced this code with the code above.
// VIF vif = getVifByMac(conn, vm, nic.getMac());
// if (vif != null) {
// final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists";
// s_logger.warn(msg);
// return new PlugNicAnswer(cmd, false, msg);
// }
final String deviceId = citrixResourceBase.getLowestAvailableVIFDeviceNum(conn, vm);
nic.setDeviceId(Integer.parseInt(deviceId));
final VIF vif = citrixResourceBase.createVif(conn, vmName, vm, null, nic);
// vif = createVif(conn, vmName, vm, null, nic);
vif.plug(conn);
return new PlugNicAnswer(command, true, "success");
} catch (final Exception e) {
final String msg = " Plug Nic failed due to " + e.toString();
s_logger.error(msg, e);
return new PlugNicAnswer(command, false, msg);
}
}
}

View File

@ -25,12 +25,16 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckOnHostCommand;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.DeleteVMSnapshotCommand;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
@ -52,14 +56,18 @@ import com.cloud.agent.api.OvsSetupBridgeCommand;
import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PlugNicCommand;
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.RevertToVMSnapshotCommand;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
@ -135,6 +143,14 @@ public class CitrixRequestWrapper extends RequestWrapper {
map.put(OvsSetupBridgeCommand.class, new CitrixOvsSetupBridgeCommandWrapper());
map.put(OvsDestroyBridgeCommand.class, new CitrixOvsDestroyBridgeCommandWrapper());
map.put(OvsDestroyTunnelCommand.class, new CitrixOvsDestroyTunnelCommandWrapper());
map.put(UpdateHostPasswordCommand.class, new CitrixUpdateHostPasswordCommandWrapper());
map.put(ClusterVMMetaDataSyncCommand.class, new CitrixClusterVMMetaDataSyncCommandWrapper());
map.put(CheckNetworkCommand.class, new CitrixCheckNetworkCommandWrapper());
map.put(PlugNicCommand.class, new CitrixPlugNicCommandWrapper());
map.put(UnPlugNicCommand.class, new CitrixUnPlugNicCommandWrapper());
map.put(CreateVMSnapshotCommand.class, new CitrixCreateVMSnapshotCommandWrapper());
map.put(DeleteVMSnapshotCommand.class, new CitrixDeleteVMSnapshotCommandWrapper());
map.put(RevertToVMSnapshotCommand.class, new CitrixRevertToVMSnapshotCommandWrapper());
}
public static CitrixRequestWrapper getInstance() {

View File

@ -0,0 +1,110 @@
//
// 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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
import com.cloud.agent.api.RevertToVMSnapshotCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.vm.VirtualMachine.PowerState;
import com.cloud.vm.snapshot.VMSnapshot;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Types;
import com.xensource.xenapi.VBD;
import com.xensource.xenapi.VDI;
import com.xensource.xenapi.VM;
public final class CitrixRevertToVMSnapshotCommandWrapper extends CommandWrapper<RevertToVMSnapshotCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixRevertToVMSnapshotCommandWrapper.class);
@Override
public Answer execute(final RevertToVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) {
final String vmName = command.getVmName();
final List<VolumeObjectTO> listVolumeTo = command.getVolumeTOs();
final VMSnapshot.Type vmSnapshotType = command.getTarget().getType();
final Boolean snapshotMemory = vmSnapshotType == VMSnapshot.Type.DiskAndMemory;
final Connection conn = citrixResourceBase.getConnection();
PowerState vmState = null;
VM vm = null;
try {
final Set<VM> vmSnapshots = VM.getByNameLabel(conn, command.getTarget().getSnapshotName());
if (vmSnapshots == null || vmSnapshots.size() == 0) {
return new RevertToVMSnapshotAnswer(command, false, "Cannot find vmSnapshot with name: " + command.getTarget().getSnapshotName());
}
final VM vmSnapshot = vmSnapshots.iterator().next();
// find target VM or creating a work VM
try {
vm = citrixResourceBase.getVM(conn, vmName);
} catch (final Exception e) {
vm = citrixResourceBase.createWorkingVM(conn, vmName, command.getGuestOSType(), command.getPlatformEmulator(), listVolumeTo);
}
if (vm == null) {
return new RevertToVMSnapshotAnswer(command, false, "Revert to VM Snapshot Failed due to can not find vm: " + vmName);
}
// call plugin to execute revert
citrixResourceBase.revertToSnapshot(conn, vmSnapshot, vmName, vm.getUuid(conn), snapshotMemory, citrixResourceBase.getHost().getUuid());
vm = citrixResourceBase.getVM(conn, vmName);
final Set<VBD> vbds = vm.getVBDs(conn);
final Map<String, VDI> vdiMap = new HashMap<String, VDI>();
// get vdi:vbdr to a map
for (final VBD vbd : vbds) {
final VBD.Record vbdr = vbd.getRecord(conn);
if (vbdr.type == Types.VbdType.DISK) {
final VDI vdi = vbdr.VDI;
vdiMap.put(vbdr.userdevice, vdi);
}
}
if (!snapshotMemory) {
vm.destroy(conn);
vmState = PowerState.PowerOff;
} else {
vmState = PowerState.PowerOn;
}
// after revert, VM's volumes path have been changed, need to report to manager
for (final VolumeObjectTO volumeTo : listVolumeTo) {
final Long deviceId = volumeTo.getDeviceId();
final VDI vdi = vdiMap.get(deviceId.toString());
volumeTo.setPath(vdi.getUuid(conn));
}
return new RevertToVMSnapshotAnswer(command, listVolumeTo, vmState);
} catch (final Exception e) {
s_logger.error("revert vm " + vmName + " to snapshot " + command.getTarget().getSnapshotName() + " failed due to " + e.getMessage());
return new RevertToVMSnapshotAnswer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,72 @@
//
// 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.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Network;
import com.xensource.xenapi.VIF;
import com.xensource.xenapi.VM;
public final class CitrixUnPlugNicCommandWrapper extends CommandWrapper<UnPlugNicCommand, Answer, CitrixResourceBase> {
private static final Logger s_logger = Logger.getLogger(CitrixUnPlugNicCommandWrapper.class);
@Override
public Answer execute(final UnPlugNicCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
final String vmName = command.getVmName();
try {
final Set<VM> vms = VM.getByNameLabel(conn, vmName);
if (vms == null || vms.isEmpty()) {
return new UnPlugNicAnswer(command, false, "Can not find VM " + vmName);
}
final VM vm = vms.iterator().next();
final NicTO nic = command.getNic();
final String mac = nic.getMac();
final VIF vif = citrixResourceBase.getVifByMac(conn, vm, mac);
if (vif != null) {
vif.unplug(conn);
final Network network = vif.getNetwork(conn);
vif.destroy(conn);
try {
if (network.getNameLabel(conn).startsWith("VLAN")) {
citrixResourceBase.disableVlanNetwork(conn, network);
}
} catch (final Exception e) {
}
}
return new UnPlugNicAnswer(command, true, "success");
} catch (final Exception e) {
final String msg = " UnPlug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new UnPlugNicAnswer(command, false, msg);
}
}
}

View File

@ -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.hypervisor.xenserver.resource.wrapper;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
public final class CitrixUpdateHostPasswordCommandWrapper extends CommandWrapper<UpdateHostPasswordCommand, Answer, CitrixResourceBase> {
@Override
public Answer execute(final UpdateHostPasswordCommand command, final CitrixResourceBase citrixResourceBase) {
citrixResourceBase.addToPwdQueue(command.getNewPassword());
return new Answer(command, true, null);
}
}

View File

@ -13,9 +13,11 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.Test;
@ -30,12 +32,16 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckOnHostCommand;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.DeleteVMSnapshotCommand;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
@ -57,16 +63,21 @@ import com.cloud.agent.api.OvsSetupBridgeCommand;
import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
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.RevertToVMSnapshotCommand;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
@ -76,12 +87,14 @@ import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.storage.ResizeVolumeCommand;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.NicTO;
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.hypervisor.xenserver.resource.XsLocalNetwork;
import com.cloud.network.PhysicalNetworkSetupInfo;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
@ -92,6 +105,7 @@ import com.xensource.xenapi.Host;
import com.xensource.xenapi.Marshalling;
import com.xensource.xenapi.Network;
import com.xensource.xenapi.PIF;
import com.xensource.xenapi.Pool;
import com.xensource.xenapi.Types.BadServerResponse;
import com.xensource.xenapi.Types.XenAPIException;
@ -1269,6 +1283,194 @@ public class CitrixRequestWrapperTest {
assertFalse(answer.getResult());
}
@Test
public void testUpdateHostPasswordCommand() {
final UpdateHostPasswordCommand updatePwd = new UpdateHostPasswordCommand("test", "123");
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(updatePwd, citrixResourceBase);
assertTrue(answer.getResult());
}
@Test
public void testClusterVMMetaDataSyncCommand() {
final String uuid = "6172d8b7-ba10-4a70-93f9-ecaf41f51d53";
final Connection conn = Mockito.mock(Connection.class);
final XsHost xsHost = Mockito.mock(XsHost.class);
final Pool pool = PowerMockito.mock(Pool.class);
final Pool.Record poolr = Mockito.mock(Pool.Record.class);
final Host.Record hostr = Mockito.mock(Host.Record.class);
final Host master = Mockito.mock(Host.class);
final ClusterVMMetaDataSyncCommand vmDataSync = new ClusterVMMetaDataSyncCommand(10, 1l);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
try {
when(citrixResourceBase.getHost()).thenReturn(xsHost);
when(citrixResourceBase.getHost().getUuid()).thenReturn(uuid);
PowerMockito.mockStatic(Pool.Record.class);
when(pool.getRecord(conn)).thenReturn(poolr);
poolr.master = master;
when(poolr.master.getRecord(conn)).thenReturn(hostr);
hostr.uuid = uuid;
} 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(vmDataSync, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertTrue(answer.getResult());
}
@Test
public void testCheckNetworkCommandSuccess() {
final List<PhysicalNetworkSetupInfo> setupInfos = new ArrayList<PhysicalNetworkSetupInfo>();
final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(checkNet, citrixResourceBase);
assertTrue(answer.getResult());
}
@Test
public void testCheckNetworkCommandFailure() {
final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
final List<PhysicalNetworkSetupInfo> setupInfos = new ArrayList<PhysicalNetworkSetupInfo>();
setupInfos.add(info);
final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(checkNet, citrixResourceBase);
assertFalse(answer.getResult());
}
@Test
public void testPlugNicCommand() {
final NicTO nicTO = Mockito.mock(NicTO.class);
final Connection conn = Mockito.mock(Connection.class);
final PlugNicCommand plugNic = new PlugNicCommand(nicTO, "Test", VirtualMachine.Type.User);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
final Answer answer = wrapper.execute(plugNic, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertFalse(answer.getResult());
}
@Test
public void testUnPlugNicCommand() {
final NicTO nicTO = Mockito.mock(NicTO.class);
final Connection conn = Mockito.mock(Connection.class);
final UnPlugNicCommand unplugNic = new UnPlugNicCommand(nicTO, "Test");
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
final Answer answer = wrapper.execute(unplugNic, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertFalse(answer.getResult());
}
@Test
public void testCreateVMSnapshotCommand() {
final Connection conn = Mockito.mock(Connection.class);
final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class);
final List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>();
final CreateVMSnapshotCommand vmSnapshot = new CreateVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian");
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertTrue(answer.getResult());
}
@Test
public void testDeleteVMSnapshotCommand() {
final Connection conn = Mockito.mock(Connection.class);
final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class);
final List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>();
final DeleteVMSnapshotCommand vmSnapshot = new DeleteVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian");
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertTrue(answer.getResult());
}
@Test
public void testRevertToVMSnapshotCommand() {
final Connection conn = Mockito.mock(Connection.class);
final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class);
final List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>();
final RevertToVMSnapshotCommand vmSnapshot = new RevertToVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian");
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);
when(citrixResourceBase.getConnection()).thenReturn(conn);
final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase);
verify(citrixResourceBase, times(1)).getConnection();
assertFalse(answer.getResult());
}
}
class NotAValidCommand extends Command {