/* * Copyright (c) 2008-2011 EMC Corporation * All Rights Reserved */ package com.emc.storageos.plugins.common; import java.util.List; import java.util.Map; import javax.cim.CIMArgument; import javax.cim.CIMInstance; import javax.cim.CIMObjectPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.plugins.BaseCollectionException; import com.emc.storageos.plugins.common.domainmodel.Operation; import com.emc.storageos.plugins.metering.smis.SMIPluginException; import com.google.common.collect.Iterables; /** * All Processors should extend this abstract Class. If the output got from * SMIProviders is CIMArgument[], then we need a CIMArg processor, whose * responsibility is to only handle CIMArg[] values, and if the output is * CIMPath, then we need a CIMPath processor which can handle CIMPath * outputs.The idea is to follow the principle * "Class with Single Responsibility" */ public abstract class Processor { private Logger _logger = LoggerFactory .getLogger(Processor.class); protected static final String CreationClassNamestr = "CreationClassName"; protected static final String SystemCreationClassNamestr = "SystemCreationClassName"; protected static final String SystemNamestr = "SystemName"; protected static final String DeviceIDstr = "DeviceID"; protected static final String _symm = "SYMM"; protected static final String _clar = "CLAR"; protected static final String _symmetrix = "SYMMETRIX"; protected static final String _clariion = "CLARIION"; protected static final String _symmvolume = "Symm_StorageVolume"; protected static final String _clarvolume = "Clar_StorageVolume"; protected static final String _symmsystem = "Symm_StorageSystem"; protected static final String _clarsystem = "Clar_StorageSystem"; protected static final String _volume = "Volume"; protected static final String _spaceConsumed = "AFSPSpaceConsumed"; protected static final String _spaceLimit = "SpaceLimit"; protected static final String _SEVEN = "7"; protected static final String _VOL = "VOLUME"; protected static final String _plusDelimiter = "+"; protected static final String _SVSystemName = "SVSystemName"; protected static final String _SVDeviceID = "SVDeviceID"; protected static final String _emcspaceConsumed = "EMCSpaceConsumed"; /** * Process the result got from data sources. * * @param operation * : Domain Logic operation. * @param resultObj * : Result got from 3rd party Instances. * @param keyMap * : common datastructure to hold values. * @return * @throws SMIPluginException * ex. */ public abstract void processResult( Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException; /** * set the required arguments for processor to process Result. to-Do :for * future use * * @param inputArgs * : List of arguments. To-Do : for future purpose * @return */ protected void setPrerequisiteObjects(List<Object> inputArgs) throws BaseCollectionException { // TODO Auto-generated method stub } /** * create the nativeID key from CIMObjectPath * * @param sourcePath * @return String */ protected String createKeyfromPath(CIMObjectPath sourcePath) { String systemName = sourcePath.getKey(SystemNamestr).getValue().toString() .replaceAll(Constants.SMIS80_DELIMITER_REGEX, Constants.PLUS); String key = systemName.toUpperCase() + _plusDelimiter + _VOL + _plusDelimiter + sourcePath.getKey(DeviceIDstr).getValue().toString(); _logger.debug("Key Created :{} ", key); return key; } /** * Add CIMObject Paths to Map. * * @param keyMap * @param operation * @param path * @throws SMIPluginException */ @SuppressWarnings("serial") protected void addPath( Map<String, Object> keyMap, String key, CIMObjectPath path) throws BaseCollectionException { try { Object result = keyMap.get(key); if (keyMap.containsKey(key) && result instanceof List<?>) { @SuppressWarnings("unchecked") List<CIMObjectPath> cimPathList = (List<CIMObjectPath>) keyMap .get(key); cimPathList.add(path); keyMap.put(key, cimPathList); } else { keyMap.put(key, path); } } catch (Exception ex) { throw new BaseCollectionException( "Error while adding CIMObject Path to Map : " + path, ex) { @Override public int getErrorCode() { // To-Do errorCode return -1; } }; } } /** * Add CIMObject Paths to Map. * * @param keyMap * @param operation * @param path * @throws SMIPluginException */ @SuppressWarnings("serial") protected void addInstance( Map<String, Object> keyMap, String key, CIMInstance instance) throws BaseCollectionException { try { Object result = keyMap.get(key); if (keyMap.containsKey(key) && result instanceof List<?>) { @SuppressWarnings("unchecked") List<CIMInstance> cimInstanceList = (List<CIMInstance>) keyMap .get(key); cimInstanceList.add(instance); keyMap.put(key, cimInstanceList); } else { keyMap.put(key, instance); } } catch (Exception ex) { throw new BaseCollectionException( "Error while adding CIMInstance to Map : " + instance.getObjectPath(), ex) { @Override public int getErrorCode() { // To-Do errorCode return -1; } }; } } /** * Get Volume Metrics Object from Map. * * @param keyMap * @param key * @return Stats * * To-Do: move this to util * @throws SMIPluginException */ @SuppressWarnings("serial") protected Object getMetrics(Map<String, Object> keyMap, String key) throws BaseCollectionException { Object metrics = null; if (keyMap.containsKey(key)) { metrics = (Object) keyMap.get(key); } return metrics; } /* * Create key from CIMProperties * * @param volumeInstance * * @return String */ protected String createKeyfromProps(CIMInstance volumeInstance) { String SystemName = volumeInstance.getPropertyValue(_SVSystemName).toString().toUpperCase(); String DeviceID = volumeInstance.getPropertyValue(_SVDeviceID).toString().toUpperCase(); return createVolumeIdKeyForArray(SystemName, DeviceID); } /** * Calculate Provisioned Capacity * * @param volumeInstance * @return long */ protected long returnProvisionedCapacity(CIMInstance volumeInstance, Map<String, Object> keyMap) { long blocksize, blocks; if (keyMap.containsKey(Constants.IS_NEW_SMIS_PROVIDER) && Boolean.valueOf(keyMap.get(Constants.IS_NEW_SMIS_PROVIDER).toString())) { blocksize = Long.parseLong(volumeInstance.getPropertyValue( Constants.BLOCK_SIZE).toString()); blocks = Long.parseLong(volumeInstance.getPropertyValue( Constants.NUMBER_OF_BLOCKS).toString()); } else { blocksize = Long.parseLong(volumeInstance.getPropertyValue( Constants.SV_BLOCK_SIZE).toString()); blocks = Long.parseLong(volumeInstance.getPropertyValue( Constants.SV_NUMBER_BLOCKS).toString()); } return blocksize * blocks; } /** * get Property Value; * * @param poolInstance * @param propName * @return */ protected String getCIMPropertyValue(CIMInstance instance, String propName) { String value = null; try { value = instance.getPropertyValue(propName).toString(); if (propName.equals(Constants.INSTANCEID) && value.contains(Constants.SMIS80_DELIMITER)) { value = value.replaceAll(Constants.SMIS80_DELIMITER_REGEX, Constants.PLUS); } } catch (Exception e) { _logger.debug("Property {} Not found in returned Instance {}", propName, instance.getObjectPath()); } return value; } /** * get Property Value; * * @param poolInstance * @param propName * @return */ protected String getCIMPropertyValue(CIMObjectPath path, String propName) { String value = null; try { value = path.getKey(propName).getValue().toString(); if (value.contains(Constants.SMIS80_DELIMITER)) { value = value.replaceAll(Constants.SMIS80_DELIMITER_REGEX, Constants.PLUS); } } catch (Exception e) { _logger.warn("Property {} Not found in returned Instance {}", propName, path); } return value; } /** * get property array value; * * @param instance * @param propName * @return */ protected String[] getCIMPropertyArrayValue(CIMInstance instance, String propName) { String[] value = null; try { value = (String[]) instance.getPropertyValue(propName); } catch (Exception e) { _logger.warn("Property {} Not found in returned Instance {}", propName, instance.getObjectPath()); } return value; } protected boolean checkForNull(Object obj) { if (null == obj) { return true; } return false; } /** * get Message. * * @param ex WBEMException. * @return String. */ protected String getMessage(final Exception ex) { String cause = ex.getCause() != null ? ex.getCause().toString() : ""; String message = ex.getMessage() != null ? ex.getMessage() : ""; String error = ""; if (!cause.isEmpty()) { error = cause; } if (!message.isEmpty()) { error = error + "-" + message; } return error; } protected int getPartitionSize(Map<String, Object> keyMap) { @SuppressWarnings("unchecked") Map<String, String> props = (Map<String, String>) keyMap.get(Constants.PROPS); int size = Constants.DEFAULT_PARTITION_SIZE; if (null != props.get(Constants.METERING_RECORDS_PARTITION_SIZE)) { size = Integer.parseInt(props.get(Constants.METERING_RECORDS_PARTITION_SIZE)); } return size; } /** * return 1st Argument in inputArguments used to * call this SMI-S call. * * @return */ protected CIMObjectPath getObjectPathfromCIMArgument(List<Object> args) { Object[] arguments = (Object[]) args.get(0); return (CIMObjectPath) arguments[0]; } /** * return 1st Argument in inputArguments used to * call this SMI-S call. * * @return */ protected CIMObjectPath getObjectPathfromCIMArgument(List<Object> args, Map<String, Object> keyMap) { Object[] arguments = (Object[]) args.get(0); Boolean using80Delimiters = (Boolean) keyMap.get(Constants.USING_SMIS80_DELIMITERS); if (null != using80Delimiters && using80Delimiters) { return (CIMObjectPath) Util.normalizedWriteArgs(keyMap, arguments)[0]; } return (CIMObjectPath) arguments[0]; } /** * Return the 2nd argument in the input arguments, * which should be the current command object index * for this processor. * * @return the current command object index */ protected Integer getCurrentCommandIndex(List<Object> args) { int currentCommandIndex = (int) args.get(1); return currentCommandIndex; } protected String getValueAtGivenPositionFromTierId(Iterable<String> itr, int position) { return Iterables.get(itr, position); } public Object getFromOutputArgs(CIMArgument[] outputArguments, String key) { Object element = null; if (outputArguments != null) { for (CIMArgument outArg : outputArguments) { if (outArg != null && null != outArg.getName()) { if (outArg.getName().equals(key)) { element = outArg.getValue(); break; } } else { _logger.info("Provider returned unexpected values"); } } } return element; } /** * @param instance CIMInstance to be checked * @return true if name space match, otherwise false */ protected boolean isIBMInstance(CIMInstance instance) { return Constants.IBM_NAMESPACE.equals(instance.getObjectPath().getNamespace()) || instance.getClassName().startsWith(Constants.IBMXIV_CLASS_PREFIX); } /** * Create key from CIMProperties * * @param volumeInstance {@link CIMInstance} volume details. * * @return String */ protected String createKeyfor8x(CIMInstance volumeInstance) { String SystemName = volumeInstance.getPropertyValue(SystemNamestr) .toString().toUpperCase(); String DeviceID = volumeInstance.getPropertyValue(DeviceIDstr) .toString().toUpperCase(); String keyString = (createVolumeIdKeyForArray(SystemName, DeviceID)) .replaceAll(Constants.SMIS_80_STYLE, Constants.SMIS_PLUS_REGEX); return keyString; } /** * Method to create key Array+SerialNumber+VOLUME+VOLUMEID dynamically * from the returned Volume Instance, so that we can use this key to get * back its corresponding Stat Object * * @param systemName {@link String} Systemname or Array name * @param deviceId {@link String} device id * @return */ private String createVolumeIdKeyForArray(String systemName, String deviceId) { // Creating the key - Array+SerialNumber+VOLUME+VOLUMEID dynamically // from the returned Volume Instance, so that we can use this key to get // back its corresponding Stat Object StringBuilder key = new StringBuilder(systemName); key.append(Constants._plusDelimiter).append(_VOL); key.append(Constants._plusDelimiter).append(deviceId); return key.toString(); } }