private <T extends DataObject> boolean hasDataInCF(Class<T> clazz) { if (excludeClasses.contains(clazz)) { return false; // ignore the data in those CFs } // true: query only active object ids, for below reason: // add VDC should succeed just when remove the data in vdc2. List<URI> ids = dbClient.queryByType(clazz, true, null, 2); if (clazz.equals(TenantOrg.class) || clazz.equals(ObjectStore.class)) { if (ids.size() > 1) { // at least one non-root tenant exist return true; } return false; } if (!ids.isEmpty()) { log.info("The class {} has data e.g. id={}", clazz.getSimpleName(), ids.get(0)); return true; } return false; }
private void updateBlackListForReconnectedVdc() { List<URI> vdcIds = dbClient.queryByType(VirtualDataCenter.class, true); dbClient.clearBlackList(); log.info("After clear, get current black list {}", dbClient.getBlacklist()); for (URI vdcId : vdcIds) { VirtualDataCenter vdc = dbClient.queryObject(VirtualDataCenter.class, vdcId); if (vdc.getConnectionStatus() == VirtualDataCenter.ConnectionStatus.DISCONNECTED) { log.info("Add vdc {} with status {} to blacklist", vdc.getId(), vdc.getConnectionStatus()); dbClient.addVdcNodesToBlacklist(vdc); } } }
private VirtualDataCenter getLocalVdc() { List<URI> ids = dbClient.queryByType(VirtualDataCenter.class, true); for (URI id : ids) { VirtualDataCenter vdc = dbClient.queryObject(VirtualDataCenter.class, id); if (vdc.getLocal() == true) { return vdc; } } throw new RuntimeException("Failed to find local vdc"); }
private void updateVdcStatusInDB(List<VdcConfig> vdcConfigs) { List<URI> vdcIdIter = new ArrayList<>(); List<URI> vdcIds = dbClient.queryByType(VirtualDataCenter.class, true); for (URI id : vdcIds) { vdcIdIter.add(id); } for (VdcConfig vdcConfig : vdcConfigs) { log.info("current config's id is {}", vdcConfig.getId()); if (vdcIdIter.contains(vdcConfig.getId())) { VirtualDataCenter vdc = dbClient.queryObject(VirtualDataCenter.class, vdcConfig.getId()); vdc.setConnectionStatus( VirtualDataCenter.ConnectionStatus.valueOf(vdcConfig.getConnectionStatus())); dbClient.updateAndReindexObject(vdc); } } }
@PUT @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response syncVdcConfig(VdcConfigSyncParam param) { log.info("Acquired gobal lock, vdc {}...", param.getVirtualDataCenters().size()); VdcConfig.ConfigChangeType type = VdcConfig.ConfigChangeType.valueOf(param.getConfigChangeType()); log.info("Current config change type is {}", type); switch (type) { case DISCONNECT_VDC: String disconntecedvdcId = param.getAssignedVdcId(); try { disconnectVdc(disconntecedvdcId); } catch (Exception e) { throw GeoException.fatals.disconnectRemoteSyncFailed(disconntecedvdcId, e.getMessage()); } break; case RECONNECT_VDC: String reconnectVdcId = param.getAssignedVdcId(); try { VirtualDataCenter localVdc = VdcUtil.getLocalVdc(); // If the local vdc is the one need to be reconnected back, trigger a node repair for // geodb if (localVdc.getId().toString().equals(reconnectVdcId)) { log.info( "Perform sync vdc config operation and node repair for the reconnected vdc {}", reconnectVdcId); VirtualDataCenter reconnVdc = dbClient.queryObject(VirtualDataCenter.class, new URI(reconnectVdcId)); // Update operated local db, make sure all the vdcs in operated vdc'd db have the same // status with others. log.info("Reconnect ops update local db for operatedVdc"); updateVdcStatusInDB(param.getVirtualDataCenters()); log.info("Reconnect ops update local db done"); // Clean blacklist for reconnected vdc log.info("Reconnect ops to clean blacklist for reconnected vdc."); updateBlackListForReconnectedVdc(); log.info("Reconnect ops: new blacklist is {}", dbClient.getBlacklist()); helper.syncVdcConfig(param.getVirtualDataCenters(), null); log.info("Current strategy options is {}", dbClient.getGeoStrategyOptions()); log.info("Current schema version for Geo is {}", dbClient.getGeoSchemaVersions()); geoBackgroundTasks.startGeodbNodeRepair(); } else { reconnectVdc(reconnectVdcId); } } catch (Exception e) { throw GeoException.fatals.reconnectRemoteSyncFailed(reconnectVdcId, e.getMessage()); } break; default: Iterator<URI> srcVdcIdIter = dbClient.queryByType(VirtualDataCenter.class, true).iterator(); String assignedVdcId = param.getAssignedVdcId(); String geoEncryptionKey = param.getGeoEncryptionKey(); // for add-vdc if (assignedVdcId != null && geoEncryptionKey != null) { log.info("This vdc will be added to a geo system."); if (!srcVdcIdIter.hasNext()) { throw GeoException.fatals.connectVDCLocalMultipleVDC(assignedVdcId); } URI srcVdcId = srcVdcIdIter.next(); // Delete the local vdc record VirtualDataCenter existingVdc = dbClient.queryObject(VirtualDataCenter.class, srcVdcId); dbClient.markForDeletion(existingVdc); log.info( "The existing vdc {} has been removed. The current vdc id will be {}.", srcVdcId, assignedVdcId); helper.setGeoEncryptionKey(geoEncryptionKey); log.info("geo encryption key has been updated"); helper.resetStaleLocalObjects(); dbClient.stopClusterGossiping(); } else if (assignedVdcId == null && geoEncryptionKey == null) { log.info("Sync'ing new vdc info to existing geo system."); } else { throw GeoException.fatals.remoteVDCGeoEncryptionMissing(); } helper.syncVdcConfig(param.getVirtualDataCenters(), assignedVdcId); if (isRemoveOp(param)) { log.info("Disable grossip to avoid schema version disagreement errors"); dbClient.stopClusterGossiping(); } break; } return Response.ok().build(); }