/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.security.geo; import java.net.URI; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.coordinator.client.service.CoordinatorClient; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.client.model.VirtualDataCenter; import com.emc.storageos.db.client.util.KeyspaceUtil; import com.emc.storageos.db.common.DependencyChecker; import com.emc.storageos.db.common.VdcUtil; public class GeoDependencyChecker { final private Logger log = LoggerFactory.getLogger(GeoDependencyChecker.class); private final DbClient dbClient; private final GeoClientCacheManager geoClientManager; private final DependencyChecker localDependencyChecker; public GeoDependencyChecker(DbClient dbClient, CoordinatorClient coordinator, DependencyChecker localDependencyChecker) { this.dbClient = dbClient; geoClientManager = new GeoClientCacheManager(); geoClientManager.setDbClient(dbClient); geoClientManager.setCoordinatorClient(coordinator); this.localDependencyChecker = localDependencyChecker; } /** * 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) { String depMsg = localDependencyChecker.checkDependencies(uri, type, true, excludeTypes); if (depMsg != null || KeyspaceUtil.isLocal(type)) { return depMsg; } // If there is any vdc under disconnect status, do not check dependency, return "" if (hasDisconnectedVdc()) { return ""; } List<URI> vDCIds = dbClient.queryByType(VirtualDataCenter.class, true); VirtualDataCenter vDC = null; for (URI vDCId : vDCIds) { if (vDCId.equals(VdcUtil.getLocalVdc().getId())) { continue; // skip local vDC } vDC = dbClient.queryObject(VirtualDataCenter.class, vDCId); GeoServiceClient client = geoClientManager.getGeoClient(vDC.getShortId()); log.debug("Query Geo server={}", client.getServiceURI()); try { String dependency = client.checkDependencies(type, uri, true); if (!dependency.isEmpty()) { log.info("Can't GC {} because depends on {} on {}", new Object[] { uri, dependency, vDCId }); return dependency; } } catch (Exception e) { log.error("Failed to query depenedency for {} on {} e=", new Object[] { uri, vDC.getShortId(), e }); log.error("so assume it has dependency"); return ""; } } log.debug("Geo object {} can be GC", uri); return null; } private boolean hasDisconnectedVdc() { boolean hasDiconnVdc = false; List<URI> vDCIds = dbClient.queryByType(VirtualDataCenter.class, true); VirtualDataCenter vDC = null; for (URI vDCId : vDCIds) { if (vDCId.equals(VdcUtil.getLocalVdc().getId())) { continue; // skip local vDC } vDC = dbClient.queryObject(VirtualDataCenter.class, vDCId); if (vDC.getConnectionStatus() == VirtualDataCenter.ConnectionStatus.DISCONNECTED || vDC.getConnectionStatus() == VirtualDataCenter.ConnectionStatus.DISCONNECTING) { log.info("Geo dependency check, vdc {} is under disconnect status", vDC.getShortId()); hasDiconnVdc = true; } } return hasDiconnVdc; } }