/* * Copyright (c) 2008-2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.metering.smis.processor; import java.util.List; import java.util.Map; import javax.cim.CIMArgument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.Stat; import com.emc.storageos.db.client.model.StoragePort; import com.emc.storageos.plugins.AccessProfile; import com.emc.storageos.plugins.common.Constants; import com.emc.storageos.plugins.common.domainmodel.Operation; import com.emc.storageos.plugins.metering.smis.SMIPluginException; import com.emc.storageos.volumecontroller.impl.ControllerUtils; /** * FEPortStatsProcessor used in retrieving TotalIOs,KBytesTransferred and nativeGuid of FEPort. */ public class FEPortStatsProcessor extends CommonStatsProcessor { private Logger _logger = LoggerFactory.getLogger(FEPortStatsProcessor.class); PortMetricsProcessor portMetricsProcessor; public static enum FEPortMetric { UnKnown, InstanceID, ElementType, TotalIOs, KBytesTransferred, StatisticTime; private static final FEPortMetric[] metricCopyOfValues = values(); public static FEPortMetric lookup(String name) { for (FEPortMetric value : metricCopyOfValues) { if (value.name().equals(name)) { return value; } } return UnKnown; } } @SuppressWarnings("unchecked") @Override public void processResult( Operation operation, Object resultObj, Map<String, Object> keyMap) throws SMIPluginException { try { CIMArgument<?>[] outputArguments = (CIMArgument<?>[]) resultObj; DbClient dbClient = (DbClient) keyMap.get(Constants.dbClient); AccessProfile profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE); List<Stat> metricsObjList = (List<Stat>) keyMap.get(Constants._Stats); List<String> metricSequence = (List<String>) keyMap.get(Constants.STORAGEOS_FEPORT_MANIFEST); String[] feportsMetricValues = ((String[]) outputArguments[0].getValue())[0].split("\n"); List<StoragePort> systemPorts = ControllerUtils.getSystemPortsOfSystem(dbClient, profile.getSystemId()); _logger.debug("FEPort metricNames Sequence {}", metricSequence); // Step1: If there is no metric sequence, there is no need to // process the results. if (null != metricSequence && !metricSequence.isEmpty()) { // Step2: For each feport metric record for (String fePortMetricValue : feportsMetricValues) { if (fePortMetricValue.isEmpty()) { _logger.debug("Empty FEPort stats returned as part of Statistics Response"); continue; } String metrics[] = fePortMetricValue.split(Constants.SEMI_COLON); // Step 3: For each port in db for a given system. for (StoragePort port : systemPorts) { // Step 4: if port in db is null just continue. if (null == port) { continue; } else if (!port.getInactive() && metrics[0].endsWith(port.getPortName())) { // Step 5: Check whether provider returned port // exists in db or not. if port exists in db, // then create a PortStat object for it. _logger.debug("found FEPort in db for {}", port.getPortName()); createPortStatMetric(metricSequence, port, keyMap, metricsObjList, metrics); } } } // // compute port metric to trigger if any port allocation qualification changed. If there is // changes, run vpool matcher // portMetricsProcessor.triggerVpoolMatcherIfPortAllocationQualificationChanged(profile.getSystemId(), systemPorts); // // compute storage system's average of port metrics. Then, persist it into storage system object. // portMetricsProcessor.computeStorageSystemAvgPortMetrics(profile.getSystemId()); } else { _logger.error("failed processing FEPOrt Metric values as metric sequence is null."); } } catch (Exception e) { _logger.error("Failed while extracting stats for FEPorts: ", e); } resultObj = null; } /** * Create a new PortStat. * * @param metrics * @param portStatsList * @param port * @param keyMap */ private void createPortStatMetric(List<String> metricSequence, StoragePort port, Map<String, Object> keyMap, List<Stat> portStatsList, String metrics[]) { int count = 0; Stat portStat = new Stat(); Long kbytes = 0L; Long iops = 0L; String statisticTime = ""; for (String metricName : metricSequence) { portStat.setTimeCollected((Long) keyMap.get(Constants._TimeCollected)); portStat.setTimeInMillis((Long) keyMap.get(Constants._TimeCollected)); portStat.setNativeGuid(port.getNativeGuid()); portStat.setResourceId(port.getId()); portStat.setServiceType(Constants._Block); switch (FEPortMetric.lookup(metricName)) { case InstanceID: case ElementType: break; case TotalIOs: iops = ControllerUtils.getLongValue(metrics[count]); portStat.setTotalIOs(iops); break; case KBytesTransferred: kbytes = ControllerUtils.getLongValue(metrics[count]); portStat.setKbytesTransferred(kbytes); break; case StatisticTime: statisticTime = metrics[count]; break; default: _logger.warn("Ignoring unknown metric {} during system metric processing:", metricName); break; } count++; } portStatsList.add(portStat); // Process the port metrics. portMetricsProcessor.processFEPortMetrics(kbytes, iops, port, convertCIMStatisticTime(statisticTime)); } public PortMetricsProcessor getPortMetricsProcessor() { return portMetricsProcessor; } public void setPortMetricsProcessor(PortMetricsProcessor portMetricsProcessor) { this.portMetricsProcessor = portMetricsProcessor; } }