Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/openapi/api-internal-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ components:
type: string
message:
type: string
additionalDetails:
type: object
additionalProperties: true
flowThrow:
type: string
enum:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public Mono<Void> handleRetryError(PaperTrackingsErrors paperTrackingsErrors) {
}

public Mono<Void> handleError(PaperTrackingsErrors paperTrackingsErrors, Long messageReceiveCount, PnPaperTrackerValidationException ex) {
boolean isStatusCodeError = ErrorCategory.STATUS_CODE_ERROR.equals(paperTrackingsErrors.getErrorCategory());
boolean isStatusCodeError = Objects.nonNull(paperTrackingsErrors.getDetails()) && ErrorCause.VALUES_NOT_FOUND.equals(paperTrackingsErrors.getDetails().getCause());

if (isStatusCodeError) {
if (messageReceiveCount < 5) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.RequiredArgsConstructor;

import java.time.Instant;
import java.util.Map;

@RequiredArgsConstructor(access = AccessLevel.NONE)
public class PaperTrackingsErrorsMapper {
Expand All @@ -15,6 +16,7 @@ public static PaperTrackingsErrors buildPaperTrackingsError(PaperTrackings paper
ErrorCategory errorCategory,
ErrorCause errorCause,
String errorMessage,
Map<String, Object> additionalDetails,
FlowThrow flowThrow,
ErrorType errorType,
String eventIdThrow) {
Expand All @@ -25,6 +27,7 @@ public static PaperTrackingsErrors buildPaperTrackingsError(PaperTrackings paper
.details(ErrorDetails.builder()
.cause(errorCause)
.message(errorMessage)
.additionalDetails(additionalDetails)
.build())
.flowThrow(flowThrow)
.eventThrow(statusCode)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package it.pagopa.pn.papertracker.middleware.dao.dynamo;

import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
import software.amazon.awssdk.enhanced.dynamodb.EnhancedType;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

public class AdditionalDetailsConverter implements AttributeConverter<Map<String, Object>> {

@Override
public AttributeValue transformFrom(Map<String, Object> value) {
if (Objects.isNull(value)) {
return AttributeValue.builder().nul(true).build();
}
return AttributeValue.builder().m(value.entrySet().stream()
.collect(java.util.stream.Collectors.toMap(
Map.Entry::getKey,
e -> toAttr(e.getValue())
))).build();
}

@Override
public Map<String, Object> transformTo(AttributeValue attributeValue) {
if (Boolean.TRUE.equals(attributeValue.nul())) {
return null;
}
if (Objects.isNull(attributeValue.m())) {
return Map.of();
}
return attributeValue.m().entrySet().stream().collect(java.util.stream.Collectors.toMap(
Map.Entry::getKey,
e -> Optional.ofNullable(fromAttr(e.getValue())).orElse("")
));
}

@Override
public AttributeValueType attributeValueType() {
return AttributeValueType.M;
}

@Override
public EnhancedType<Map<String, Object>> type() {
return EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(Object.class));
}

/* -------- conversioni -------- */

private AttributeValue toAttr(Object v) {
return switch (v) {
case String s -> AttributeValue.builder().s(s).build();
case Number n -> AttributeValue.builder().n(n.toString()).build();
case Boolean b -> AttributeValue.builder().bool(b).build();
case Map<?, ?> m -> AttributeValue.builder().m(m.entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey().toString(), e -> toAttr(e.getValue()))))
.build();
case List<?> l -> AttributeValue.builder().l(l.stream().map(this::toAttr).toList()).build();
case null -> AttributeValue.builder().nul(true).build();
default -> throw new IllegalArgumentException("Unsupported type in additionalDetails: " + v.getClass());
};
}

private Object fromAttr(AttributeValue attributeValue) {
if (Objects.nonNull(attributeValue.nul()) && attributeValue.nul()) return null;
if (Objects.nonNull(attributeValue.s())) return attributeValue.s();
if (Objects.nonNull(attributeValue.n())) return attributeValue.n();
if (Objects.nonNull(attributeValue.bool())) return attributeValue.bool();
if (Objects.nonNull((attributeValue.m()))) {
return attributeValue.m().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> Optional.ofNullable(fromAttr(e.getValue())).orElse("")));
}
if (Objects.nonNull(attributeValue.l())) {
return attributeValue.l().stream()
.map(this::fromAttr)
.toList();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public enum ErrorCategory {
NOT_RETRYABLE_EVENT_ERROR("Evento not retryable ricevuto"),
RENDICONTAZIONE_SCARTATA("Rendicontazione scartata"),
DATE_ERROR("Errore nella validazione delle date della sequenza."),
STATUS_CODE_ERROR("Errore nella validazione della presenza degli elementi della sequenza."),
LAST_EVENT_EXTRACTION_ERROR("Errore nell'estrazione della sequenza dall'ultimo evento."),
REGISTERED_LETTER_CODE_ERROR("Errore nella validazione del registered letter code"),
REGISTERED_LETTER_CODE_NOT_FOUND("Registered letter code non trovato"),
Expand All @@ -21,7 +20,12 @@ public enum ErrorCategory {
DEMAT_ATTACHMENT_NUMBER_ERROR("Errore nel numero di attachment trovati per demat"),
DUPLICATED_EVENT("Errore nella validazione della presenza di eventi duplicati"),
INVALID_STATE_FOR_STOCK_890("Stato non valido per giacenza 890"),
INCONSISTENT_STATE("Tracking completato o in attesa validazione OCR");
INCONSISTENT_STATE("Tracking completato o in attesa validazione OCR"),
/**
* @deprecated Non utilizzare. Campo mantenuto solo per retrocompatibilità.
*/
@Deprecated
STATUS_CODE_ERROR("Errore nella validazione della presenza degli elementi della sequenza.");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ public enum ErrorCause {
OCR_KO( "Errore nella validazione dell'OCR"),
OCR_UNSUPPORTED_PRODUCT("Prodotto non supportato per la validazione OCR"),
STOCK_890_REFINEMENT_MISSING("Spedizione 890 non perfezionata"),
STOCK_890_REFINEMENT_ERROR("Errore nel perfezionamento della spedizione 890"),;
STOCK_890_REFINEMENT_ERROR("Errore nel perfezionamento della spedizione 890"),
VALUE_AFTER_REFINEMENT("Evento arrivato dopo la conclusione della spedizione o mentre si stava aspettando l’OCR (DONE o AWAITING_OCR)"),
VALUES_NOT_MATCHING("Errore nella validazione degli allegati della sequenza: mancano degli allegati"),
INVALID_VALUES("Errore nella validazione"),
VALUES_NOT_FOUND("Errore nella validazione dei statusCode della sequenza: non sono presenti tutti gli statusCode previsti dalla macchina a stati");

private final String description;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package it.pagopa.pn.papertracker.middleware.dao.dynamo.entity;

import it.pagopa.pn.papertracker.middleware.dao.dynamo.AdditionalDetailsConverter;
import lombok.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbConvertedBy;

import java.util.Map;

@Setter
@Getter
Expand All @@ -13,7 +17,10 @@ public class ErrorDetails {

public static final String COL_CAUSE = "cause";
public static final String COL_MESSAGE = "message";
public static final String COL_ADDITIONAL_DETAILS = "additionalDetails";

private ErrorCause cause;
private String message;
@Getter(onMethod = @__({ @DynamoDbConvertedBy(AdditionalDetailsConverter.class) }))
private Map<String, Object> additionalDetails;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;

import static it.pagopa.pn.papertracker.model.EventStatusCodeEnum.*;

Expand Down Expand Up @@ -91,6 +92,9 @@ private Mono<Void> handleNoDifferenceGreater(HandlerContext context,
"The difference between RECRN005A and RECRN010 is greater than the configured duration",
PaperTrackingsErrorsMapper.buildPaperTrackingsError(paperTrackings, finalEvent.getStatusCode(), ErrorCategory.RENDICONTAZIONE_SCARTATA, ErrorCause.GIACENZA_DATE_ERROR,
String.format("RECRN005A getStatusTimestamp: %s, RECRN010 getStatusTimestamp: %s", eventRECRN00XA.getStatusTimestamp(), eventRECRN010.getStatusTimestamp()),
Map.of("recrn005aTimestamp", eventRECRN00XA.getStatusTimestamp().toString(),
"recrn010Timestamp", eventRECRN010.getStatusTimestamp().toString()
),
FlowThrow.FINAL_EVENT_BUILDING, ErrorType.ERROR, finalEvent.getId())));
}
return addEventToSend(context, finalEvent, EventStatusCodeEnum.fromKey(statusCode).getStatus().name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.Objects;

@Component
Expand Down Expand Up @@ -62,6 +63,9 @@ private boolean checkState(HandlerContext context) {
ErrorCategory.INCONSISTENT_STATE,
ErrorCause.STOCK_890_REFINEMENT_MISSING,
"invalid AWAITING_REFINEMENT state for stock 890",
Map.of("statusCode", context.getPaperProgressStatusEvent().getStatusCode(),
"statusTimestamp", context.getPaperProgressStatusEvent().getStatusDateTime().toString()
),
FlowThrow.SEQUENCE_VALIDATION,
ErrorType.ERROR,
context.getEventId()
Expand All @@ -81,6 +85,9 @@ private boolean checkState(HandlerContext context) {
ErrorCategory.INCONSISTENT_STATE,
ErrorCause.STOCK_890_REFINEMENT_ERROR,
"Refinement process reached KO state, cannot proceed with final event validation",
Map.of("statusCode", context.getPaperProgressStatusEvent().getStatusCode(),
"statusTimestamp", context.getPaperProgressStatusEvent().getStatusDateTime().toString()
),
FlowThrow.SEQUENCE_VALIDATION,
ErrorType.ERROR,
context.getEventId()
Expand All @@ -94,6 +101,7 @@ private boolean checkState(HandlerContext context) {
ErrorCategory.INVALID_STATE_FOR_STOCK_890,
ErrorCause.STOCK_890_REFINEMENT_ERROR,
String.format("Invalid state %s for processing stock 890 final event",state),
null,
FlowThrow.SEQUENCE_VALIDATION,
ErrorType.ERROR,
context.getEventId()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package it.pagopa.pn.papertracker.service.handler_step.generic;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sngular.apigenerator.asyncapi.business_model.model.event.Data;
import com.sngular.apigenerator.asyncapi.business_model.model.event.OcrDataResultPayload;
import it.pagopa.pn.papertracker.exception.PnPaperTrackerValidationException;
Expand All @@ -15,6 +17,7 @@
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.Objects;

@Component
Expand All @@ -23,6 +26,7 @@
public class CheckOcrResponse implements HandlerStep {

private final PaperTrackingsDAO paperTrackingsDAO;
private final ObjectMapper objectMapper;

/**
* Step che effettua un controllo sul messaggio ricevuto dal servizio OCR.<br>
Expand Down Expand Up @@ -71,11 +75,21 @@ private Mono<Void> handleFinalStateError(Event event, PaperTrackings paperTracki
PaperTrackingsErrorsMapper.buildPaperTrackingsError(
paperTrackings, event.getStatusCode(), ErrorCategory.OCR_VALIDATION,
cause, "CommandId: " + ocrResultMessage.getCommandId(),
Map.of("ocrDataResultPayload", transformToMap(ocrResultMessage.getData())),
FlowThrow.DEMAT_VALIDATION, type, event.getId()
)
));
}

private Map<String,Object> transformToMap(Data data) {
return objectMapper.convertValue(
data,
new TypeReference<>() {
}
);
}


private Mono<Void> handleValidationStatus(Data.ValidationStatus status, PaperTrackings paperTrackings,
Event event, OcrDataResultPayload ocrResultMessage, HandlerContext context) {
return switch (status) {
Expand All @@ -84,6 +98,7 @@ private Mono<Void> handleValidationStatus(Data.ValidationStatus status, PaperTra
PaperTrackingsErrorsMapper.buildPaperTrackingsError(
paperTrackings, event.getStatusCode(), ErrorCategory.OCR_VALIDATION,
ErrorCause.OCR_KO, ocrResultMessage.getData().getDescription(),
Map.of("ocrDataResultPayload", transformToMap(ocrResultMessage.getData())),
FlowThrow.DEMAT_VALIDATION, ErrorType.ERROR, event.getId()
)
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import it.pagopa.pn.papertracker.exception.PnPaperTrackerValidationException;
import it.pagopa.pn.papertracker.mapper.PaperTrackingsErrorsMapper;
import it.pagopa.pn.papertracker.middleware.dao.dynamo.entity.ErrorCategory;
import it.pagopa.pn.papertracker.middleware.dao.dynamo.entity.ErrorCause;
import it.pagopa.pn.papertracker.middleware.dao.dynamo.entity.ErrorType;
import it.pagopa.pn.papertracker.middleware.dao.dynamo.entity.FlowThrow;
import it.pagopa.pn.papertracker.model.HandlerContext;
Expand All @@ -13,6 +14,9 @@
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.Objects;

import static it.pagopa.pn.papertracker.utils.TrackerUtility.isInvalidState;

@Component
Expand Down Expand Up @@ -53,15 +57,19 @@ private Mono<Void> createValidationError(HandlerContext ctx, String statusCode)
: ctx.getPaperTrackings().getState().name();

String errorMsg = String.format("Tracking in state %s, statusCode %s: %s", state, statusCode, ctx.getTrackingId());
Map<String, Object> additionalDetails = Map.of("statusCode", statusCode,
"statusTimestamp", Objects.toString(ctx.getPaperProgressStatusEvent().getStatusDateTime(), null)
);

return Mono.error(new PnPaperTrackerValidationException(
errorMsg,
PaperTrackingsErrorsMapper.buildPaperTrackingsError(
ctx.getPaperTrackings(),
statusCode,
ErrorCategory.INCONSISTENT_STATE,
null,
ErrorCause.VALUE_AFTER_REFINEMENT,
errorMsg,
additionalDetails,
FlowThrow.CHECK_TRACKING_STATE,
ErrorType.WARNING,
ctx.getEventId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static java.time.temporal.ChronoUnit.SECONDS;
Expand Down Expand Up @@ -65,6 +66,10 @@ private PnPaperTrackerValidationException createValidationException(PaperTrackin
PaperProgressStatusEvent event,
HandlerContext context) {
String statusCode = event.getStatusCode();
Map<String, Object> additionalDetails = Map.of(
"statusCode", statusCode,
"statusTimestamp", Objects.toString(event.getStatusDateTime(), null)
);
return new PnPaperTrackerValidationException(
"Duplicated event found: " + statusCode,
PaperTrackingsErrorsMapper.buildPaperTrackingsError(
Expand All @@ -73,6 +78,7 @@ private PnPaperTrackerValidationException createValidationException(PaperTrackin
ErrorCategory.DUPLICATED_EVENT,
null,
"Duplicated event found for statusCode: " + statusCode,
additionalDetails,
FlowThrow.DUPLICATED_EVENT_VALIDATION,
ErrorType.WARNING,
context.getEventId()
Expand Down
Loading