/*
* Copyright (c) 2008-2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.ibm.xiv;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.cim.CIMInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.StoragePool;
import com.emc.storageos.db.client.model.StoragePort;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.plugins.AccessProfile;
import com.emc.storageos.plugins.BaseCollectionException;
import com.emc.storageos.plugins.common.Constants;
import com.emc.storageos.plugins.common.domainmodel.Operation;
import com.emc.storageos.volumecontroller.impl.NativeGUIDGenerator;
import com.emc.storageos.volumecontroller.impl.StoragePoolAssociationHelper;
import com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.StorageEndPointProcessor;
import com.google.common.base.Joiner;
public class XIVStorageProtocolEndPointProcessor extends StorageEndPointProcessor {
private Logger _logger = LoggerFactory
.getLogger(XIVStorageProtocolEndPointProcessor.class);
private DbClient _dbClient;
private static final String NAME = "Name";
private List<Object> args;
@Override
public void processResult(
Operation operation, Object resultObj, Map<String, Object> keyMap)
throws BaseCollectionException {
try {
@SuppressWarnings("unchecked")
final Iterator<CIMInstance> it = (Iterator<CIMInstance>) resultObj;
_dbClient = (DbClient) keyMap.get(Constants.dbClient);
AccessProfile profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE);
@SuppressWarnings("unchecked")
Map<URI, StoragePool> poolsToMatchWithVpool = (Map<URI, StoragePool>) keyMap.get(Constants.MODIFIED_STORAGEPOOLS);
StorageSystem device = _dbClient.queryObject(StorageSystem.class, profile.getSystemId());
List<StoragePort> newPorts = new ArrayList<StoragePort>();
List<StoragePort> existingPorts = new ArrayList<StoragePort>();
while (it.hasNext()) {
CIMInstance endPointInstance = null;
StoragePort port = null;
try {
endPointInstance = it.next();
String name = getCIMPropertyValue(endPointInstance, NAME).toLowerCase();
String portInstanceID = getObjectPathfromCIMArgument(args).toString();
port = checkEthernetStoragePortExistsInDB(name, _dbClient, device);
URI portID = createEthernetStoragePort(keyMap, port, name,
portInstanceID, newPorts, existingPorts);
keyMap.put(endPointInstance.getObjectPath().toString(), portID);
addPath(keyMap, operation.getResult(),
endPointInstance.getObjectPath());
} catch (Exception e) {
_logger.warn("SCSI End Point Discovery failed for {}-->{}", "",
getMessage(e));
}
}
@SuppressWarnings("unchecked")
List<List<StoragePort>> portsUsedToRunNetworkConnectivity = (List<List<StoragePort>>) keyMap.get(Constants.STORAGE_PORTS);
portsUsedToRunNetworkConnectivity.add(newPorts);
// discovered ports used later to check for not visible ports
List<StoragePort> discoveredPorts = (List<StoragePort>) keyMap.get(Constants.DISCOVERED_PORTS);
discoveredPorts.addAll(newPorts);
discoveredPorts.addAll(existingPorts);
List<StoragePool> modifiedPools = StoragePoolAssociationHelper.getStoragePoolsFromPorts(_dbClient, newPorts, null);
for (StoragePool pool : modifiedPools) {
// pool matcher will be invoked on this pool
if (!poolsToMatchWithVpool.containsKey(pool.getId())) {
poolsToMatchWithVpool.put(pool.getId(), pool);
}
}
_logger.debug("# Pools used in invoking PoolMatcher during StorageProtoclEndPoint {}",
Joiner.on("\t").join(poolsToMatchWithVpool.keySet()));
} catch (Exception e) {
_logger.error("SCSI End Point Discovery failed -->{}", getMessage(e));
}
}
/**
* create Ethernet Storage Port.
* StoragePorts would have been created in SToragePorts Processor, but for ethernet those
* will not get updated to DB, as to get SCSIAddress ,we need a different SMI Class ProtocolEndPoint
* Algo :
* 1. Check if StorageEthernet Port available in DB.
* 2. If not, then get already created StoragePort, update SCSI Address and persist.
* 3. If yes, then just update the properties alone.
*
* @param keyMap
* @param port
* @param endPointInstance
* @param portInstanceID
* @throws IOException
*/
private URI createEthernetStoragePort(
Map<String, Object> keyMap, StoragePort port, String name,
String portInstanceID, List<StoragePort> newPorts, List<StoragePort> existingPorts) throws IOException {
StoragePort portinMemory = (StoragePort) keyMap.get(portInstanceID);
if (null == port) {
// Name Property's value --> iqn.23.....,t,0x0001
portinMemory.setPortNetworkId(name);
portinMemory.setPortEndPointID(name);
String portNativeGuid = NativeGUIDGenerator.generateNativeGuid(_dbClient, portinMemory);
portinMemory.setNativeGuid(portNativeGuid);
portinMemory.setLabel(portNativeGuid);
_dbClient.createObject(portinMemory);
newPorts.add(portinMemory);
return portinMemory.getId();
} else {
port.setPortName(portinMemory.getPortName());
port.setPortSpeed(portinMemory.getPortSpeed());
port.setPortEndPointID(name);
port.setCompatibilityStatus(portinMemory.getCompatibilityStatus());
port.setDiscoveryStatus(portinMemory.getDiscoveryStatus());
port.setOperationalStatus(portinMemory.getOperationalStatus());
port.setPortType(portinMemory.getPortType());
_dbClient.persistObject(port);
existingPorts.add(port);
return port.getId();
}
}
@Override
protected void setPrerequisiteObjects(List<Object> inputArgs)
throws BaseCollectionException {
args = inputArgs;
}
}