/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.service.vmware.block;
import static com.emc.sa.service.ServiceParams.MULTIPATH_POLICY;
import static com.emc.sa.service.ServiceParams.STORAGE_IO_CONTROL;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.emc.sa.engine.ExecutionUtils;
import com.emc.sa.engine.bind.Bindable;
import com.emc.sa.engine.bind.BindingUtils;
import com.emc.sa.engine.bind.Param;
import com.emc.sa.engine.service.Service;
import com.emc.sa.service.vipr.block.BlockStorageUtils;
import com.emc.sa.service.vipr.block.CreateBlockVolumeForHostHelper;
import com.emc.sa.service.vmware.VMwareBinding;
import com.emc.sa.service.vmware.VMwareBinding.DatastoreToVolumeParams;
import com.emc.sa.service.vmware.VMwareBinding.DatastoreToVolumeTable;
import com.emc.sa.service.vmware.VMwareHostService;
import com.emc.storageos.model.block.BlockObjectRestRep;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.iwave.ext.vmware.VMwareUtils;
import com.vmware.vim25.mo.Datastore;
@Service("VMware-CreateVolumeAndVmfsDatastore")
public class CreateVolumeAndVmfsDatastoreService extends VMwareHostService {
@Param(value = MULTIPATH_POLICY, required = false)
protected String multipathPolicy;
@Param(value = STORAGE_IO_CONTROL, required = false)
protected Boolean storageIOControl;
@Bindable(itemType = DatastoreToVolumeTable.class)
protected DatastoreToVolumeTable[] datastoreToVolume;
@Bindable
protected DatastoreToVolumeParams datastoreToVolumeParams = new DatastoreToVolumeParams();
List<String> datastoreNames = null;
List<String> volumeNames = null;
protected List<CreateBlockVolumeForHostHelper> createBlockVolumeHelpers = Lists.newArrayList();
@Override
public boolean checkClusterConnectivity() {
return false;
}
@Override
public void init() throws Exception {
super.init();
int hluIncrement = 0;
// for each pair of datastore / volume, bind params to createBlockVolumeHelper
for (DatastoreToVolumeTable dsToVol : datastoreToVolume) {
CreateBlockVolumeForHostHelper createBlockVolumeHelper = new CreateBlockVolumeForHostHelper();
BindingUtils.bind(createBlockVolumeHelper,
VMwareBinding.createDatastoreVolumeParam(dsToVol, datastoreToVolumeParams, hluIncrement));
createBlockVolumeHelpers.add(createBlockVolumeHelper);
hluIncrement++;
}
}
@Override
public void precheck() throws Exception {
datastoreNames = VMwareBinding.getDatastoreNamesFromDatastoreToVolume(datastoreToVolume);
volumeNames = VMwareBinding.getVolumeNamesFromDatastoreToVolume(datastoreToVolume);
if (datastoreNames.isEmpty()) {
throw new IllegalStateException(
ExecutionUtils.getMessage("CreateVolumeAndVmfsDatastoreService.datastore.empty"));
}
if (!VMwareUtils.isUniqueNames(datastoreNames)) {
throw new IllegalStateException(
ExecutionUtils.getMessage("CreateVolumeAndVmfsDatastoreService.datastore.datastore.notunique"));
}
if (!VMwareUtils.isUniqueNames(volumeNames)) {
throw new IllegalStateException(
ExecutionUtils.getMessage("CreateVolumeAndVmfsDatastoreService.datastore.volume.notunique"));
}
super.precheck();
for (CreateBlockVolumeForHostHelper helper : createBlockVolumeHelpers) {
helper.precheck();
}
acquireHostLock();
for (String datastore : datastoreNames) {
vmware.verifyDatastoreDoesNotExist(datacenter.getLabel(), datastore);
}
vmware.verifySupportedMultipathPolicy(host, multipathPolicy);
vmware.disconnect();
}
@Override
public void execute() throws Exception {
if (datastoreNames.size() != createBlockVolumeHelpers.size()) {
throw new IllegalStateException(
ExecutionUtils.getMessage("CreateVolumeAndVmfsDatastoreService.datastore.volume.mismatch"));
}
Map<String, BlockObjectRestRep> datastoreVolumeMap = Maps.newHashMap();
List<URI> volumes = BlockStorageUtils.createMultipleVolumes(createBlockVolumeHelpers);
if (volumes.isEmpty()) {
ExecutionUtils.fail("CreateVolumeAndVmfsDatastoreService.illegalState.noVolumesCreated", args(), args());
}
// use one of the helpers to export all volumes to the host or cluster
createBlockVolumeHelpers.get(0).exportVolumes(volumes);
int index = 0;
for (String datastoreName : datastoreNames) {
BlockObjectRestRep volume = BlockStorageUtils.getBlockResource(volumes.get(index));
datastoreVolumeMap.put(datastoreName, volume);
index++;
}
connectAndInitializeHost();
vmware.refreshStorage(host, cluster);
for (Entry<String, BlockObjectRestRep> entry : datastoreVolumeMap.entrySet()) {
Datastore datastore = vmware.createVmfsDatastore(host, cluster, hostId, entry.getValue(), entry.getKey());
vmware.setMultipathPolicy(host, cluster, multipathPolicy, entry.getValue());
vmware.setStorageIOControl(datastore, storageIOControl, true);
}
vmware.disconnect();
}
}