Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutor.java
  • Loading branch information
andrea-putzu committed Oct 19, 2024
2 parents bbf1e6f + 4ff4ec5 commit 047066d
Show file tree
Hide file tree
Showing 28 changed files with 2,931 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,12 @@ public void onboardingsOrchestrator(
case IMPORT -> workflowExecutor = new WorkflowExecutorImport(objectMapper, optionsRetry);
case USERS -> workflowExecutor = new WorkflowExecutorForUsers(objectMapper, optionsRetry);
case INCREMENT_REGISTRATION_AGGREGATOR -> workflowExecutor = new WorkflowExecutorIncrementRegistrationAggregator(objectMapper, optionsRetry, onboardingMapper);
case USERS_PG -> workflowExecutor = new WorkflowExecutorForUsersPg(objectMapper, optionsRetry);
default -> throw new IllegalArgumentException("Workflow options not found!");
}

Optional<OnboardingStatus> optNextStatus = workflowExecutor.execute(ctx, onboarding);
optNextStatus.ifPresent(onboardingStatus -> {
service.updateOnboardingStatus(onboardingId, onboardingStatus);
workflowExecutor.postProcessor(ctx, onboarding, onboardingStatus);
});
optNextStatus.ifPresent(onboardingStatus -> service.updateOnboardingStatus(onboardingId, onboardingStatus));
} catch (TaskFailedException ex) {
functionContext.getLogger().warning("Error during workflowExecutor execute, msg: " + ex.getMessage());
service.updateOnboardingStatusAndInstanceId(onboardingId, OnboardingStatus.FAILED, ctx.getInstanceId());
Expand Down Expand Up @@ -311,4 +309,10 @@ public void createAggregatesCsv(@DurableActivityTrigger(name = "onboardingString
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, CREATE_AGGREGATES_CSV_ACTIVITY, onboardingWorkflowString));
contractService.uploadAggregatesCsv(readOnboardingWorkflowValue(objectMapper, onboardingWorkflowString));
}

