/** * Called to update the job status when the volume expand job completes. * * @param jobContext The job context. */ public void updateStatus(JobContext jobContext) throws Exception { CloseableIterator<CIMObjectPath> associatorIterator = null; CloseableIterator<CIMInstance> instanceIterator = null; JobStatus jobStatus = getJobStatus(); try { if (jobStatus == JobStatus.IN_PROGRESS) { return; } DbClient dbClient = jobContext.getDbClient(); CIMConnectionFactory cimConnectionFactory = jobContext.getCimConnectionFactory(); WBEMClient client = getWBEMClient(dbClient, cimConnectionFactory); // If terminal state update storage pool capacity and remove reservation for volume capacity // from pool's reserved capacity map. if (jobStatus == JobStatus.SUCCESS || jobStatus == JobStatus.FAILED || jobStatus == JobStatus.FATAL_ERROR) { SmisUtils.updateStoragePoolCapacity(dbClient, client, _storagePoolURI); StoragePool pool = dbClient.queryObject(StoragePool.class, _storagePoolURI); StringMap reservationMap = pool.getReservedCapacityMap(); URI volumeId = getTaskCompleter().getId(); // remove from reservation map reservationMap.remove(volumeId.toString()); dbClient.persistObject(pool); } String opId = getTaskCompleter().getOpId(); StringBuilder logMsgBuilder = new StringBuilder( String.format( "Updating status of job %s to %s, task: %s", this.getJobName(), jobStatus.name(), opId)); if (jobStatus == JobStatus.SUCCESS) { VolumeExpandCompleter taskCompleter = (VolumeExpandCompleter) getTaskCompleter(); Volume volume = dbClient.queryObject(Volume.class, taskCompleter.getId()); // set requested capacity volume.setCapacity(taskCompleter.getSize()); // set meta related properties volume.setTotalMetaMemberCapacity(taskCompleter.getTotalMetaMembersSize()); volume.setMetaMemberCount(taskCompleter.getMetaMemberCount()); volume.setMetaMemberSize(taskCompleter.getMetaMemberSize()); volume.setIsComposite(taskCompleter.isComposite()); volume.setCompositionType(taskCompleter.getMetaVolumeType()); // set provisioned capacity associatorIterator = client.associatorNames(getCimJob(), null, SmisConstants.CIM_STORAGE_VOLUME, null, null); if (associatorIterator.hasNext()) { CIMObjectPath volumePath = associatorIterator.next(); CIMInstance volumeInstance = client.getInstance(volumePath, true, false, null); if (volumeInstance != null) { CIMProperty consumableBlocks = volumeInstance.getProperty(SmisConstants.CP_CONSUMABLE_BLOCKS); CIMProperty blockSize = volumeInstance.getProperty(SmisConstants.CP_BLOCK_SIZE); // calculate provisionedCapacity = consumableBlocks * block size Long provisionedCapacity = Long.valueOf(consumableBlocks.getValue().toString()) * Long.valueOf(blockSize.getValue().toString()); volume.setProvisionedCapacity(provisionedCapacity); } // set allocated capacity instanceIterator = client.referenceInstances( volumePath, SmisConstants.CIM_ALLOCATED_FROM_STORAGEPOOL, null, false, SmisConstants.PS_SPACE_CONSUMED); if (instanceIterator.hasNext()) { CIMInstance allocatedFromStoragePoolPath = instanceIterator.next(); CIMProperty spaceConsumed = allocatedFromStoragePoolPath.getProperty(SmisConstants.CP_SPACE_CONSUMED); if (null != spaceConsumed) { volume.setAllocatedCapacity(Long.valueOf(spaceConsumed.getValue().toString())); } } } logMsgBuilder.append( String.format( "%n Capacity: %s, Provisioned capacity: %s, Allocated Capacity: %s", volume.getCapacity(), volume.getProvisionedCapacity(), volume.getAllocatedCapacity())); if (volume.getIsComposite()) { logMsgBuilder.append( String.format( "%n Is Meta: %s, Total meta member capacity: %s, Meta member count %s, Meta member size: %s", volume.getIsComposite(), volume.getTotalMetaMemberCapacity(), volume.getMetaMemberCount(), volume.getMetaMemberSize())); } _log.info(logMsgBuilder.toString()); // Reset list of meta member volumes in the volume if (volume.getMetaVolumeMembers() != null) { volume.getMetaVolumeMembers().clear(); } StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, volume.getStorageController()); // set the RP tag on the volume if the volume is RP protected if (volume.checkForRp() && storageSystem.getSystemType() != null && storageSystem .getSystemType() .equalsIgnoreCase(DiscoveredDataObject.Type.vmax.toString())) { SmisCommandHelper helper = jobContext.getSmisCommandHelper(); List<CIMObjectPath> volumePathList = new ArrayList<CIMObjectPath>(); volumePathList.add(helper.getVolumeMember(storageSystem, volume)); helper.setRecoverPointTag(storageSystem, volumePathList, true); } dbClient.persistObject(volume); // Reset list of meta members native ids in WF data (when meta is created meta members are // removed from array) WorkflowService.getInstance().storeStepData(opId, new ArrayList<String>()); } } catch (Exception e) { _log.error("Caught an exception while trying to updateStatus for SmisVolumeExpandJob", e); setPostProcessingErrorStatus( "Encountered an internal error during volume expand job status processing : " + e.getMessage()); } finally { _metaVolumeTaskCompleter.setLastStepStatus(jobStatus); if (associatorIterator != null) { associatorIterator.close(); } if (instanceIterator != null) { instanceIterator.close(); } super.updateStatus(jobContext); } }
/** * Create StoragePool Record, if not present already, else update only the properties. * * @param pool * @param poolInstance * @param profile * @param poolClassName * @param supportedVolumeTypes * @param protocols * @param poolsToMatchWithVpool * @throws URISyntaxException * @throws IOException */ private void createStoragePool( StoragePool pool, CIMInstance poolInstance, AccessProfile profile, String poolClassName, String supportedVolumeTypes, Set<String> protocols, Map<URI, StoragePool> poolsToMatchWithVpool, StorageSystem device) throws URISyntaxException, IOException { boolean newPool = false; boolean modifiedPool = false; // indicates whether to add to modified pools list or not if (null == pool) { String instanceID = getCIMPropertyValue(poolInstance, Constants.INSTANCEID); String nativeIdFromInstance = getNativeIDFromInstance(instanceID); newPool = true; pool = new StoragePool(); pool.setId(URIUtil.createId(StoragePool.class)); pool.setPoolName(getCIMPropertyValue(poolInstance, POOL_ID)); pool.setNativeId(nativeIdFromInstance); pool.setStorageDevice(profile.getSystemId()); pool.setPoolServiceType(PoolServiceType.block.toString()); String poolNativeGuid = NativeGUIDGenerator.generateNativeGuid(_dbClient, pool); pool.setNativeGuid(poolNativeGuid); pool.setLabel(poolNativeGuid); // setting default values on Pool Creation for VMAX and VNX pool.setMaximumThickVolumeSize(0L); pool.setMinimumThickVolumeSize(0L); pool.setMaximumThinVolumeSize(0L); pool.setMinimumThinVolumeSize(0L); if (device.getAutoTieringEnabled()) { pool.setAutoTieringEnabled(Boolean.TRUE); } else { pool.setAutoTieringEnabled(Boolean.FALSE); } _logger.info( String.format( "Maximum default limits for volume capacity in storage pool %s / %s : \n " + "max thin volume capacity: %s, max thick volume capacity: %s ", pool.getPoolName(), pool.getId(), pool.getMaximumThinVolumeSize(), pool.getMaximumThickVolumeSize())); // set default utilization/subscription limits double poolSubscriptionPercent = CapacityMatcher.getMaxPoolSubscriptionPercentage(pool, _coordinator); double poolUtilizationPercent = CapacityMatcher.getMaxPoolUtilizationPercentage(pool, _coordinator); pool.setMaxThinPoolSubscriptionPercentage((int) poolSubscriptionPercent); pool.setMaxPoolUtilizationPercentage((int) poolUtilizationPercent); } String maxSubscriptionPercent = getCIMPropertyValue(poolInstance, SmisConstants.CP_EMCMAXSUBSCRIPTIONPERCENT); _logger.info( String.format( "Discovered maximum subscription percent of storage pool %s from array : %s ", pool.getPoolName(), maxSubscriptionPercent)); // null value indicates "not available". Integer newMaxSubscriptionPercentFromArray = maxSubscriptionPercent == null ? null : new Integer(maxSubscriptionPercent); _logger.info( String.format( "New maximum subscription percent of storage pool %s from array : %s ", pool.getPoolName(), newMaxSubscriptionPercentFromArray)); processMaxSubscriptionPercent( newMaxSubscriptionPercentFromArray, pool, _dbClient, _eventManager); String subscribedCapacity = getCIMPropertyValue(poolInstance, SmisConstants.CP_SUBSCRIBEDCAPACITY); if (null != subscribedCapacity) { pool.setSubscribedCapacity(ControllerUtils.convertBytesToKBytes(subscribedCapacity)); } pool.setFreeCapacity(SmisUtils.getFreeCapacity(poolInstance)); pool.setTotalCapacity(SmisUtils.getTotalCapacity(poolInstance)); pool.setPoolClassName(poolClassName); pool.setSupportedResourceTypes(supportedVolumeTypes); String operationalStatus = determineOperationalStatus(poolInstance); if (!newPool && (ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getOperationalStatus(), operationalStatus) || ImplicitPoolMatcher.checkPoolPropertiesChanged(pool.getProtocols(), protocols) || ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getCompatibilityStatus(), DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name()) || ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getDiscoveryStatus(), DiscoveredDataObject.DiscoveryStatus.VISIBLE.name()))) { modifiedPool = true; } pool.addProtocols(protocols); pool.setOperationalStatus(operationalStatus); pool.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name()); pool.setDiscoveryStatus(DiscoveredDataObject.DiscoveryStatus.VISIBLE.name()); Set<String> diskDrives = new HashSet<String>(); String driveTypes = getCIMPropertyValue(poolInstance, EMC_DRIVE_TYPE); if (null != driveTypes) { String driveTypesArr[] = driveTypes.split(SPACE_STR_DELIM); if (device.checkIfVmax3() && driveTypesArr.length == 1 && driveTypesArr[0].equals(MIXED_DRIVE_TYPE)) { driveTypesArr = getVMAX3PoolDriveTypes(device, poolInstance); } for (String driveType : driveTypesArr) { String driveDisplayName = SupportedDriveTypeValues.getDiskDriveDisplayName(driveType); if (null == driveDisplayName) { _logger.warn( "UnSupported DiskDrive Type : {} resulting in drives not getting discovered for this pool: {}", driveType, getCIMPropertyValue(poolInstance, Constants.INSTANCEID)); continue; } diskDrives.add(driveDisplayName); } if (!newPool && !modifiedPool && ImplicitPoolMatcher.checkPoolPropertiesChanged( pool.getSupportedDriveTypes(), diskDrives)) { modifiedPool = true; } pool.addDriveTypes(diskDrives); } _logger.info("Discovered disk drives:[{}] for pool id:{}", driveTypes, pool.getId()); if (newPool) { _newPoolList.add(pool); // add new pools to modified pools list to consider them for implicit pool matching. if (!poolsToMatchWithVpool.containsKey(pool.getId())) { poolsToMatchWithVpool.put(pool.getId(), pool); } } else { _updatePoolList.add(pool); // add to modified pool list if pool's property which is required for vPool matcher, has // changed. // No need to check whether the pool is already there in the list here // because this processor is the first to discover pools. if (modifiedPool && !poolsToMatchWithVpool.containsKey(pool.getId())) { poolsToMatchWithVpool.put(pool.getId(), pool); } } }