/* * Copyright (c) 2008-2012 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.monitoring; import java.net.URI; import java.util.ArrayList; import java.util.List; import com.emc.storageos.db.client.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.helpers.MessageFormatter; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.constraint.AlternateIdConstraint; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.client.model.FileShare; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.volumecontroller.impl.ControllerUtils; /** * This abstract base class encapsulates behavior common for events generated * from monitored storage devices. RecordableDeviceEvent implements the methods * of the {@link RecordableEvent} interface for getting the tenant, project, * vpool, and user information to be recorded with the event. This information is * obtained from the database resource, i.e., Volume, Fileshare, etc..., that is * impacted by the event. This class will find the resource using the alternate * native identifier for the resource, which is provided by an implementation * specific class that extends the RecordableDeviceEvent. The resource reference * is then used to provide the tenant, project, vpool, and user when the * associated method is invoked. */ public abstract class RecordableDeviceEvent implements RecordableEvent { // A reference to the database client. protected DbClient _dbClient; // A reference to the resource, i.e., Volume, Fileshare, in the database // that is impacted by the event. private DataObject _resource = null; public void setResource(DataObject resource) { _resource = resource; } // The logger. protected static Logger s_logger = LoggerFactory.getLogger(RecordableDeviceEvent.class); /** * Constructor * * @param dbClient * A reference to the data base client. */ public RecordableDeviceEvent(DbClient dbClient) { _dbClient = dbClient; } /** * {@inheritDoc} */ @Override public URI getTenantId() { URI tenantOrg = null; URI projectURI = getProjectId(); if (projectURI != null) { tenantOrg = ControllerUtils.getProjectTenantOrgURI(_dbClient, getProjectId()); } if (tenantOrg == null) { // If none found we have to have a blank value in monitoring. tenantOrg = URI.create(""); } return tenantOrg; } /** * {@inheritDoc} */ @Override public URI getUserId() { // Not currently available from the resource. To be added when // security is put in place return null; } /** * {@inheritDoc} */ @Override public URI getProjectId() { URI projectId = null; DataObject resource = getResource(); if (resource != null) { if (resource instanceof Volume) { Volume volume = (Volume) resource; projectId = volume.getProject().getURI(); } else if (resource instanceof FileShare) { FileShare fs = (FileShare) resource; projectId = fs.getProject().getURI(); } else if (resource instanceof BlockSnapshot) { BlockSnapshot bs = (BlockSnapshot) resource; projectId = bs.getProject().getURI(); } else { s_logger.info("Error getting projectId for event. Unexpected resource type {}.", resource.getClass().getName()); } } return projectId; } /** * {@inheritDoc} */ @Override public URI getVirtualPool() { URI vpool = null; DataObject resource = getResource(); if (resource != null) { if (resource instanceof Volume) { Volume volume = (Volume) resource; vpool = volume.getVirtualPool(); } else if (resource instanceof BlockSnapshot) { BlockSnapshot bs = (BlockSnapshot) resource; Volume volume = _dbClient.queryObject(Volume.class, bs.getParent().getURI()); if (volume != null) { vpool = volume.getVirtualPool(); } } else if (resource instanceof FileShare) { FileShare fs = (FileShare) resource; vpool = fs.getVirtualPool(); } else { s_logger.info("Error getting vpool for event. Unexpected resource type {}.", resource.getClass().getName()); } } return vpool; } /** * {@inheritDoc} */ @Override public URI getResourceId() { URI resourceId = null; DataObject resource = getResource(); if (resource != null) { resourceId = resource.getId(); } return resourceId; } /** * Returns the Class reference for the actual type of the resource impacted * by the event, which must be a subclass of {@link DataObject}. Implemented * by derived classes by extracting the information from the native event to * identify the resource type. * * @return The Class reference for the actual type of the resource impacted * by the event */ protected abstract Class<? extends DataObject> getResourceClass(); /** * Finds the resource in the database impacted by an event using the * alternate native id for the resource and the class of the resource as * provided by the concrete derived class. * * @return A reference to the resource in the database impacted by the * event. */ private DataObject getResource() { String altNativeId = null; if (_resource == null && (altNativeId = getNativeGuid()) != null) { Class<? extends DataObject> resourceClass = getResourceClass(); s_logger.debug("Looking up resource type: {} ", resourceClass.getSimpleName()); if (resourceClass == null) { return null; } try { List<URI> resourceURIs = new ArrayList<URI>(); if (resourceClass.getName().equals(Volume.class.getName())) { resourceURIs = _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeNativeGuidConstraint(altNativeId)); } else if (resourceClass.getName().equals(BlockSnapshot.class.getName())) { resourceURIs = _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getBlockSnapshotsByNativeGuid(altNativeId)); } else if (resourceClass.getName().equals(FileShare.class.getName())) { resourceURIs = _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getFileShareNativeIdConstraint(altNativeId)); } else if (resourceClass.getName().equals(StoragePort.class.getName())) { resourceURIs = _dbClient.queryByConstraint(AlternateIdConstraint.Factory .getStoragePortByNativeGuidConstraint(altNativeId)); } else if (resourceClass.getName().equals(StoragePool.class.getName())) { resourceURIs = _dbClient.queryByConstraint(AlternateIdConstraint.Factory .getStoragePoolByNativeGuidConstraint(altNativeId)); } s_logger.debug("[Monitoring] -> Number of resources found {} having Native Guid: {}", resourceURIs.size(), altNativeId); if (resourceURIs.size() == 1) { List<? extends DataObject> objects = _dbClient.queryObject(resourceClass, resourceURIs); _resource = objects.get(0); } else if (resourceURIs.size() > 1) { List<? extends DataObject> objects = _dbClient.queryObject(resourceClass, resourceURIs); for (DataObject obj : objects) { s_logger.info("[Monitoring] -> Resource found with native guid {} with its InActive status {}", altNativeId, obj.getInactive()); if (!obj.getInactive()) { _resource = obj; s_logger.info("[Monitoring] -> Found resource with label : {} and id : {}", _resource.getLabel(), _resource.getId()); } else { s_logger.info("[Monitoring] -> InActive resource found and Ignoring to update"); } } } else { s_logger.debug("Could not find resource of type {} with nativeGUID {}", resourceClass.getSimpleName(), altNativeId); } } catch (Exception t) { s_logger.error( MessageFormatter.format("Error finding resource of type {} with nativeGUID {}", resourceClass.getName(), altNativeId).getMessage(), t); } } return _resource; } /** * Event identifier * * @return The eventId */ public abstract String getEventId(); /** * Event severity * * @return the Severity of an Alert */ public abstract String getSeverity(); }