/* * Copyright (c) 2012 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.common; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.constraint.ContainmentConstraint; import com.emc.storageos.db.client.constraint.URIQueryResultList; import com.emc.storageos.db.client.constraint.impl.ContainmentConstraintImpl; import com.emc.storageos.db.client.model.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Class provides method for checking dependencies * used by GC and apisvc decommission api */ public class DependencyChecker { private static final Logger _log = LoggerFactory.getLogger(DependencyChecker.class); final private DependencyTracker _dependencyTracker; final private DbClient _dbClient; /** * Constructor takes db client and DependencyTracker * * @param dbClient * @param dependencyTracker */ public DependencyChecker(DbClient dbClient, DependencyTracker dependencyTracker) { _dbClient = dbClient; _dependencyTracker = dependencyTracker; } /** * Constructor takes db client and DataObjectScanner * * @param dbClient * @param dataObjectScanner */ public DependencyChecker(DbClient dbClient, DataObjectScanner dataObjectScanner) { _dbClient = dbClient; _dependencyTracker = dataObjectScanner.getDependencyTracker(); } /** * checks to see if any references exist for this uri * uses dependency list created from relational indices * * @param uri id of the DataObject * @param type DataObject class name * @param onlyActive if true, checks for active references only (expensive) * @return null if no references exist on this uri, return the type of the dependency if exist */ public String checkDependencies(URI uri, Class<? extends DataObject> type, boolean onlyActive) { return checkDependencies(uri, type, onlyActive, null); } /** * checks to see if any references exist for this uri * uses dependency list created from relational indices * * @param uri id of the DataObject * @param type DataObject class name * @param onlyActive if true, checks for active references only (expensive) * @param excludeTypes optional list of classes that can be excluded as dependency * @return null if no references exist on this uri, return the type of the dependency if exist */ public String checkDependencies(URI uri, Class<? extends DataObject> type, boolean onlyActive, List<Class<? extends DataObject>> excludeTypes) { List<DependencyTracker.Dependency> dependencies = _dependencyTracker.getDependencies(type); // no dependencies - nothing to do if (dependencies.isEmpty()) { return null; } for (DependencyTracker.Dependency dependency : dependencies) { if (excludeTypes != null) { if (excludeTypes.contains(dependency.getType())) { continue; } } // Query relational index to see if any dependents exist ContainmentConstraint constraint = new ContainmentConstraintImpl(uri, dependency.getType(), dependency.getColumnField()); URIQueryResultList list = new URIQueryResultList(); _dbClient.queryByConstraint(constraint, list); if (list.iterator().hasNext()) { if (!onlyActive || checkIfAnyActive(list, dependency.getType())) { _log.info("{}: active references of type {} found", uri.toString(), dependency.getType().getSimpleName()); return dependency.getType().getSimpleName(); } } } return null; } /** * Checks if any of the uris from the list are active * * @param uris * @param type * @return true if active uri found, false otherwise */ public boolean checkIfAnyActive(URIQueryResultList uris, Class<? extends DataObject> type) { Iterator<URI> uriIterator = uris.iterator(); while (uriIterator.hasNext()) { int added = 0, found = 0; List<URI> urisToQuery = new ArrayList<URI>(); for (int i = 0; (i < 100) && uriIterator.hasNext(); i++) { urisToQuery.add(uriIterator.next()); added++; } List<? extends DataObject> results = _dbClient.queryObjectField(type, "inactive", urisToQuery); for (DataObject obj : results) { found++; if (!obj.getInactive()) { return true; } } if (found != added) { return true; } } return false; } }