use of com.palantir.atlasdb.timelock.api.Namespace in project atlasdb by palantir.
the class MultiClientConjureTimelockResourceTest method requestHandlesExceptionAndThrowsIfAnyQueryFails.
@Test
public void requestHandlesExceptionAndThrowsIfAnyQueryFails() {
String throwingClient = "alpha";
Set<Namespace> namespaces = ImmutableSet.of(Namespace.of(throwingClient), Namespace.of("beta"));
when(getServiceForClient(throwingClient).leaderTime()).thenThrow(new BlockingTimeoutException(""));
assertThatThrownBy(() -> Futures.getUnchecked(resource.leaderTimes(AUTH_HEADER, namespaces))).hasCauseInstanceOf(Throttle.class);
}
use of com.palantir.atlasdb.timelock.api.Namespace in project atlasdb by palantir.
the class MultiClientConjureTimelockResourceTest method canGetLeaderTimesForMultipleClients.
@Test
public void canGetLeaderTimesForMultipleClients() {
Namespace client1 = Namespace.of("client1");
Namespace client2 = Namespace.of("client2");
Set<Namespace> namespaces = ImmutableSet.of(client1, client2);
LeaderTimes leaderTimesResponse = Futures.getUnchecked(resource.leaderTimes(AUTH_HEADER, namespaces));
Map<Namespace, LeaderTime> leaderTimes = leaderTimesResponse.getLeaderTimes();
// leaderTimes for namespaces are computed by their respective underlying AsyncTimelockService instances
leaderTimes.forEach((namespace, leaderTime) -> {
assertThat(leaderTime.id()).isEqualTo(namespaceToLeaderMap.get(namespace.get()));
});
// there should be as many leaders as there are distinct clients
Set<UUID> leaders = leaderTimes.values().stream().map(LeaderTime::id).map(LeadershipId::id).collect(Collectors.toSet());
assertThat(leaders).hasSameSizeAs(namespaces);
}
use of com.palantir.atlasdb.timelock.api.Namespace in project atlasdb by palantir.
the class AtlasBackupService method completeBackup.
/**
* Completes backup for the given set of atlas services.
* This will store metadata about the completed backup via the BackupPersister.
* <p>
* In order to do this, we must unlock the immutable timestamp for each service. If {@link #prepareBackup(Set)}
* was not called, we will not have a record of the in-progress backup (and will not have been refreshing
* its lock anyway). Thus, we attempt to complete backup only for those atlas services where we have the in-progress
* backup stored.
*
* @return the atlas services whose backups were successfully completed
*/
public Set<AtlasService> completeBackup(Set<AtlasService> atlasServices) {
throwIfClosed(atlasServices);
AtlasServices.throwIfAtlasServicesCollide(atlasServices);
Map<AtlasService, InProgressBackupToken> knownBackups = KeyedStream.of(atlasServices).map((Function<AtlasService, InProgressBackupToken>) inProgressBackups::remove).filter(Objects::nonNull).collectToMap();
Set<InProgressBackupToken> tokens = ImmutableSet.copyOf(knownBackups.values());
if (tokens.isEmpty()) {
log.error("Complete backup called, but no in progress backups were found.", SafeArg.of("atlasServices", atlasServices));
return ImmutableSet.of();
}
lockRefresher.unregisterLocks(tokens);
Set<AtlasService> atlasServicesWithInProgressBackups = knownBackups.keySet();
if (tokens.size() < atlasServices.size()) {
Set<AtlasService> atlasServicesWithNoInProgressBackup = Sets.difference(atlasServices, atlasServicesWithInProgressBackups);
log.error("In progress backups were not found for some atlasServices. We will not complete backup for these.", SafeArg.of("numAtlasServicesWithBackup", tokens.size()), SafeArg.of("numAtlasServicesWithoutBackup", atlasServicesWithNoInProgressBackup.size()), SafeArg.of("atlasServicesWithoutBackup", atlasServicesWithNoInProgressBackup), SafeArg.of("allRequestedAtlasServices", atlasServices));
}
Map<Namespace, AtlasService> namespaceToServices = KeyedStream.of(atlasServices).mapKeys(AtlasService::getNamespace).collectToMap();
CompleteBackupRequest request = CompleteBackupRequest.of(tokens);
CompleteBackupResponse response = atlasBackupClient.completeBackup(authHeader, request);
Map<AtlasService, CompletedBackup> successfulBackups = KeyedStream.of(response.getSuccessfulBackups()).mapKeys(token -> namespaceToServices.get(token.getNamespace())).collectToMap();
Set<AtlasService> successfullyStoredBackups = storeCompletedBackups(successfulBackups);
if (successfullyStoredBackups.size() < atlasServicesWithInProgressBackups.size()) {
Set<AtlasService> failedAtlasServices = Sets.difference(atlasServicesWithInProgressBackups, successfullyStoredBackups);
log.error("Backup did not complete successfully for all atlasServices. Check TimeLock logs to debug.", SafeArg.of("failedAtlasServices", failedAtlasServices), SafeArg.of("successfulAtlasServices", successfullyStoredBackups), SafeArg.of("atlasServicesWithoutBackup", atlasServicesWithInProgressBackups));
}
return successfulBackups.keySet();
}
use of com.palantir.atlasdb.timelock.api.Namespace in project atlasdb by palantir.
the class AtlasRestoreService method prepareRestore.
/**
* Disables TimeLock on all nodes for the given atlasServices.
* This will fail if any atlasService is already disabled, unless it was disabled with the provided backupId.
* AtlasServices for which we don't have a recorded backup will be ignored.
*
* @param restoreRequests the requests to prepare.
* @param backupId a unique identifier for this request (uniquely identifies the backup to which we're restoring)
*
* @return the atlasServices successfully disabled.
*/
public Set<AtlasService> prepareRestore(Set<RestoreRequest> restoreRequests, String backupId) {
validateRestoreRequests(restoreRequests);
Map<RestoreRequest, CompletedBackup> completedBackups = getCompletedBackups(restoreRequests);
Set<AtlasService> atlasServicesToRestore = getAtlasServicesToRestore(completedBackups);
Preconditions.checkArgument(atlasServicesToRestore.size() == completedBackups.size(), "Attempting to restore multiple atlasServices into the same atlasService! " + "This will cause severe data corruption.", SafeArg.of("restoreRequests", restoreRequests));
Set<Namespace> namespacesToRestore = atlasServicesToRestore.stream().map(AtlasService::getNamespace).collect(Collectors.toSet());
DisableNamespacesRequest request = DisableNamespacesRequest.of(namespacesToRestore, backupId);
DisableNamespacesResponse response = timeLockManagementService.disableTimelock(authHeader, request);
return response.accept(new DisableNamespacesResponse.Visitor<>() {
@Override
public Set<AtlasService> visitSuccessful(SuccessfulDisableNamespacesResponse value) {
return atlasServicesToRestore;
}
@Override
public Set<AtlasService> visitUnsuccessful(UnsuccessfulDisableNamespacesResponse value) {
log.error("Failed to disable namespaces prior to restore", SafeArg.of("requests", restoreRequests), SafeArg.of("response", value));
return ImmutableSet.of();
}
@Override
public Set<AtlasService> visitUnknown(String unknownType) {
throw new SafeIllegalStateException("Unknown DisableNamespacesResponse", SafeArg.of("unknownType", unknownType));
}
});
}
use of com.palantir.atlasdb.timelock.api.Namespace in project atlasdb by palantir.
the class AtlasBackupServiceTest method completeBackupReturnsSuccessfulServices.
@Test
public void completeBackupReturnsSuccessfulServices() {
InProgressBackupToken otherInProgress = inProgressBackupToken(OTHER_NAMESPACE);
Set<Namespace> namespaces = ImmutableSet.of(NAMESPACE, OTHER_NAMESPACE);
when(atlasBackupClient.prepareBackup(authHeader, PrepareBackupRequest.of(namespaces))).thenReturn(PrepareBackupResponse.of(ImmutableSet.of(IN_PROGRESS, otherInProgress)));
when(atlasBackupClient.completeBackup(authHeader, CompleteBackupRequest.of(ImmutableSet.of(IN_PROGRESS, otherInProgress)))).thenReturn(CompleteBackupResponse.of(ImmutableSet.of(completedBackup())));
Set<AtlasService> services = ImmutableSet.of(ATLAS_SERVICE, OTHER_ATLAS_SERVICE);
atlasBackupService.prepareBackup(services);
assertThat(atlasBackupService.completeBackup(services)).containsExactly(ATLAS_SERVICE);
}
Aggregations