@FunctionName(DELETE_MANAGERS_BY_IC_AND_ADE)
public void deleteOldPgManagers(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(() -> String.format(FORMAT_LOGGER_ONBOARDING_STRING, DELETE_MANAGERS_BY_IC_AND_ADE, onboardingString));
completionService.deleteOldPgManagers(readOnboardingValue(objectMapper, onboardingString));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class ActivityName {
public static final String RESEND_NOTIFICATIONS_ACTIVITY = "ResendNotificationsActivity";
public static final String CREATE_AGGREGATES_CSV_ACTIVITY = "CreateAggregatesCsv";
public static final String EXISTS_DELEGATION_ACTIVITY = "ExistsDelegationActivity";
public static final String DELETE_MANAGERS_BY_IC_AND_ADE = "DeleteManagersByIcAndAde";

private ActivityName() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ public interface CompletionService {

String existsDelegation(OnboardingAggregateOrchestratorInput onboardingAggregateOrchestratorInput);

void deleteOldPgManagers(Onboarding onboarding);

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package it.pagopa.selfcare.onboarding.service;

import com.microsoft.azure.functions.ExecutionContext;
import it.pagopa.selfcare.onboarding.common.InstitutionPaSubunitType;
import it.pagopa.selfcare.onboarding.common.InstitutionType;
import it.pagopa.selfcare.onboarding.common.OnboardingStatus;
import it.pagopa.selfcare.onboarding.common.Origin;
import it.pagopa.selfcare.onboarding.common.*;
import it.pagopa.selfcare.onboarding.dto.OnboardingAggregateOrchestratorInput;
import it.pagopa.selfcare.onboarding.entity.*;
import it.pagopa.selfcare.onboarding.exception.GenericOnboardingException;
Expand All @@ -28,8 +25,16 @@
import org.openapi.quarkus.core_json.api.InstitutionApi;
import org.openapi.quarkus.core_json.model.*;
import org.openapi.quarkus.party_registry_proxy_json.api.AooApi;
import org.openapi.quarkus.party_registry_proxy_json.api.InfocamereApi;
import org.openapi.quarkus.party_registry_proxy_json.api.NationalRegistriesApi;
import org.openapi.quarkus.party_registry_proxy_json.api.UoApi;
import org.openapi.quarkus.party_registry_proxy_json.model.BusinessesResource;
import org.openapi.quarkus.party_registry_proxy_json.model.GetInstitutionsByLegalDto;
import org.openapi.quarkus.party_registry_proxy_json.model.GetInstitutionsByLegalFilterDto;
import org.openapi.quarkus.party_registry_proxy_json.model.LegalVerificationResult;
import org.openapi.quarkus.user_json.model.AddUserRoleDto;
import org.openapi.quarkus.user_json.model.OnboardedProductState;
import org.openapi.quarkus.user_json.model.UserInstitutionResponse;
import org.openapi.quarkus.user_registry_json.api.UserApi;

import java.time.LocalDateTime;
Expand All @@ -43,7 +48,6 @@
import static it.pagopa.selfcare.onboarding.common.OnboardingStatus.REJECTED;
import static it.pagopa.selfcare.onboarding.common.PartyRole.MANAGER;
import static it.pagopa.selfcare.onboarding.common.WorkflowType.CONFIRMATION_AGGREGATE;
import static it.pagopa.selfcare.onboarding.service.OnboardingService.USERS_FIELD_LIST;
import static jakarta.ws.rs.core.Response.Status.Family.SUCCESSFUL;
import static org.openapi.quarkus.core_json.model.DelegationResponse.StatusEnum.ACTIVE;

Expand Down Expand Up @@ -71,6 +75,16 @@ public class CompletionServiceDefault implements CompletionService {
@RestClient
@Inject
org.openapi.quarkus.party_registry_proxy_json.api.InstitutionApi institutionRegistryProxyApi;
@RestClient
@Inject
org.openapi.quarkus.user_json.api.InstitutionApi userInstitutionApi;
@RestClient
@Inject
InfocamereApi infocamereApi;
@RestClient
@Inject
NationalRegistriesApi nationalRegistriesApi;


private final InstitutionMapper institutionMapper;
private final OnboardingRepository onboardingRepository;
Expand All @@ -82,6 +96,7 @@ public class CompletionServiceDefault implements CompletionService {
private final OnboardingMapper onboardingMapper;
private final boolean hasToSendEmail;
private final boolean forceInstitutionCreation;
private static final String USERS_FIELD_LIST = "fiscalCode,familyName,name";

public CompletionServiceDefault(ProductService productService,
NotificationService notificationService,
Expand Down Expand Up @@ -223,8 +238,8 @@ public void rejectOutdatedOnboardings(Onboarding onboarding) {
LocalDateTime now = LocalDateTime.now();
onboardingRepository
.update("status = ?1 and updatedAt = ?2 ", REJECTED, now)
.where("productId = ?1 and institution.origin = ?2 and institution.originId = ?3 and status = PENDING or status = TOBEVALIDATED",
onboarding.getProductId(), onboarding.getInstitution().getOrigin(), onboarding.getInstitution().getOriginId());
.where("productId = ?1 and institution.origin = ?2 and institution.originId = ?3 and _id != ?4 and status = PENDING or status = TOBEVALIDATED",
onboarding.getProductId(), onboarding.getInstitution().getOrigin(), onboarding.getInstitution().getOriginId(), onboarding.getId());
}

@Override
Expand Down Expand Up @@ -376,4 +391,105 @@ private List<String> getDestinationMails(Onboarding onboarding) {
.map(workContract -> workContract.getEmail().getValue())
.collect(Collectors.toList());
}

@Override
public void deleteOldPgManagers(Onboarding onboarding) {
String institutionId = onboarding.getInstitution().getId();
String productId = onboarding.getProductId();
List<String> oldPgManagersUid = retrieveActiveManagersOnInstitution(institutionId, productId);
Origin origin = onboarding.getInstitution().getOrigin();

oldPgManagersUid.stream()
.map(uid -> new PgManagerInfo(uid, retrieveTaxCode(uid)))
.filter(pgManagerInfo -> !isActiveManagerOnRegistries(pgManagerInfo.getTaxCode(), onboarding.getInstitution().getTaxCode(), origin))
.forEach(pgManagerInfo -> deleteManagerFromProduct(pgManagerInfo.getUid(), institutionId, productId));
}

private List<String> retrieveActiveManagersOnInstitution(String institutionId, String productId) {
List<UserInstitutionResponse> activeManagers = userInstitutionApi.institutionsInstitutionIdUserInstitutionsGet(
institutionId,
null,
List.of(productId),
List.of(MANAGER.name()),
List.of(OnboardedProductState.ACTIVE.name()),
null
);

if(Objects.isNull(activeManagers) || CollectionUtils.isEmpty(activeManagers)) {
return Collections.emptyList();
}

return activeManagers.stream()
.map(UserInstitutionResponse::getUserId)
.toList();
}

private String retrieveTaxCode(String uid) {
return userRegistryApi.findByIdUsingGET(USERS_FIELD_LIST, uid).getFiscalCode();
}

private boolean isActiveManagerOnRegistries(String userTaxCode, String institutionTaxCode, Origin origin) {
return switch (origin) {
case INFOCAMERE -> isActiveManagerOnInfocamereRegistry(userTaxCode, institutionTaxCode);
case ADE -> isActiveManagerOnAdeRegistry(userTaxCode, institutionTaxCode);
default -> throw new GenericOnboardingException("Origin not supported");
};
}

private boolean isActiveManagerOnInfocamereRegistry(String userTaxCode, String institutionTaxCode) {
BusinessesResource businessesResource = infocamereApi.institutionsByLegalTaxIdUsingPOST(toGetInstitutionByLegalDto(userTaxCode));
if(Objects.isNull(businessesResource) || CollectionUtils.isEmpty(businessesResource.getBusinesses())) {
return false;
}

return businessesResource.getBusinesses().stream()
.anyMatch(business -> institutionTaxCode.equals(business.getBusinessTaxId()));
}

private GetInstitutionsByLegalDto toGetInstitutionByLegalDto(String userTaxCode) {
GetInstitutionsByLegalDto getInstitutionsByLegalDto = new GetInstitutionsByLegalDto();
GetInstitutionsByLegalFilterDto getInstitutionsByLegalFilterDto = new GetInstitutionsByLegalFilterDto();
getInstitutionsByLegalFilterDto.setLegalTaxId(userTaxCode);
getInstitutionsByLegalDto.setFilter(getInstitutionsByLegalFilterDto);
return getInstitutionsByLegalDto;
}

private boolean isActiveManagerOnAdeRegistry(String userTaxCode, String institutionTaxCode) {
try {
LegalVerificationResult legalVerificationResult = nationalRegistriesApi.verifyLegalUsingGET(userTaxCode, institutionTaxCode);
return legalVerificationResult.getVerificationResult();
} catch (WebApplicationException e) {
// 400 status code means that the user is not a manager of the institution
if (e.getResponse().getStatus() == 400) {
return false;
}
throw new GenericOnboardingException(String.format("Error during verify legal %s", e.getMessage()));
}
}

private void deleteManagerFromProduct(String uid, String institutionId, String productId) {
try (Response response = userApi.usersUserIdInstitutionsInstitutionIdProductsProductIdDelete(institutionId, productId, uid)) {
if (!SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
throw new GenericOnboardingException(String.format("Failed to delete user %s from product %s in institution %s", uid, productId, institutionId));
}
}
}

private static class PgManagerInfo {
private final String uid;
private final String taxCode;

public PgManagerInfo(String uid, String taxCode) {
this.uid = uid;
this.taxCode = taxCode;
}

public String getUid() {
return uid;
}

public String getTaxCode() {
return taxCode;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ public class PdfMapper {
public static final String INSTITUTION_REGISTER_LABEL_VALUE = "institutionRegisterLabelValue";
public static final String CSV_AGGREGATES_LABEL_VALUE = "aggregatesCsvLink";
public static final String ORIGIN_ID_LABEL = "<li class=\"c19 c39 li-bullet-0\"><span class=\"c1\">codice di iscrizione all&rsquo;Indice delle Pubbliche Amministrazioni e dei gestori di pubblici servizi (I.P.A.) <span class=\"c3\">${originId}</span> </span><span class=\"c1\"></span></li>";
public static final String CSV_AGGREGATES_LABEL = "&emsp;- <span class=\"c3\" style=\"color:blue\"><a class=\"c15\" href=\"%s\"><u>Dati di Enti Aggregati</u></a></span>";
public static final String CSV_AGGREGATES_LABEL = "&emsp;- <span class=\"c3\" style=\"color:blue\"><a class=\"c15\" href=\"%s\"><u>%s</u></a></span>";
public static final String CSV_AGGREGATES_TEXT_PAGOPA = "Dati di Enti Aggregati";
public static final String CSV_AGGREGATES_TEXT_IO = "Dati degli Enti Aggregati_IO";
public static final String INSTITUTION_RECIPIENT_CODE = "institutionRecipientCode";

private PdfMapper() {
Expand Down Expand Up @@ -214,7 +216,8 @@ private static void addAggregatesCsvLink(Onboarding onboarding, Map<String, Obje

if (Boolean.TRUE.equals(onboarding.getIsAggregator())) {
String url = baseUrl + onboarding.getId() + products + onboarding.getProductId() + aggregates;
csvLink = String.format(CSV_AGGREGATES_LABEL, url);
String csvText = PROD_IO.getValue().equals(onboarding.getProductId()) ? CSV_AGGREGATES_TEXT_IO : CSV_AGGREGATES_TEXT_PAGOPA;
csvLink = String.format(CSV_AGGREGATES_LABEL, url, csvText);
}

map.put(CSV_AGGREGATES_LABEL_VALUE, csvLink);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.microsoft.durabletask.TaskOptions;
import com.microsoft.durabletask.TaskOrchestrationContext;
import it.pagopa.selfcare.onboarding.common.OnboardingStatus;
import it.pagopa.selfcare.onboarding.common.WorkflowType;
import it.pagopa.selfcare.onboarding.dto.OnboardingAggregateOrchestratorInput;
import it.pagopa.selfcare.onboarding.entity.AggregateInstitution;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
Expand Down Expand Up @@ -53,6 +54,7 @@ default String createInstitutionAndOnboarding(TaskOrchestrationContext ctx, Onbo
if (!onboarding.getWorkflowType().equals(WorkflowType.IMPORT)) {
ctx.callActivity(STORE_ONBOARDING_ACTIVATEDAT, onboardingWithInstitutionIdString, optionsRetry(), String.class).await();
}
ctx.callActivity(REJECT_OUTDATED_ONBOARDINGS, onboardingString, optionsRetry(), String.class).await();

createTestEnvironmentsOnboarding(ctx, onboarding, onboardingWithInstitutionIdString);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package it.pagopa.selfcare.onboarding.workflow;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.durabletask.TaskOptions;
import com.microsoft.durabletask.TaskOrchestrationContext;
import it.pagopa.selfcare.onboarding.common.OnboardingStatus;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflow;
import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowUser;

import java.util.Optional;

import static it.pagopa.selfcare.onboarding.common.OnboardingStatus.COMPLETED;
import static it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowType.USER;
import static it.pagopa.selfcare.onboarding.functions.utils.ActivityName.*;
import static it.pagopa.selfcare.onboarding.utils.Utils.getOnboardingString;

public record WorkflowExecutorForUsersPg(ObjectMapper objectMapper, TaskOptions optionsRetry) implements WorkflowExecutor {
@Override
public Optional<OnboardingStatus> executeRequestState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) {
return Optional.empty();
}

@Override
public Optional<OnboardingStatus> executeToBeValidatedState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) {
return Optional.empty();
}

@Override
public Optional<OnboardingStatus> executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) {
final String onboardingString = getOnboardingString(objectMapper(), onboardingWorkflow.getOnboarding());
ctx.callActivity(DELETE_MANAGERS_BY_IC_AND_ADE, onboardingString, optionsRetry(), String.class).await();
ctx.callActivity(CREATE_USERS_ACTIVITY, onboardingString, optionsRetry(), String.class).await();
ctx.callActivity(STORE_ONBOARDING_ACTIVATEDAT, onboardingString, optionsRetry(), String.class).await();
return Optional.of(COMPLETED);
}

@Override
public OnboardingWorkflow createOnboardingWorkflow(Onboarding onboarding) {
return new OnboardingWorkflowUser(onboarding, USER.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,24 @@ quarkus.openapi-generator.codegen.spec.user_json.additional-api-type-annotations
quarkus.rest-client."org.openapi.quarkus.user_json.api.UserApi".url=${MS_USER_URL:http://localhost:8081}
quarkus.rest-client."org.openapi.quarkus.user_json.api.UserApi".read-timeout=60000
quarkus.rest-client."org.openapi.quarkus.user_json.api.UserApi".connection-pool-size=1024
quarkus.rest-client."org.openapi.quarkus.user_json.api.InstitutionApi".url=${MS_USER_URL:http://localhost:8081}
quarkus.rest-client."org.openapi.quarkus.user_json.api.InstitutionApi".read-timeout=60000
quarkus.rest-client."org.openapi.quarkus.user_json.api.InstitutionApi".connection-pool-size=1024

quarkus.openapi-generator.codegen.spec.party_registry_proxy_json.enable-security-generation=false
quarkus.openapi-generator.codegen.spec.party_registry_proxy_json.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders(it.pagopa.selfcare.onboarding.client.auth.AuthenticationPropagationHeadersFactory.class)
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.UoApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.AooApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.InstitutionApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.GeographicTaxonomiesApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.InfocamereApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.NationalRegistriesApi".url=${MS_PARTY_REGISTRY_URL:http://localhost:8080}
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.UoApi".read-timeout=30000
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.AooApi".read-timeout=30000
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.InstitutionApi".read-timeout=30000
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.GeographicTaxonomiesApi".read-timeout=30000
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.InfocamereApi".read-timeout=30000
quarkus.rest-client."org.openapi.quarkus.party_registry_proxy_json.api.NationalRegistriesApi".read-timeout=30000


## AZURE STORAGE ##
Expand Down
Loading

0 comments on commit 047066d

Please sign in to comment.