use of org.apache.curator.framework.recipes.barriers.DistributedBarrier in project coprhd-controller by CoprHD.
the class DisasterRecoveryService method doSwitchover.
/**
* Do Site Switchover
* This API will do switchover to target new active site according passed in site UUID. After failover, old active site will
* work as normal standby site and target site will be promoted to active. All site will update properties to trigger reconfig.
*
* @param uuid target new active site UUID
* @brief Do site switchover
* @return return accepted response if operation is successful
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{uuid}/switchover")
@CheckPermission(roles = { Role.SECURITY_ADMIN, Role.RESTRICTED_SECURITY_ADMIN }, blockProxies = true)
public Response doSwitchover(@PathParam("uuid") String uuid) {
log.info("Begin to switchover for standby UUID {}", uuid);
precheckForSwitchoverForActiveSite(uuid);
List<Site> allStandbySites = drUtil.listStandbySites();
for (Site site : allStandbySites) {
if (!site.getUuid().equals(uuid) && site.getState() == SiteState.STANDBY_PAUSED) {
try (InternalSiteServiceClient client = new InternalSiteServiceClient(site)) {
client.setCoordinatorClient(coordinator);
client.setKeyGenerator(apiSignatureGenerator);
client.switchoverPrecheck();
}
}
}
String oldActiveUUID = drUtil.getActiveSite().getUuid();
InterProcessLock lock = drUtil.getDROperationLock();
Site newActiveSite = null;
Site oldActiveSite = null;
try {
newActiveSite = drUtil.getSiteFromLocalVdc(uuid);
// Set old active site's state, short id and key
oldActiveSite = drUtil.getSiteFromLocalVdc(oldActiveUUID);
if (StringUtils.isEmpty(oldActiveSite.getSiteShortId())) {
oldActiveSite.setSiteShortId(newActiveSite.getVdcShortId());
}
coordinator.startTransaction();
oldActiveSite.setState(SiteState.ACTIVE_SWITCHING_OVER);
coordinator.persistServiceConfiguration(oldActiveSite.toConfiguration());
// this barrier is set when begin switchover and will be removed by new active site. Old active site will wait and reboot after
// barrier is removed
DistributedBarrier restartBarrier = coordinator.getDistributedBarrier(String.format("%s/%s/%s", ZkPath.SITES, oldActiveSite.getUuid(), Constants.SWITCHOVER_BARRIER_RESTART));
restartBarrier.setBarrier();
drUtil.recordDrOperationStatus(oldActiveSite.getUuid(), InterState.SWITCHINGOVER_ACTIVE);
// trigger reconfig
// a version for all sites.
long vdcConfigVersion = DrUtil.newVdcConfigVersion();
for (Site eachSite : drUtil.listSites()) {
if (!eachSite.getUuid().equals(uuid) && eachSite.getState() == SiteState.STANDBY_PAUSED) {
try (InternalSiteServiceClient client = new InternalSiteServiceClient(eachSite)) {
client.setCoordinatorClient(coordinator);
client.setKeyGenerator(apiSignatureGenerator);
client.switchover(newActiveSite.getUuid(), vdcConfigVersion);
}
} else {
drUtil.updateVdcTargetVersion(eachSite.getUuid(), SiteInfo.DR_OP_SWITCHOVER, vdcConfigVersion, oldActiveSite.getUuid(), newActiveSite.getUuid());
}
}
coordinator.commitTransaction();
auditDisasterRecoveryOps(OperationTypeEnum.SWITCHOVER, AuditLogManager.AUDITLOG_SUCCESS, AuditLogManager.AUDITOP_BEGIN, oldActiveSite.toBriefString(), newActiveSite.toBriefString());
return Response.status(Response.Status.ACCEPTED).build();
} catch (Exception e) {
log.error(String.format("Error happened when switchover from site %s to site %s", oldActiveUUID, uuid), e);
coordinator.discardTransaction();
auditDisasterRecoveryOps(OperationTypeEnum.SWITCHOVER, AuditLogManager.AUDITLOG_FAILURE, null, newActiveSite.getName(), newActiveSite.getVipEndPoint());
throw APIException.internalServerErrors.switchoverFailed(oldActiveSite.getName(), newActiveSite.getName(), e.getMessage());
} finally {
try {
lock.release();
} catch (Exception ignore) {
log.error(String.format("Lock release failed when switchover from %s to %s", oldActiveUUID, uuid));
}
}
}
Aggregations