Skip to content

Commit

Permalink
[SELC-3996] feat: PNPG onboarding use case (#129)
Browse files Browse the repository at this point in the history
* request dto

* pg completion endpoint

* unit test

* persist onboarding and then start orchestration

* TrustedListsCertificateSource based on signature enabled

* unit test
  • Loading branch information
manuraf authored Jan 29, 2024
1 parent 9b2a8f9 commit 28d691b
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import eu.europa.esig.dss.tsl.job.TLValidationJob;
import eu.europa.esig.dss.tsl.source.LOTLSource;
import eu.europa.esig.dss.tsl.sync.AcceptAllStrategy;
import io.quarkus.arc.profile.IfBuildProfile;
import io.quarkus.arc.profile.UnlessBuildProfile;
import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.runtime.Startup;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
Expand All @@ -45,7 +44,7 @@ public class TrustedListsCertificateSourceConfig {

@Startup
@ApplicationScoped
@UnlessBuildProfile("test")
@IfBuildProperty(name = "onboarding-ms.signature.verify-enabled", stringValue = "true", enableIfMissing = false)
public TrustedListsCertificateSource generateTrustedListsCertificateSource() {

TrustedListsCertificateSource trustedListsCertificateSource = new TrustedListsCertificateSource();
Expand All @@ -67,7 +66,7 @@ public TrustedListsCertificateSource generateTrustedListsCertificateSource() {

/* It is used for unit test, it does not perform onlineRefresh */
@ApplicationScoped
@IfBuildProfile("test")
@IfBuildProperty(name = "onboarding-ms.signature.verify-enabled", stringValue = "false", enableIfMissing = true)
public TrustedListsCertificateSource generateTrustedListsCertificateSourceTest() {

TrustedListsCertificateSource trustedListsCertificateSource = new TrustedListsCertificateSource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.smallrye.mutiny.Uni;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingDefaultRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingPaRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingPgRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingPspRequest;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGetResponse;
Expand Down Expand Up @@ -113,18 +114,15 @@ public Uni<OnboardingResponse> onboardingPspCompletion(@Valid OnboardingPspReque
}


/**
* Onboarding pg may be excluded from the async onboarding flow
* Institutions may be saved without passing from onboarding
*
@POST
@Path("/pg")
@Path("/pg/completion")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Uni<OnboardingResponse> onboardingPg(@Valid OnboardingPgRequest onboardingRequest) {
return onboardingService.onboarding(onboardingMapper.toEntity(onboardingRequest))
.map(onboardingMapper::toResponse);
}*/
public Uni<OnboardingResponse> onboardingPgCompletion(@Valid OnboardingPgRequest onboardingRequest, @Context SecurityContext ctx) {
return readUserIdFromToken(ctx)
.onItem().invoke(onboardingRequest::setUserRequestUid)
.onItem().transformToUni(ignore -> onboardingService.onboardingCompletion(onboardingMapper.toEntity(onboardingRequest), onboardingRequest.getUsers()));
}


private Uni<String> readUserIdFromToken(SecurityContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package it.pagopa.selfcare.onboarding.controller.request;

import it.pagopa.selfcare.onboarding.common.Origin;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
Expand All @@ -21,9 +22,10 @@ public class OnboardingPgRequest {
private String taxCode;
private String businessName;
@NotNull
private boolean certified;
private Origin origin;
@NotBlank
@Email
private String digitalAddress;
private String userRequestUid;

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package it.pagopa.selfcare.onboarding.mapper;

import it.pagopa.selfcare.onboarding.controller.request.OnboardingDefaultRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingPaRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingPspRequest;
import it.pagopa.selfcare.onboarding.controller.request.OnboardingSaRequest;
import it.pagopa.selfcare.onboarding.controller.request.*;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
import org.bson.types.ObjectId;
import org.mapstruct.*;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

@Mapper(componentModel = "cdi")
public interface OnboardingMapper {
Expand All @@ -18,10 +17,11 @@ public interface OnboardingMapper {
Onboarding toEntity(OnboardingDefaultRequest request);
Onboarding toEntity(OnboardingSaRequest request);

//@Mapping(source = "taxCode", target = "institution.taxCode")
//@Mapping(source = "businessName", target = "institution.description")
//@Mapping(source = "digitalAddress", target = "institution.digitalAddress")
//Onboarding toEntity(OnboardingPgRequest request);
@Mapping(source = "taxCode", target = "institution.taxCode")
@Mapping(source = "businessName", target = "institution.description")
@Mapping(source = "digitalAddress", target = "institution.digitalAddress")
@Mapping(source = "origin", target = "institution.origin")
Onboarding toEntity(OnboardingPgRequest request);

OnboardingResponse toResponse(Onboarding onboarding);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public class OnboardingServiceDefault implements OnboardingService {

@Override
public Uni<OnboardingResponse> onboarding(Onboarding onboarding, List<UserRequest> userRequests) {
onboarding.setExpiringDate(OffsetDateTime.now().plusDays(onboardingExpireDate).toLocalDateTime());
onboarding.setWorkflowType(getWorkflowType(onboarding));
onboarding.setStatus(OnboardingStatus.REQUEST);

Expand All @@ -154,18 +155,19 @@ public Uni<OnboardingResponse> onboardingCompletion(Onboarding onboarding, List<
* If is null the timeout is default 1 sec and the response is delivered asynchronously
*/
private Uni<OnboardingResponse> fillUsersAndOnboarding(Onboarding onboarding, List<UserRequest> userRequests, String timeout) {
onboarding.setExpiringDate(OffsetDateTime.now().plusDays(onboardingExpireDate).toLocalDateTime());
onboarding.setCreatedAt(LocalDateTime.now());

return Panache.withTransaction(() -> Onboarding.persist(onboarding).replaceWith(onboarding)
.onItem().transformToUni(onboardingPersisted -> checkRoleAndRetrieveUsers(userRequests, onboardingPersisted.id.toHexString())
.onItem().invoke(onboardingPersisted::setUsers).replaceWith(onboardingPersisted))
.onItem().transformToUni(this::checkProductAndReturnOnboarding)
return validationProductDataAndOnboardingExists(onboarding, userRequests)
.onItem().transformToUni(OnboardingUtils::customValidationOnboardingData)
.onItem().transformToUni(this::addParentDescriptionForAooOrUo)
/* I have to retrieve onboarding id for saving reference to pdv */
.onItem().transformToUni(current -> Panache.withTransaction(() -> Onboarding.persist(onboarding).replaceWith(onboarding)
.onItem().transformToUni(onboardingPersisted -> validationRoleAndRetrieveUsers(userRequests, onboardingPersisted.id.toHexString())
.onItem().invoke(onboardingPersisted::setUsers).replaceWith(onboardingPersisted))))
/* Update onboarding data with users and start orchestration */
.onItem().transformToUni(currentOnboarding -> persistAndStartOrchestrationOnboarding(currentOnboarding,
orchestrationApi.apiStartOnboardingOrchestrationGet(currentOnboarding.getId().toHexString(), timeout)))
.onItem().transform(onboardingMapper::toResponse));
.onItem().transform(onboardingMapper::toResponse);
}


Expand Down Expand Up @@ -251,8 +253,9 @@ private Uni<Product> product(String productId) {
.runSubscriptionOn(Infrastructure.getDefaultWorkerPool());
}

public Uni<Onboarding> checkProductAndReturnOnboarding(Onboarding onboarding) {
public Uni<Onboarding> validationProductDataAndOnboardingExists(Onboarding onboarding, List<UserRequest> userRequests) {

/* retrieve product, if is not valid will throw OnboardingNotAllowedException */
return product(onboarding.getProductId())
.onFailure().transform(ex -> new OnboardingNotAllowedException(String.format(UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED,
onboarding.getInstitution().getTaxCode(),
Expand All @@ -266,7 +269,7 @@ public Uni<Onboarding> checkProductAndReturnOnboarding(Onboarding onboarding) {
onboarding.getProductId()), DEFAULT_ERROR.getCode()));
}

validateProductRole(onboarding.getUsers(), Objects.nonNull(product.getParent())
validateProductRole(userRequests, Objects.nonNull(product.getParent())
? product.getParent().getRoleMappings()
: product.getRoleMappings());

Expand Down Expand Up @@ -306,7 +309,7 @@ private Uni<Boolean> checkIfAlreadyOnboardingAndValidateAllowedMap(String produc
.replaceWith(Boolean.TRUE);
}

private void validateProductRole(List<User> users, Map<PartyRole, ProductRoleInfo> roleMappings) {
private void validateProductRole(List<UserRequest> users, Map<PartyRole, ProductRoleInfo> roleMappings) {
try {
if(Objects.isNull(roleMappings) || roleMappings.isEmpty())
throw new IllegalArgumentException("Role mappings is required");
Expand All @@ -324,7 +327,7 @@ private void validateProductRole(List<User> users, Map<PartyRole, ProductRoleInf
}
}

public Uni<List<User>> checkRoleAndRetrieveUsers(List<UserRequest> users, String onboardingId) {
public Uni<List<User>> validationRoleAndRetrieveUsers(List<UserRequest> users, String onboardingId) {

List<PartyRole> validRoles = List.of(PartyRole.MANAGER, PartyRole.DELEGATE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import io.restassured.http.ContentType;
import io.smallrye.mutiny.Uni;
import it.pagopa.selfcare.onboarding.common.InstitutionType;
import it.pagopa.selfcare.onboarding.common.Origin;
import it.pagopa.selfcare.onboarding.controller.request.*;
import it.pagopa.selfcare.onboarding.controller.response.InstitutionResponse;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGetResponse;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
import it.pagopa.selfcare.onboarding.exception.InvalidRequestException;
import it.pagopa.selfcare.onboarding.service.OnboardingService;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -418,6 +420,33 @@ void onboardingCompletePsp() {
.onboardingCompletion(any(), any());
}

@Test
@TestSecurity(user = "userJwt")
void onboardingCompletePg() {

OnboardingPgRequest onboardingPgRequest = new OnboardingPgRequest();
onboardingPgRequest.setProductId("productId");
onboardingPgRequest.setUsers(List.of(userDTO));
onboardingPgRequest.setTaxCode("taxCode");
onboardingPgRequest.setDigitalAddress("[email protected]");
onboardingPgRequest.setOrigin(Origin.INFOCAMERE);

Mockito.when(onboardingService.onboardingCompletion(any(), any()))
.thenReturn(Uni.createFrom().item(new OnboardingResponse()));

given()
.when()
.body(onboardingPgRequest)
.contentType(ContentType.JSON)
.post("/pg/completion")
.then()
.statusCode(200);

ArgumentCaptor<Onboarding> captor = ArgumentCaptor.forClass(Onboarding.class);
Mockito.verify(onboardingService, times(1))
.onboardingCompletion(captor.capture(), any());
}

private static Map<String, String> getStringStringMap() {
Map<String, String> queryParameterMap = new HashMap<>();
queryParameterMap.put("productId","prod-io");
Expand Down
Loading

0 comments on commit 28d691b

Please sign in to comment.