/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.service.windows;
import static com.emc.sa.service.vipr.ViPRExecutionUtils.addAffectedResource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.emc.sa.engine.ExecutionUtils;
import com.emc.sa.machinetags.KnownMachineTags;
import com.emc.sa.service.vipr.ViPRExecutionUtils;
import com.emc.sa.service.vipr.block.tasks.RemoveBlockVolumeMachineTag;
import com.emc.sa.service.vipr.block.tasks.SetBlockVolumeMachineTag;
import com.emc.sa.service.windows.tasks.AddDiskToCluster;
import com.emc.sa.service.windows.tasks.AssignLabel;
import com.emc.sa.service.windows.tasks.DeleteClusterResource;
import com.emc.sa.service.windows.tasks.DeleteDirectory;
import com.emc.sa.service.windows.tasks.DiscoverDisksForVolumes;
import com.emc.sa.service.windows.tasks.ExtendVolume;
import com.emc.sa.service.windows.tasks.FetchDiskDetail;
import com.emc.sa.service.windows.tasks.FindDisksForVolumes;
import com.emc.sa.service.windows.tasks.FormatAndMountDisk;
import com.emc.sa.service.windows.tasks.GetAssignedDriveLetters;
import com.emc.sa.service.windows.tasks.GetDirectoryContents;
import com.emc.sa.service.windows.tasks.GetDiskToResourceMap;
import com.emc.sa.service.windows.tasks.MakeDirectory;
import com.emc.sa.service.windows.tasks.MountVolume;
import com.emc.sa.service.windows.tasks.OfflineClusterResource;
import com.emc.sa.service.windows.tasks.OfflineDisk;
import com.emc.sa.service.windows.tasks.OnlineDisk;
import com.emc.sa.service.windows.tasks.CheckPartitionRestriction;
import com.emc.sa.service.windows.tasks.RescanDisks;
import com.emc.sa.service.windows.tasks.UnmountVolume;
import com.emc.sa.service.windows.tasks.VerifyActiveCluster;
import com.emc.sa.service.windows.tasks.VerifyClusterConfiguration;
import com.emc.sa.service.windows.tasks.VerifyDriveLetterIsAvailable;
import com.emc.sa.service.windows.tasks.VerifyFailoverClusterInstalled;
import com.emc.sa.service.windows.tasks.VerifyMountPointHostDriveIsMounted;
import com.emc.sa.service.windows.tasks.VerifyMountPointHostDriveIsNotShared;
import com.emc.sa.service.windows.tasks.VerifyMountPointIsDriveLetter;
import com.emc.sa.service.windows.tasks.VerifyWinRM;
import com.emc.sa.service.windows.tasks.WindowsExecutionTask;
import com.emc.storageos.db.client.model.Host;
import com.emc.storageos.model.block.BlockObjectRestRep;
import com.emc.storageos.model.block.VolumeRestRep;
import com.iwave.ext.windows.WindowsSystemWinRM;
import com.iwave.ext.windows.model.Disk;
import com.iwave.ext.windows.model.Volume;
import com.iwave.ext.windows.model.wmi.DiskDrive;
public class WindowsSupport {
private WindowsSystemWinRM targetSystem;
public WindowsSupport(WindowsSystemWinRM targetSystem) {
this.targetSystem = targetSystem;
}
public String getHostName() {
return targetSystem.getTarget().getHost();
}
public void verifyWinRM() {
execute(new VerifyWinRM());
}
public void verifyClusterSupport() {
execute(new VerifyFailoverClusterInstalled());
execute(new VerifyActiveCluster());
}
public void verifyClusterHosts(List<Host> hosts) {
execute(new VerifyClusterConfiguration(hosts));
}
public void rescanDisks() {
execute(new RescanDisks());
}
public Disk getDiskDetail(DiskDrive disk) {
return execute(new FetchDiskDetail(disk.getNumber()));
}
public Set<String> getAssignedDriveLetters() {
return execute(new GetAssignedDriveLetters());
}
public String getAssignedMountPoint(DiskDrive disk) {
Disk detail = getDiskDetail(disk);
return getAssignedMountPoint(disk, detail);
}
public String getAssignedMountPoint(DiskDrive disk, Disk detail) {
if ((detail != null) && (detail.getVolumes() != null) && (!detail.getVolumes().isEmpty())) {
return detail.getVolumes().get(0).getMountPoint();
}
ExecutionUtils.fail("failTask.WindowsSupport.noMountPoint", String.valueOf(disk.getNumber()), disk.getName(),
String.valueOf(disk.getNumber()));
return null; // fail() will throw an exception - we should never get here
}
public void assignLabel(Volume volume, String label) {
execute(new AssignLabel(volume, label));
}
public Map<? extends BlockObjectRestRep, DiskDrive> discoverDisks(
Collection<? extends BlockObjectRestRep> volumes, int attempts, long delay) {
return execute(new DiscoverDisksForVolumes(volumes, attempts, delay));
}
public Map<? extends BlockObjectRestRep, DiskDrive> findDisks(Collection<? extends BlockObjectRestRep> volumes) {
return execute(new FindDisksForVolumes(volumes));
}
public boolean isReadOnly(Disk disk) {
return Boolean.TRUE.equals(disk.getCurrentReadOnlyState())
|| Boolean.TRUE.equals(disk.getReadOnly());
}
public void onlineDisk(Disk disk) {
boolean isReadOnly = isReadOnly(disk);
execute(new OnlineDisk(disk.getNumber(), isReadOnly));
addRollback(new OfflineDisk(disk.getNumber()));
}
public void offlineDisk(DiskDrive disk) {
execute(new OfflineDisk(disk.getNumber()));
}
public void checkPartitionRestriction(DiskDrive disk, long volumeSizeInBytes) {
execute(new CheckPartitionRestriction(disk.getNumber(), volumeSizeInBytes));
}
public void formatAndMount(DiskDrive disk, String fsType,
String allocationUnitSize, String label, String mountpoint, String partitionType) {
execute(new FormatAndMountDisk(disk, fsType, allocationUnitSize, label,
mountpoint, partitionType));
}
public void mountVolume(int volumeNumber, String mountpoint) {
execute(new MountVolume(volumeNumber, mountpoint));
}
public void unmountVolume(int volumeNumber, String mountpoint) {
execute(new UnmountVolume(volumeNumber, mountpoint));
}
public void makeDirectory(String directory) {
execute(new MakeDirectory(directory));
}
public void extendDrive(VolumeRestRep volume) {
String mountPoint = getMountPoint(volume);
extendDrive(volume, mountPoint);
}
public void extendDrive(BlockObjectRestRep volume, String mountPoint) {
execute(new ExtendVolume(mountPoint));
addAffectedResource(volume.getId());
}
public <T extends BlockObjectRestRep> void removeVolumeMountPoint(T volume) {
ExecutionUtils.execute(new RemoveBlockVolumeMachineTag(volume.getId(), getMountPointTagName()));
addAffectedResource(volume);
}
public <T extends BlockObjectRestRep> void addVolumeMountPoint(T volume, String mountpoint) {
ExecutionUtils.execute(new SetBlockVolumeMachineTag(volume.getId(), getMountPointTagName(), mountpoint));
ExecutionUtils.addRollback(new RemoveBlockVolumeMachineTag(volume.getId(), getMountPointTagName()));
addAffectedResource(volume);
}
public <T extends BlockObjectRestRep> String getMountPoint(T volume) {
if (targetSystem.getClusterId() != null) {
return KnownMachineTags.getBlockVolumeMountPoint(targetSystem.getClusterId(), volume);
}
else {
return KnownMachineTags.getBlockVolumeMountPoint(targetSystem.getHostId(), volume);
}
}
public <T extends BlockObjectRestRep> void verifyVolumesMounted(Collection<T> volumes) {
for (T volume : volumes) {
verifyVolumeMounted(volume);
}
}
public <T extends BlockObjectRestRep> void verifyVolumeMounted(T volume) {
String driveLetter = WindowsUtils.getDriveLetterFromMountPath(getMountPoint(volume));
if (StringUtils.isBlank(driveLetter)) {
ExecutionUtils.fail("failTask.WindowsSupport.notMounted", driveLetter, volume.getDeviceLabel());
}
}
public String addDiskToCluster(String diskId) {
String resourceName = execute(new AddDiskToCluster(diskId));
addRollback(new DeleteClusterResource(resourceName));
addRollback(new OfflineClusterResource(resourceName));
return resourceName;
}
public void deleteClusterResource(String resourceName) {
execute(new DeleteClusterResource(resourceName));
}
public void offlineClusterResource(String resourceName) {
execute(new OfflineClusterResource(resourceName));
}
public Map<String, String> getDiskToResourceMap() {
return execute(new GetDiskToResourceMap());
}
protected <T> T execute(WindowsExecutionTask<T> task) {
task.setTargetSystem(targetSystem);
return ViPRExecutionUtils.execute(task);
}
public void addRollback(WindowsExecutionTask<?> rollbackTask) {
rollbackTask.setTargetSystem(targetSystem);
ExecutionUtils.addRollback(rollbackTask);
}
public boolean isClustered() {
return targetSystem.getClusterId() != null;
}
private String getMountPointTagName() {
if (targetSystem.getClusterId() != null) {
return KnownMachineTags.getHostMountPointTagName(targetSystem.getClusterId());
}
else {
return KnownMachineTags.getHostMountPointTagName(targetSystem.getHostId());
}
}
public void deleteDirectory(String mountPoint) {
execute(new DeleteDirectory(mountPoint));
}
public boolean isDirectoryEmpty(String mountPoint) {
return execute(new GetDirectoryContents(mountPoint)).isEmpty();
}
public void verifyMountPointIsDriveLetter(String mountPoint) {
execute(new VerifyMountPointIsDriveLetter(mountPoint));
}
public void verifyMountPointHostDriveIsMounted(String mountPoint, Collection<String> assignedMountPoints) {
execute(new VerifyMountPointHostDriveIsMounted(mountPoint, assignedMountPoints));
}
public void verifyMountPointIsNotShared(String mountPoint) {
execute(new VerifyMountPointHostDriveIsNotShared(mountPoint));
}
public void verifyMountPointLetterIsAvailable(String mountPointLetter, Set<String> usedDriveLetters) {
execute(new VerifyDriveLetterIsAvailable(mountPointLetter, usedDriveLetters));
}
public boolean isGuid(String expression)
{
if (expression != null) {
Pattern guidRegEx = Pattern
.compile("^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$");
Matcher matcher = guidRegEx.matcher(expression);
return matcher.find();
}
return false;
}
}