/*
* Copyright (c) 2008-2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.smis.ibm;
import java.util.ArrayList;
import java.util.List;
import javax.cim.CIMArgument;
import javax.cim.CIMInstance;
import javax.cim.CIMObjectPath;
import javax.cim.CIMProperty;
import javax.wbem.CloseableIterator;
import javax.wbem.WBEMException;
import javax.wbem.client.WBEMClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.cimadapter.connections.cim.CimConnection;
import com.emc.storageos.cimadapter.connections.cim.CimObjectPathCreator;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.StoragePool;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.plugins.common.Constants;
import com.emc.storageos.volumecontroller.impl.smis.CIMArgumentFactory;
import com.emc.storageos.volumecontroller.impl.smis.CIMConnectionFactory;
import com.emc.storageos.volumecontroller.impl.smis.CIMPropertyFactory;
/**
* This class will contain functions and properties related to creating
* CIMObjectPath objects.
*/
public class IBMCIMObjectPathFactory implements IBMSmisConstants {
private final static Logger _log = LoggerFactory
.getLogger(IBMCIMObjectPathFactory.class);
private final static String REPLICATION_GROUP_NAME_FORMAT = "%s:%s-%s";
CIMArgumentFactory _cimArgument = null;
CIMPropertyFactory _cimProperty = null;
CIMConnectionFactory _cimConnection = null;
DbClient _dbClient;
private String _systemNamePrefix;
private String _paramNamePrefix;
public void setCimArgumentFactory(CIMArgumentFactory cimArgumentFactory) {
_cimArgument = cimArgumentFactory;
}
public void setCimPropertyFactory(CIMPropertyFactory cimPropertyFactory) {
_cimProperty = cimPropertyFactory;
}
public void setCimConnectionFactory(CIMConnectionFactory connectionFactory) {
_cimConnection = connectionFactory;
}
public void setDbClient(DbClient dbClient) {
_dbClient = dbClient;
}
public void setSystemNamePrefix(String systemNamePrefix) {
_systemNamePrefix = systemNamePrefix;
}
public String prefixWithSystemName(String str) {
return _systemNamePrefix.concat(str);
}
public void setParamNamePrefix(String paramNamePrefix) {
_paramNamePrefix = paramNamePrefix;
}
public String prefixWithParamName(String str) {
return _paramNamePrefix.concat(str);
}
/*
* (non-Javadoc) Construct object path of
* IBMTSDS_StorageConfigurationService.
*
* Example - Namespace: "/root/ibm"
* CreationClassName="IBMTSDS_StorageConfigurationService"
* Name="StorageConfigurationService for IBM.2810-7825363"
* SystemCreationClassName="IBMTSDS_StorageSystem"
* SystemName="IBM.2810-7825363"
*/
public CIMObjectPath getConfigSvcPath(StorageSystem storageDevice) {
CIMObjectPath configSvcPath;
try {
String systemName = storageDevice.getSerialNumber();
CIMProperty[] configSvcPropKeys = {
_cimProperty.string(CP_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_CONFIGURATION_SERVICE)),
_cimProperty.string(CP_NAME,
STORAGE_CONFIGURATION_SERVICE_NAME + systemName),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, systemName) };
configSvcPath = CimObjectPathCreator.createInstance(
prefixWithParamName(STORAGE_CONFIGURATION_SERVICE),
Constants.IBM_NAMESPACE, configSvcPropKeys);
} catch (Exception e) {
_log.error(e.getMessage(), e);
throw new IllegalStateException("Problem getting config service: "
+ storageDevice.getLabel());
}
return configSvcPath;
}
/**
* Create object path for storage pool.
*/
public CIMObjectPath getStoragePoolPath(StoragePool storagePool) {
CIMProperty[] poolKeys = { _cimProperty.string(CP_INSTANCE_ID,
storagePool.getNativeId()) };
return CimObjectPathCreator.createInstance(
storagePool.getPoolClassName(), Constants.IBM_NAMESPACE,
poolKeys);
}
/**
* Construct object path of block object.
*/
public CIMObjectPath getBlockObjectPath(StorageSystem storage,
BlockObject blockObject) {
return getObjectPath(storage, blockObject.getNativeId());
}
/**
* Construct object paths of volumes.
*/
public CIMObjectPath[] getVolumePaths(StorageSystem storageDevice,
String[] volumeNames) throws Exception {
ArrayList<CIMObjectPath> theElementsList = new ArrayList<CIMObjectPath>();
for (String volumeName : volumeNames) {
theElementsList.add(getObjectPath(storageDevice, volumeName));
}
return theElementsList
.toArray(new CIMObjectPath[theElementsList.size()]);
}
/**
* Construct object path with given volume's native ID
*/
private CIMObjectPath getObjectPath(StorageSystem storage, String nativeId) {
@SuppressWarnings("rawtypes")
CIMProperty[] volumeKeys = {
_cimProperty.string(CP_CREATION_CLASS_NAME, CP_STORAGE_VOLUME),
_cimProperty.string(CP_DEVICE_ID, nativeId),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME,
_paramNamePrefix.concat(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, storage.getSerialNumber()) };
return CimObjectPathCreator.createInstance(
CP_STORAGE_VOLUME,
Constants.IBM_NAMESPACE, volumeKeys);
}
/**
* Return requested output argument.
*/
public Object getFromOutputArgs(CIMArgument[] outputArguments, String key) {
Object element = null;
for (CIMArgument outArg : outputArguments) {
if (outArg != null) {
if (outArg.getName().equals(key)) {
element = outArg.getValue();
break;
}
}
}
return element;
}
/**
* Construct object path of Storage HardwareID management service.
*/
public CIMObjectPath getStorageHardwareIDManagementService(
StorageSystem storage) {
String systemName = storage.getSerialNumber();
CIMProperty[] properties = {
_cimProperty
.string(CP_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_HARDWARE_ID_MANAGEMENT_SERVICE)),
_cimProperty
.string(CP_NAME,
STORAGE_HARDWARE_ID_MANAGEMENT_SERVICE_NAME
+ systemName),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, systemName) };
return CimObjectPathCreator.createInstance(
prefixWithParamName(STORAGE_HARDWARE_ID_MANAGEMENT_SERVICE),
Constants.IBM_NAMESPACE, properties);
}
/**
* Construct object path of controller configuration service.
*/
public CIMObjectPath getControllerConfigSvcPath(StorageSystem storageDevice) {
String systemName = storageDevice.getSerialNumber();
CIMProperty[] configSvcPropKeys = {
_cimProperty.string(CP_CREATION_CLASS_NAME,
prefixWithParamName(CONTROLLER_CONFIGURATION_SERVICE)),
_cimProperty.string(CP_NAME, CONTROLLER_CONFIGURATION_SERVICE_NAME + systemName),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, systemName)
};
return CimObjectPathCreator.createInstance(prefixWithParamName(CONTROLLER_CONFIGURATION_SERVICE),
Constants.IBM_NAMESPACE, configSvcPropKeys);
}
/**
* Get protocol controller object path.
*
* @param storage StorageSystem
* @param protocolControllerId String of protocol controller ID
* @return CIMObjectPath of protocol controller
*/
public CIMObjectPath getSCSIProtocolControllerPath(StorageSystem storage,
String protocolControllerId) {
if (protocolControllerId == null || protocolControllerId.isEmpty()) {
return null;
}
String creationClass = CP_SCSI_PROTOCOL_CONTROLLER;
CIMProperty[] keys = {
_cimProperty.string(CP_CREATION_CLASS_NAME, creationClass),
_cimProperty.string(CP_DEVICE_ID, protocolControllerId),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME, prefixWithParamName(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, storage.getSerialNumber())
};
return CimObjectPathCreator.createInstance(creationClass, Constants.IBM_NAMESPACE, keys);
}
/**
* Get protocol controllers in output argument.
*/
public CIMObjectPath[] getProtocolControllersFromOutputArgs(CIMArgument[] outputArguments) {
CIMObjectPath[] protocolControllers = null;
for (CIMArgument outputArgument : outputArguments) {
if ((outputArgument != null) && outputArgument.getName().equals(CP_PROTOCOL_CONTROLLERS)) {
protocolControllers = (CIMObjectPath[]) outputArgument.getValue();
break;
}
}
return protocolControllers;
}
public CIMObjectPath getReplicationSvcPath(StorageSystem storageDevice) {
String replicationSvcClassName = prefixWithParamName(REPLICATION_SERVICE);
@SuppressWarnings("rawtypes")
CIMProperty[] replicationSvcKeys = {
_cimProperty.string(CP_CREATION_CLASS_NAME,
replicationSvcClassName),
_cimProperty.string(CP_NAME, REPLICATION_SERVICE_NAME
+ storageDevice.getSerialNumber()),
_cimProperty.string(CP_SYSTEM_CREATION_CLASS_NAME,
prefixWithParamName(STORAGE_SYSTEM)),
_cimProperty.string(CP_SYSTEM_NAME, storageDevice.getSerialNumber()) };
return CimObjectPathCreator.createInstance(replicationSvcClassName,
Constants.IBM_NAMESPACE, replicationSvcKeys);
}
public CIMObjectPath getConsistencyGroupPath(StorageSystem storage,
String groupName) {
String groupInstanceName = String.format(REPLICATION_GROUP_NAME_FORMAT,
_paramNamePrefix, storage.getSerialNumber(), groupName);
@SuppressWarnings("rawtypes")
CIMProperty[] replicationGroupKeys = { _cimProperty.string(
CP_INSTANCE_ID, groupInstanceName) };
return CimObjectPathCreator.createInstance(CP_CONSISTENCY_GROUP,
Constants.IBM_NAMESPACE, replicationGroupKeys);
}
public CIMObjectPath getSnapshotGroupPath(StorageSystem storage,
String groupName) {
CIMObjectPath queryPath = CimObjectPathCreator.createInstance(CP_SNAPSHOT_GROUP,
Constants.IBM_NAMESPACE, null);
return getObjectPathByName(storage, queryPath, "ElementName", groupName);
}
/**
* Return IBMTSDS_StorageSynchronized instance referenced by the given
* BlockObject.
*
* @param storage
* @param subject
* @return CIMObjectPath
*/
public CIMObjectPath getSyncObject(StorageSystem storage,
BlockObject subject) {
CloseableIterator<CIMObjectPath> syncReference = null;
CIMObjectPath syncObjectPath = NULL_IBM_CIM_OBJECT_PATH;
try {
CIMObjectPath subjectPath = getBlockObjectPath(storage, subject);
syncReference = _cimConnection.getConnection(storage)
.getCimClient()
.referenceNames(subjectPath, CP_STORAGE_SYNCHRONIZED, null);
if (syncReference != null) {
while (syncReference.hasNext()) {
syncObjectPath = syncReference.next();
if (syncObjectPath != null) {
break;
}
}
}
} catch (WBEMException e) {
_log.warn(String.format("Trying to find syncObject for %s failed",
subject.getId()));
} finally {
if (syncReference != null) {
syncReference.close();
}
}
return syncObjectPath;
}
public CIMObjectPath getGroupSynchronizedPath(StorageSystem storage, String snapGroupName) {
CIMObjectPath queryPath = CimObjectPathCreator.createInstance(CP_GROUP_SYNCHRONIZED,
Constants.IBM_NAMESPACE, null);
return getObjectPathByName(storage, queryPath, "RelationshipName", snapGroupName);
}
@SuppressWarnings("rawtypes")
public CIMObjectPath getCimObjectPathFromOutputArgs(
CIMArgument[] outputArguments, String key) {
CIMObjectPath cimObjectPath = null;
for (CIMArgument outArg : outputArguments) {
if (outArg != null) {
if (outArg.getName().equals(key)) {
cimObjectPath = (CIMObjectPath) outArg.getValue();
break;
}
}
}
return cimObjectPath;
}
/**
* Executes query
*
* @param storageSystem
* @param query
* @param queryLanguage
* @return list of matched instances
*/
public List<CIMInstance> executeQuery(StorageSystem storageSystem,
CIMObjectPath objectPath, String query, String queryLanguage) {
CloseableIterator<CIMInstance> iterator = null;
CimConnection connection = _cimConnection.getConnection(storageSystem);
WBEMClient client = connection.getCimClient();
_log.info(String.format(
"Executing query: %s, objectPath: %s, query language: %s",
query, objectPath, queryLanguage));
List<CIMInstance> instanceList = new ArrayList<CIMInstance>();
try {
iterator = client.execQuery(objectPath, query, queryLanguage);
while (iterator.hasNext()) {
CIMInstance instance = iterator.next();
instanceList.add(instance);
}
} catch (WBEMException we) {
_log.error(
"Caught an error while attempting to execute query and process query result. Query: "
+ query, we);
} finally {
if (iterator != null) {
iterator.close();
}
}
return instanceList;
}
/**
* Look up CIMObjectPath by property value. The value has to be unique on array.
*
* @param storage
* @param path CIMObjectPath for the query (only object name, no key)
* @param prop property (string type) that used in lookup
* @param value string value
* @return CIMObjectPath of returned instance, or null
*/
private CIMObjectPath getObjectPathByName(StorageSystem storage, CIMObjectPath path, String prop, String value) {
String query = String.format(
"Select * From %s Where %s=\"%s\"",
path.getObjectName(), prop, value);
List<CIMInstance> instances = executeQuery(storage, path, query, "WQL");
if (instances.isEmpty()) {
return null;
}
else {
return instances.get(0).getObjectPath();
}
}
}