Search in sources :

Example 1 with IdempotencyException

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);
}
Also used : Inject(com.google.inject.Inject) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) CredentialsService(com.nexblocks.authguard.service.CredentialsService) com.nexblocks.authguard.api.dto.requests(com.nexblocks.authguard.api.dto.requests) AccountsService(com.nexblocks.authguard.service.AccountsService) RestMapper(com.nexblocks.authguard.rest.mappers.RestMapper) Context(io.javalin.http.Context) ActorDomainVerifier(com.nexblocks.authguard.rest.access.ActorDomainVerifier) AccountsApi(com.nexblocks.authguard.api.routes.AccountsApi) IdempotencyHeader(com.nexblocks.authguard.rest.util.IdempotencyHeader) ApplicationsService(com.nexblocks.authguard.service.ApplicationsService) AccountLocksService(com.nexblocks.authguard.service.AccountLocksService) AccountDTO(com.nexblocks.authguard.api.dto.entities.AccountDTO) AppDTO(com.nexblocks.authguard.api.dto.entities.AppDTO) ErrorCode(com.nexblocks.authguard.service.exceptions.codes.ErrorCode) Collection(java.util.Collection) CompletionException(java.util.concurrent.CompletionException) com.nexblocks.authguard.service.model(com.nexblocks.authguard.service.model) AuthGuardRoles(com.nexblocks.authguard.api.access.AuthGuardRoles) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) List(java.util.List) BodyHandler(com.nexblocks.authguard.rest.util.BodyHandler) Error(com.nexblocks.authguard.api.dto.entities.Error) AccountLockDTO(com.nexblocks.authguard.api.dto.entities.AccountLockDTO) Optional(java.util.Optional) CompletionException(java.util.concurrent.CompletionException) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) Error(com.nexblocks.authguard.api.dto.entities.Error)

Example 2 with IdempotencyException

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;
    });
}
Also used : ServiceMapper(com.nexblocks.authguard.service.mappers.ServiceMapper) IdempotencyService(com.nexblocks.authguard.service.IdempotencyService) Entity(com.nexblocks.authguard.service.model.Entity) Inject(com.google.inject.Inject) IdempotentRecordBO(com.nexblocks.authguard.service.model.IdempotentRecordBO) Optional(java.util.Optional) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) CompletableFuture(java.util.concurrent.CompletableFuture) IdempotentRecordsRepository(com.nexblocks.authguard.dal.persistence.IdempotentRecordsRepository) Supplier(java.util.function.Supplier) ID(com.nexblocks.authguard.service.util.ID) IdempotentRecordBO(com.nexblocks.authguard.service.model.IdempotentRecordBO) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException)

Example 3 with IdempotencyException

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());
}
Also used : AccountBO(com.nexblocks.authguard.service.model.AccountBO) CredentialsBO(com.nexblocks.authguard.service.model.CredentialsBO) ValidatableResponse(io.restassured.response.ValidatableResponse) RequestContextBO(com.nexblocks.authguard.service.model.RequestContextBO) CreateAccountRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateAccountRequestDTO) CompletionException(java.util.concurrent.CompletionException) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) CreateCompleteAccountResponseDTO(com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountResponseDTO) CreateCompleteAccountRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountRequestDTO) CreateCredentialsRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateCredentialsRequestDTO) Test(org.junit.jupiter.api.Test)

Example 4 with IdempotencyException

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());
}
Also used : AccountBO(com.nexblocks.authguard.service.model.AccountBO) CredentialsBO(com.nexblocks.authguard.service.model.CredentialsBO) ValidatableResponse(io.restassured.response.ValidatableResponse) RequestContextBO(com.nexblocks.authguard.service.model.RequestContextBO) CreateAccountRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateAccountRequestDTO) CompletionException(java.util.concurrent.CompletionException) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) CreateCompleteAccountResponseDTO(com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountResponseDTO) CreateCompleteAccountRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountRequestDTO) CreateCredentialsRequestDTO(com.nexblocks.authguard.api.dto.requests.CreateCredentialsRequestDTO) Test(org.junit.jupiter.api.Test)

Example 5 with IdempotencyException

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"));
    }
}
Also used : ServiceConflictException(com.nexblocks.authguard.service.exceptions.ServiceConflictException) ServiceException(com.nexblocks.authguard.service.exceptions.ServiceException) IdempotencyException(com.nexblocks.authguard.service.exceptions.IdempotencyException) ServiceAuthorizationException(com.nexblocks.authguard.service.exceptions.ServiceAuthorizationException) Error(com.nexblocks.authguard.api.dto.entities.Error) RequestValidationError(com.nexblocks.authguard.api.dto.entities.RequestValidationError) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

IdempotencyException (com.nexblocks.authguard.service.exceptions.IdempotencyException)5 CompletionException (java.util.concurrent.CompletionException)3 Inject (com.google.inject.Inject)2 Error (com.nexblocks.authguard.api.dto.entities.Error)2 CreateAccountRequestDTO (com.nexblocks.authguard.api.dto.requests.CreateAccountRequestDTO)2 CreateCompleteAccountRequestDTO (com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountRequestDTO)2 CreateCompleteAccountResponseDTO (com.nexblocks.authguard.api.dto.requests.CreateCompleteAccountResponseDTO)2 CreateCredentialsRequestDTO (com.nexblocks.authguard.api.dto.requests.CreateCredentialsRequestDTO)2 AccountBO (com.nexblocks.authguard.service.model.AccountBO)2 CredentialsBO (com.nexblocks.authguard.service.model.CredentialsBO)2 RequestContextBO (com.nexblocks.authguard.service.model.RequestContextBO)2 ValidatableResponse (io.restassured.response.ValidatableResponse)2 Optional (java.util.Optional)2 AuthGuardRoles (com.nexblocks.authguard.api.access.AuthGuardRoles)1 AccountDTO (com.nexblocks.authguard.api.dto.entities.AccountDTO)1 AccountLockDTO (com.nexblocks.authguard.api.dto.entities.AccountLockDTO)1 AppDTO (com.nexblocks.authguard.api.dto.entities.AppDTO)1 RequestValidationError (com.nexblocks.authguard.api.dto.entities.RequestValidationError)1 com.nexblocks.authguard.api.dto.requests (com.nexblocks.authguard.api.dto.requests)1 AccountsApi (com.nexblocks.authguard.api.routes.AccountsApi)1