use of javax.cim.CIMInstance in project coprhd-controller by CoprHD.
the class SmisStorageDevice method doCreateVolumes.
@Override
public void doCreateVolumes(final StorageSystem storageSystem, final StoragePool storagePool, final String opId, final List<Volume> volumes, final VirtualPoolCapabilityValuesWrapper capabilities, final TaskCompleter taskCompleter) throws DeviceControllerException {
String label = null;
Long capacity = null;
Long thinVolumePreAllocationSize = null;
CIMInstance poolSetting = null;
boolean opCreationFailed = false;
StringBuilder logMsgBuilder = new StringBuilder(String.format("Create Volume Start - Array:%s, Pool:%s", storageSystem.getSerialNumber(), storagePool.getNativeGuid()));
StorageSystem forProvider = _helper.getStorageSystemForProvider(storageSystem, volumes.get(0));
// volumeGroupObjectPath is required for VMAX3
CIMObjectPath volumeGroupObjectPath = _helper.getVolumeGroupPath(forProvider, storageSystem, volumes.get(0), storagePool);
List<String> volumeLabels = new ArrayList<>();
for (Volume volume : volumes) {
logMsgBuilder.append(String.format("%nVolume:%s , IsThinlyProvisioned: %s", volume.getLabel(), volume.getThinlyProvisioned()));
String tenantName = "";
try {
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, volume.getTenant().getURI());
tenantName = tenant.getLabel();
} catch (DatabaseException e) {
_log.error("Error lookup TenantOrb object", e);
}
label = _nameGenerator.generate(tenantName, volume.getLabel(), volume.getId().toString(), '-', SmisConstants.MAX_VOLUME_NAME_LENGTH);
volumeLabels.add(label);
if (capacity == null) {
capacity = volume.getCapacity();
}
if (thinVolumePreAllocationSize == null && volume.getThinVolumePreAllocationSize() > 0) {
thinVolumePreAllocationSize = volume.getThinVolumePreAllocationSize();
}
}
_log.info(logMsgBuilder.toString());
boolean isThinlyProvisioned = volumes.get(0).getThinlyProvisioned();
try {
CIMObjectPath configSvcPath = _cimPath.getConfigSvcPath(storageSystem);
CIMArgument[] inArgs = null;
// I didn't find any ways to add this branching logic based on device Types.
if (DiscoveredDataObject.Type.vnxblock.toString().equalsIgnoreCase(storageSystem.getSystemType())) {
String autoTierPolicyName = ControllerUtils.getAutoTieringPolicyName(volumes.get(0).getId(), _dbClient);
if (autoTierPolicyName.equals(Constants.NONE)) {
autoTierPolicyName = null;
}
inArgs = _helper.getCreateVolumesInputArgumentsOnFastEnabledPool(storageSystem, storagePool, volumeLabels, capacity, volumes.size(), isThinlyProvisioned, autoTierPolicyName);
} else {
if (!storageSystem.checkIfVmax3() && isThinlyProvisioned && null != thinVolumePreAllocationSize) {
poolSetting = _smisStorageDevicePreProcessor.createStoragePoolSetting(storageSystem, storagePool, thinVolumePreAllocationSize);
}
if (storageSystem.checkIfVmax3()) {
inArgs = _helper.getCreateVolumesInputArguments(storageSystem, storagePool, volumeLabels, capacity, volumes.size(), isThinlyProvisioned, true, volumeGroupObjectPath, (null != thinVolumePreAllocationSize));
} else {
inArgs = _helper.getCreateVolumesInputArguments(storageSystem, storagePool, volumeLabels, capacity, volumes.size(), isThinlyProvisioned, poolSetting, true);
}
}
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethod(forProvider, configSvcPath, _helper.createVolumesMethodName(forProvider), inArgs, outArgs);
CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
if (job != null) {
SmisJob createSmisJob = volumes.size() > 1 ? new SmisCreateMultiVolumeJob(job, forProvider.getId(), storagePool.getId(), volumes.size(), taskCompleter) : new SmisCreateVolumeJob(job, forProvider.getId(), storagePool.getId(), taskCompleter);
ControllerServiceImpl.enqueueJob(new QueueJob(createSmisJob));
}
} catch (final InternalException e) {
_log.error("Problem in doCreateVolumes: ", e);
opCreationFailed = true;
taskCompleter.error(_dbClient, e);
} catch (WBEMException e) {
_log.error("Problem making SMI-S call: ", e);
opCreationFailed = true;
ServiceError serviceError = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
taskCompleter.error(_dbClient, serviceError);
} catch (Exception e) {
_log.error("Problem in doCreateVolumes: ", e);
opCreationFailed = true;
ServiceError serviceError = DeviceControllerErrors.smis.methodFailed("doCreateVolumes", e.getMessage());
taskCompleter.error(_dbClient, serviceError);
}
if (opCreationFailed) {
for (Volume vol : volumes) {
vol.setInactive(true);
_dbClient.updateObject(vol);
}
}
logMsgBuilder = new StringBuilder(String.format("Create Volumes End - Array:%s, Pool:%s", storageSystem.getSerialNumber(), storagePool.getNativeGuid()));
for (Volume volume : volumes) {
logMsgBuilder.append(String.format("%nVolume:%s", volume.getLabel()));
}
_log.info(logMsgBuilder.toString());
}
use of javax.cim.CIMInstance in project coprhd-controller by CoprHD.
the class SmisStorageDevice method cleanupAnyGroupBackupSnapshots.
/**
* Method will look up backup snapshots that were created when a snapshot restore operation was
* performed, then clean them up. This would be required in order to do the volume delete.
*
* @param storage
* [required] - StorageSystem object representing the array
* @param volume
* [required] - Volume object representing the volume that has a snapshot created for
* it
*/
private void cleanupAnyGroupBackupSnapshots(final StorageSystem storage, final Volume volume) {
CloseableIterator<CIMObjectPath> settingsIterator = null;
_log.info(String.format("cleanupAnyGroupBackupSnapshots for volume [%s](%s)...", volume.getLabel(), volume.getId()));
try {
String groupName = ConsistencyGroupUtils.getSourceConsistencyGroupName(volume, _dbClient);
CIMObjectPath cgPath = null;
if (groupName != null) {
cgPath = _cimPath.getReplicationGroupPath(storage, groupName);
if (cgPath == null) {
_log.info("Replication Group {} not found. Skipping cleanup of group backup snapsots step.", groupName);
return;
}
} else {
_log.info(String.format("No Replication Group found for volume [%s](%s). Skipping cleanup of group backup snapsots step.", volume.getLabel(), volume.getId()));
return;
}
CIMArgument[] outArgs = new CIMArgument[5];
CIMInstance cgPathInstance = _helper.checkExists(storage, cgPath, false, false);
if (cgPathInstance != null) {
settingsIterator = _helper.getAssociatorNames(storage, cgPath, null, SmisConstants.CLAR_SYNCHRONIZATION_ASPECT_FOR_SOURCE_GROUP, null, null);
while (settingsIterator.hasNext()) {
CIMObjectPath aspectPath = settingsIterator.next();
CIMObjectPath settingsPath = _cimPath.getGroupSynchronizedSettingsPath(storage, groupName, (String) aspectPath.getKey(SmisConstants.CP_INSTANCE_ID).getValue());
CIMArgument[] deleteSettingsInput = _helper.getDeleteSettingsForSnapshotInputArguments(settingsPath, true);
_helper.callModifySettingsDefineState(storage, deleteSettingsInput, outArgs);
}
}
} catch (Exception e) {
_log.info("Problem making SMI-S call: ", e);
} finally {
if (settingsIterator != null) {
settingsIterator.close();
}
}
}
use of javax.cim.CIMInstance in project coprhd-controller by CoprHD.
the class SmisStorageDevice method doRemoveFromConsistencyGroup.
@Override
public void doRemoveFromConsistencyGroup(StorageSystem storage, final URI consistencyGroupId, final List<URI> blockObjects, final TaskCompleter taskCompleter) throws DeviceControllerException {
Set<String> groupNames = new HashSet<String>();
String grpName = null;
try {
// get the group name from one of the block objects; we expect all of them to be the same group
Iterator<URI> itr = blockObjects.iterator();
while (itr.hasNext()) {
BlockObject blockObject = BlockObject.fetch(_dbClient, itr.next());
if (blockObject != null && !blockObject.getInactive() && !NullColumnValueGetter.isNullValue(blockObject.getReplicationGroupInstance())) {
groupNames.add(blockObject.getReplicationGroupInstance());
}
}
// Check if the replication group exists
for (String groupName : groupNames) {
grpName = groupName;
storage = findProviderFactory.withGroup(storage, groupName).find();
if (storage == null) {
ServiceError error = DeviceControllerErrors.smis.noConsistencyGroupWithGivenName();
taskCompleter.error(_dbClient, error);
return;
}
String[] blockObjectNames = _helper.getBlockObjectAlternateNames(blockObjects);
CIMObjectPath[] members = _cimPath.getVolumePaths(storage, blockObjectNames);
CIMArgument[] output = new CIMArgument[5];
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupId);
if (!storage.deviceIsType(Type.vnxblock) && ControllerUtils.checkCGHasGroupRelationship(storage, consistencyGroupId, _dbClient)) {
// remove from DeviceMaskingGroup
CIMObjectPath maskingGroupPath = _cimPath.getMaskingGroupPath(storage, groupName, SmisConstants.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
_log.info("Removing volumes {} from device masking group {}", blockObjectNames, maskingGroupPath.toString());
CIMArgument[] inArgs = _helper.getRemoveAndUnmapMaskingGroupMembersInputArguments(maskingGroupPath, members, storage, true);
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), SmisConstants.REMOVE_MEMBERS, inArgs, output, null);
} else {
CIMObjectPath cgPath = _cimPath.getReplicationGroupPath(storage, groupName);
CIMInstance cgPathInstance = _helper.checkExists(storage, cgPath, false, false);
// If there is no replication group with the given name, return success
if (cgPathInstance == null) {
_log.info(String.format("no replication group with name %s exists on storage system %s", groupName, storage.getLabel()));
} else {
CIMObjectPath replicationSvc = _cimPath.getControllerReplicationSvcPath(storage);
CIMArgument[] removeMembersInput = _helper.getRemoveMembersInputArguments(cgPath, members);
_helper.invokeMethod(storage, replicationSvc, SmisConstants.REMOVE_MEMBERS, removeMembersInput, output);
}
}
}
taskCompleter.ready(_dbClient);
} catch (Exception e) {
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupId);
_log.error("Problem while removing volume from CG :{}", consistencyGroupId, e);
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.failedToRemoveMembersToConsistencyGroup((consistencyGroup == null ? "unknown cg" : consistencyGroup.getLabel()), (grpName == null ? "unknown replication group" : grpName), e.getMessage()));
}
}
use of javax.cim.CIMInstance in project coprhd-controller by CoprHD.
the class SmisStorageDevice method doAddToConsistencyGroup.
@Override
public void doAddToConsistencyGroup(StorageSystem storage, final URI consistencyGroupId, String replicationGroupName, final List<URI> blockObjectURIs, final TaskCompleter taskCompleter) throws DeviceControllerException {
BlockConsistencyGroup consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupId);
Map<URI, BlockObject> uriToBlockObjectMap = new HashMap<URI, BlockObject>();
List<URI> replicas = new ArrayList<URI>();
List<URI> volumes = new ArrayList<URI>();
try {
List<BlockObject> blockObjects = new ArrayList<BlockObject>();
for (URI blockObjectURI : blockObjectURIs) {
// FIXME Performance improvement here
BlockObject blockObject = BlockObject.fetch(_dbClient, blockObjectURI);
if (blockObject != null) {
blockObjects.add(blockObject);
uriToBlockObjectMap.put(blockObjectURI, blockObject);
}
}
/**
* Request: Volume CG with volume objects OR
* Volume CG with replica objects(snap/clone/mirror)
*
* make sure that the blockObjects are of same type (Volume/Snap/Clone/Mirror)
* If Volume:
* add them to group
* If Replica (supported only for 8.0):
* If existing replicas do not have replicationGroupInstance set:
* create new RG on array with random name,
* add replicas to that RG,
* set RG name in replicationGroupInstance field for new replicas.
* Else:
* Get RG name from existing replica,
* Add new replicas to DMG with same name as RG name,
* set RG name in replicationGroupInstance field for new replicas.
*
* For all objects except Clone, set CG URI.
*/
for (BlockObject blockObject : blockObjects) {
boolean isFullCopy = false;
if (blockObject instanceof Volume) {
isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
}
if (blockObject instanceof BlockSnapshot || isFullCopy || blockObject instanceof BlockMirror) {
replicas.add(blockObject.getId());
} else {
volumes.add(blockObject.getId());
}
}
// adding replicas to ReplicationGroup is supported only for 8.0
if (!storage.getUsingSmis80() && !replicas.isEmpty()) {
String errMsg = "Adding replicas to Consistency Group is not supported on 4.6.x Provider";
_log.warn(errMsg);
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.failedToAddMembersToConsistencyGroup(consistencyGroup.getLabel(), consistencyGroup.fetchArrayCgName(storage.getId()), errMsg));
return;
}
if (!volumes.isEmpty() && !replicas.isEmpty()) {
String errMsg = "Mix of Volumes and Replica types is not supported";
_log.warn(errMsg);
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.failedToAddMembersToConsistencyGroup(consistencyGroup.getLabel(), consistencyGroup.getCgNameOnStorageSystem(storage.getId()), errMsg));
return;
}
if (!replicas.isEmpty()) {
addReplicasToConsistencyGroup(storage, consistencyGroup, replicas, uriToBlockObjectMap);
} else if (!volumes.isEmpty()) {
// get source provider for SRDF target volumes
// target CG is created using source system provider
StorageSystem forProvider = storage;
boolean isSrdfTarget = false;
Volume vol = (Volume) uriToBlockObjectMap.get(volumes.iterator().next());
if (vol.checkForSRDF() && !NullColumnValueGetter.isNullNamedURI(vol.getSrdfParent())) {
Volume srcVolume = _dbClient.queryObject(Volume.class, vol.getSrdfParent().getURI());
forProvider = _dbClient.queryObject(StorageSystem.class, srcVolume.getStorageController());
isSrdfTarget = true;
}
// Check if the consistency group exists
boolean createCG = false;
CIMObjectPath cgPath = null;
CIMInstance cgPathInstance = null;
boolean isVPlexOrRP = consistencyGroup.checkForType(Types.VPLEX) || consistencyGroup.checkForType(Types.RP);
String groupName = ControllerUtils.generateReplicationGroupName(storage, consistencyGroup, replicationGroupName, _dbClient);
// If this is for VPlex or RP, we would create backend consistency group if it does not exist yet.
if (!consistencyGroup.created(storage.getId(), groupName)) {
if (isVPlexOrRP) {
createCG = true;
_log.info(String.format("No consistency group exists for the storage: %s", storage.getId()));
} else {
ServiceError error = DeviceControllerErrors.smis.noConsistencyGroupWithGivenName();
taskCompleter.error(_dbClient, error);
return;
}
} else {
if (!isSrdfTarget) {
StorageSystem storageSystem = findProviderFactory.withGroup(storage, groupName).find();
if (storageSystem == null) {
if (isVPlexOrRP) {
_log.info(String.format("Could not find consistency group with the name: %s", groupName));
createCG = true;
} else {
ServiceError error = DeviceControllerErrors.smis.noConsistencyGroupWithGivenName();
taskCompleter.error(_dbClient, error);
return;
}
} else {
forProvider = storageSystem;
}
}
if (!createCG && !(storage.deviceIsType(Type.vnxblock) && !consistencyGroup.getArrayConsistency())) {
cgPath = _cimPath.getReplicationGroupPath(forProvider, storage.getSerialNumber(), groupName);
cgPathInstance = _helper.checkExists(forProvider, cgPath, false, false);
// operation to error
if (cgPathInstance == null) {
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.consistencyGroupNotFound(consistencyGroup.getLabel(), consistencyGroup.getCgNameOnStorageSystem(storage.getId())));
return;
}
}
}
if (createCG) {
doCreateConsistencyGroup(storage, consistencyGroupId, groupName, null);
consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupId);
cgPath = _cimPath.getReplicationGroupPath(storage, groupName);
}
if (storage.deviceIsType(Type.vnxblock) && !consistencyGroup.getArrayConsistency()) {
// nothing need to be done on array side
_log.info("No array operation needed for VNX replication group {}", groupName);
} else {
CIMObjectPath replicationSvc = _cimPath.getControllerReplicationSvcPath(storage);
String[] blockObjectNames = _helper.getBlockObjectAlternateNames(volumes);
// Smis call to add volumes that are already available in Group, will result in error.
// Refresh first for confidence and avoid false positives.
ReplicationUtils.callEMCRefresh(_helper, storage, true);
Set<String> blockObjectsToAdd = _helper.filterVolumesAlreadyPartOfReplicationGroup(storage, cgPath, blockObjectNames);
if (!blockObjectsToAdd.isEmpty()) {
CIMArgument[] output = new CIMArgument[5];
CIMObjectPath[] members = _cimPath.getVolumePaths(storage, blockObjectsToAdd.toArray(new String[blockObjectsToAdd.size()]));
boolean cgHasGroupRelationship = ControllerUtils.checkCGHasGroupRelationship(storage, consistencyGroup.getId(), _dbClient);
if (!cgHasGroupRelationship) {
CIMArgument[] addMembersInput = _helper.getAddMembersInputArguments(cgPath, members);
_helper.invokeMethod(storage, replicationSvc, SmisConstants.ADD_MEMBERS, addMembersInput, output);
} else {
final CIMObjectPath maskingGroupPath = _cimPath.getMaskingGroupPath(storage, groupName, SmisConstants.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
_log.info("Adding volumes {} to device masking group {}", StringUtils.join(blockObjectsToAdd, ", "), maskingGroupPath.toString());
final CIMArgument[] inArgs = _helper.getAddOrRemoveMaskingGroupMembersInputArguments(maskingGroupPath, members, true);
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), SmisConstants.ADD_MEMBERS, inArgs, output, null);
}
} else {
_log.info("Requested volumes {} are already part of the Replication Group {}, hence skipping AddMembers call..", Joiner.on(", ").join(blockObjectNames), groupName);
}
}
// refresh target provider to update its view on target CG
if (isSrdfTarget) {
refreshStorageSystem(storage.getId(), null);
}
}
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_log.error("Problem in adding volumes to Consistency Group {}", consistencyGroupId, e);
// Remove any references to the consistency group
for (URI volume : volumes) {
BlockObject volumeObject = uriToBlockObjectMap.get(volume);
volumeObject.setConsistencyGroup(NullColumnValueGetter.getNullURI());
volumeObject.setReplicationGroupInstance(NullColumnValueGetter.getNullStr());
_dbClient.updateObject(volumeObject);
}
// Remove replication group instance
for (URI replica : replicas) {
BlockObject replicaObject = uriToBlockObjectMap.get(replica);
replicaObject.setReplicationGroupInstance(NullColumnValueGetter.getNullStr());
if (!(replicaObject instanceof Volume && ControllerUtils.isVolumeFullCopy((Volume) replicaObject, _dbClient))) {
replicaObject.setConsistencyGroup(NullColumnValueGetter.getNullURI());
replicaObject.setReplicationGroupInstance(NullColumnValueGetter.getNullStr());
}
_dbClient.updateObject(replicaObject);
}
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.failedToAddMembersToConsistencyGroup(consistencyGroup.getLabel(), consistencyGroup.getCgNameOnStorageSystem(storage.getId()), e.getMessage()));
}
}
use of javax.cim.CIMInstance in project coprhd-controller by CoprHD.
the class SmisStorageDevicePreProcessor method createStoragePoolSetting.
/**
* Create StoragePool Setting for a given pool. This will be useful before
* Here are the steps to create a new PoolSetting.
* 1. First find the storagePoolCapability for a given storagepool.
* 2. Use the capability to create a new StoragePool Setting.
* 3. Update instance to set the
*
* creating a volume.
*
* @param storageSystem
* @param storagePool
* @param thinVolumePreAllocateSize
* @throws Exception
*/
public CIMInstance createStoragePoolSetting(StorageSystem storageSystem, StoragePool storagePool, long thinVolumePreAllocateSize) throws Exception {
_log.info(String.format("Create StoragePool Setting Start - Array: %s, Pool: %s, %n thinVolumePreAllocateSize: %s", storageSystem.getSerialNumber(), storagePool.getNativeId(), thinVolumePreAllocateSize));
CIMObjectPath poolSvcPath = _cimPath.getStoragePoolPath(storageSystem, storagePool);
CimConnection connection = _cimConnection.getConnection(storageSystem);
WBEMClient client = connection.getCimClient();
CIMInstance modifiedSettingInstance = null;
try {
_log.debug("Op1 start: Getting poolCapabilities associated with this pool");
final Iterator<?> it = client.associatorNames(poolSvcPath, SmisConstants.CIM_ELEMENTCAPABILITIES, SmisConstants.SYMM_STORAGEPOOL_CAPABILITIES, null, null);
if (it.hasNext()) {
final CIMObjectPath poolCapabilityPath = (CIMObjectPath) it.next();
_log.debug("Op1 end: received pool capability from provider {}", poolCapabilityPath);
CIMArgument<?>[] outputArgs = new CIMArgument<?>[1];
_log.info("Invoking CIMClient to create to create a new Setting");
client.invokeMethod(poolCapabilityPath, SmisConstants.CP_CREATE_SETTING, _helper.getCreatePoolSettingArguments(), outputArgs);
CIMObjectPath settingPath = _cimPath.getCimObjectPathFromOutputArgs(outputArgs, SmisConstants.CP_NEWSETTING);
modifiedSettingInstance = new CIMInstance(settingPath, _helper.getModifyPoolSettingArguments(thinVolumePreAllocateSize));
client.modifyInstance(modifiedSettingInstance, SmisConstants.PS_THIN_VOLUME_INITIAL_RESERVE);
_log.info("Modified the poolSetting instance to set ThinProvisionedInitialReserve");
}
} catch (WBEMException e) {
_log.error("Problem making SMI-S call: ", e);
throw e;
} catch (Exception e) {
_log.error("Problem in createStoragePoolSetting: " + storagePool.getNativeId(), e);
throw e;
} finally {
_log.info(String.format("Create StoragePool Setting End - Array:%s, Pool: %s", storageSystem.getSerialNumber(), storagePool.getNativeId()));
}
return modifiedSettingInstance;
}
Aggregations