use of com.nexblocks.authguard.service.exceptions.IdempotencyException in project AuthGuard by AuthGuard.
the class AccountsRoute method createComplete.
@Override
public void createComplete(final Context context) {
final String idempotentKey = IdempotencyHeader.getKeyOrFail(context);
final CreateCompleteAccountRequestDTO request = completeAccountRequestBodyHandler.getValidated(context);
if (!canPerform(context, request.getAccount())) {
context.status(403).json(new Error("", "An auth client violated its restrictions in the request"));
return;
}
final RequestContextBO requestContext = RequestContextBO.builder().idempotentKey(idempotentKey).source(context.ip()).build();
final AccountBO accountBO = restMapper.toBO(request.getAccount());
final CredentialsBO credentialsBO = restMapper.toBO(request.getCredentials());
final List<UserIdentifierBO> identifiers = credentialsBO.getIdentifiers().stream().map(identifier -> identifier.withDomain(credentialsBO.getDomain())).collect(Collectors.toList());
String accountId;
String credentialsId;
try {
accountId = accountsService.create(accountBO, requestContext).getId();
} catch (final CompletionException e) {
if (e.getCause() instanceof IdempotencyException) {
accountId = ((IdempotencyException) e.getCause()).getIdempotentRecord().getEntityId();
} else {
throw e;
}
}
try {
final CredentialsBO withAdditionalInfo = CredentialsBO.builder().from(credentialsBO).identifiers(identifiers).accountId(accountId).build();
credentialsId = credentialsService.create(withAdditionalInfo, requestContext).getId();
} catch (final CompletionException e) {
if (e.getCause() instanceof IdempotencyException) {
credentialsId = ((IdempotencyException) e.getCause()).getIdempotentRecord().getEntityId();
} else {
throw e;
}
}
final CreateCompleteAccountResponseDTO response = CreateCompleteAccountResponseDTO.builder().accountId(accountId).credentialsId(credentialsId).build();
context.status(201).json(response);
}
use of com.nexblocks.authguard.service.exceptions.IdempotencyException in project AuthGuard by AuthGuard.
the class IdempotencyServiceImpl method performOperation.
@Override
public <T extends Entity> CompletableFuture<T> performOperation(final Supplier<T> operation, final String idempotentKey, final String entityType) {
return findByKeyAndEntityType(idempotentKey, entityType).thenApplyAsync(record -> {
if (record.isPresent()) {
throw new IdempotencyException(record.get());
}
return operation.get();
}).thenApply(result -> {
final IdempotentRecordBO record = IdempotentRecordBO.builder().id(ID.generate()).entityId(result.getId()).entityType(result.getEntityType()).idempotentKey(idempotentKey).build();
// we don't have to wait for this to finish
CompletableFuture.runAsync(() -> create(record));
return result;
});
}
use of com.nexblocks.authguard.service.exceptions.IdempotencyException in project AuthGuard by AuthGuard.
the class AccountsApiTest method createWithCredentialsAccountExists.
@Test
void createWithCredentialsAccountExists() {
final CreateAccountRequestDTO accountRequest = CreateAccountRequestDTO.builder().externalId("external").email(AccountEmailDTO.builder().email("email@server.com").build()).domain("main").build();
final CreateCredentialsRequestDTO credentialsRequest = CreateCredentialsRequestDTO.builder().plainPassword("password").addIdentifiers(UserIdentifierDTO.builder().identifier("username").type(UserIdentifier.Type.USERNAME).build()).build();
final CreateCompleteAccountRequestDTO completeRequest = CreateCompleteAccountRequestDTO.builder().account(accountRequest).credentials(credentialsRequest).build();
final RequestContextBO requestContext = RequestContextBO.builder().idempotentKey(UUID.randomUUID().toString()).build();
final AccountBO accountBO = mapper().toBO(accountRequest);
final AccountBO accountResponse = accountBO.withId(UUID.randomUUID().toString());
final CredentialsBO credentialsBO = mapper().toBO(credentialsRequest).withAccountId(accountResponse.getId());
final CredentialsBO credentialsResponse = credentialsBO.withId(UUID.randomUUID().toString());
Mockito.when(accountsService.create(Mockito.eq(accountBO), Mockito.any())).thenThrow(new CompletionException(new IdempotencyException(IdempotentRecordBO.builder().entityId(accountResponse.getId()).build())));
Mockito.when(credentialsService.create(Mockito.eq(credentialsBO), Mockito.any())).thenReturn(credentialsResponse);
LOG.info("Request {}", accountRequest);
final ValidatableResponse httpResponse = given().body(completeRequest).contentType(ContentType.JSON).header(IdempotencyHeader.HEADER_NAME, requestContext.getIdempotentKey()).post(url("complete")).then().statusCode(201).contentType(ContentType.JSON);
final CreateCompleteAccountResponseDTO response = httpResponse.extract().response().getBody().as(CreateCompleteAccountResponseDTO.class);
assertThat(response.getAccountId()).isEqualTo(accountResponse.getId());
assertThat(response.getCredentialsId()).isEqualTo(credentialsResponse.getId());
}
use of com.nexblocks.authguard.service.exceptions.IdempotencyException in project AuthGuard by AuthGuard.
the class AccountsApiTest method createWithCredentialsAllExist.
@Test
void createWithCredentialsAllExist() {
final CreateAccountRequestDTO accountRequest = CreateAccountRequestDTO.builder().externalId("external").email(AccountEmailDTO.builder().email("email@server.com").build()).domain("main").build();
final CreateCredentialsRequestDTO credentialsRequest = CreateCredentialsRequestDTO.builder().plainPassword("password").addIdentifiers(UserIdentifierDTO.builder().identifier("username").type(UserIdentifier.Type.USERNAME).build()).build();
final CreateCompleteAccountRequestDTO completeRequest = CreateCompleteAccountRequestDTO.builder().account(accountRequest).credentials(credentialsRequest).build();
final RequestContextBO requestContext = RequestContextBO.builder().idempotentKey(UUID.randomUUID().toString()).build();
final AccountBO accountBO = mapper().toBO(accountRequest);
final AccountBO accountResponse = accountBO.withId(UUID.randomUUID().toString());
final CredentialsBO credentialsBO = mapper().toBO(credentialsRequest).withAccountId(accountResponse.getId());
final CredentialsBO credentialsResponse = credentialsBO.withId(UUID.randomUUID().toString());
Mockito.when(accountsService.create(Mockito.eq(accountBO), Mockito.any())).thenThrow(new CompletionException(new IdempotencyException(IdempotentRecordBO.builder().entityId(accountResponse.getId()).build())));
Mockito.when(credentialsService.create(Mockito.eq(credentialsBO), Mockito.any())).thenThrow(new CompletionException(new IdempotencyException(IdempotentRecordBO.builder().entityId(credentialsResponse.getId()).build())));
LOG.info("Request {}", accountRequest);
final ValidatableResponse httpResponse = given().body(completeRequest).contentType(ContentType.JSON).header(IdempotencyHeader.HEADER_NAME, requestContext.getIdempotentKey()).post(url("complete")).then().statusCode(201).contentType(ContentType.JSON);
final CreateCompleteAccountResponseDTO response = httpResponse.extract().response().getBody().as(CreateCompleteAccountResponseDTO.class);
assertThat(response.getAccountId()).isEqualTo(accountResponse.getId());
assertThat(response.getCredentialsId()).isEqualTo(credentialsResponse.getId());
}
use of com.nexblocks.authguard.service.exceptions.IdempotencyException in project AuthGuard by AuthGuard.
the class ExceptionHandlers method completionException.
// NOTE: this will go away when we move to async services
public static void completionException(final CompletionException e, final Context context) {
final Throwable cause = e.getCause();
if (cause == null) {
LOG.error("A CompletionException was thrown without a cause", e);
context.status(500).json(new Error("UNKNOWN", "An unknown error occurred"));
} else if (cause instanceof ServiceAuthorizationException) {
serviceAuthorizationException((ServiceAuthorizationException) cause, context);
} else if (cause instanceof ServiceConflictException) {
serviceConflictException((ServiceConflictException) cause, context);
} else if (cause instanceof ServiceException) {
serviceException((ServiceException) cause, context);
} else if (cause instanceof RuntimeJsonException) {
jsonMappingException((RuntimeJsonException) cause, context);
} else if (cause instanceof RequestValidationException) {
requestValidationException((RequestValidationException) cause, context);
} else if (cause instanceof IdempotencyException) {
idempotencyException((IdempotencyException) cause, context);
} else if (cause instanceof TimeoutException) {
timeoutException((TimeoutException) cause, context);
} else {
LOG.error("An unexpected exception was thrown", cause);
context.status(500).json(new Error("UNKNOWN", "An unknown error occurred"));
}
}
Aggregations