Skip to content

Commit

Permalink
feat: Moved in a filter the validation of RequestId and Version. (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniotarricone authored Aug 1, 2024
1 parent 5ad2abe commit 6f29a60
Show file tree
Hide file tree
Showing 13 changed files with 848 additions and 704 deletions.
1,353 changes: 680 additions & 673 deletions dep-sha256.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<!-- Quarkus version -->
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.10.1</quarkus.platform.version>
<quarkus.platform.version>3.13.0</quarkus.platform.version>
<!-- Plugins version -->
<compiler-plugin.version>3.12.1</compiler-plugin.version>
<surefire-plugin.version>3.2.5</surefire-plugin.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* MappedDiagnosticContextFilter.java
*
* 28 nov 2022
*/
package it.pagopa.swclient.mil;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import it.pagopa.swclient.mil.bean.Errors;
import it.pagopa.swclient.mil.bean.HeaderParamName;
import it.pagopa.swclient.mil.bean.ValidationPattern;
import jakarta.annotation.Priority;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.Provider;

/**
*
* @author Antonio Tarricone
*/
@Provider
@PreMatching
@Priority(Priorities.USER)
public class CommonHeadersValidatorFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
List<String> errorCodes = new LinkedList<>();
List<String> errorMsgs = new LinkedList<>();

String requestId = requestContext.getHeaderString(HeaderParamName.REQUEST_ID);
if (requestId != null && !requestId.matches(ValidationPattern.REQUEST_ID)) {
errorCodes.add(ErrorCode.REQUEST_ID_MUST_MATCH_REGEXP);
errorCodes.add(ErrorCode.REQUEST_ID_MUST_MATCH_REGEXP_MSG);
}

String version = requestContext.getHeaderString(HeaderParamName.VERSION);
if (version != null && !version.matches(ValidationPattern.VERSION)) {
errorCodes.add(ErrorCode.VERSION_MUST_MATCH_REGEXP);
errorCodes.add(ErrorCode.VERSION_MUST_MATCH_REGEXP_MSG);
}

if (!errorCodes.isEmpty()) {
Response response = Response.status(Status.BAD_REQUEST)
.entity(new Errors(errorCodes, errorMsgs))
.build();
throw new BadRequestException(response);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import it.pagopa.swclient.mil.bean.Errors;
import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -60,7 +61,7 @@ public Response toResponse(ConstraintViolationException e) {
.collect(Collectors.toMap(Error::getCode, Error::getDescription, (value1, value2) -> value1));

return Response
.status(Response.Status.BAD_REQUEST.getStatusCode())
.status(Status.BAD_REQUEST)
.entity(new Errors(
errors.keySet().stream().toList(),
errors.values().stream().toList()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

import org.jboss.logging.MDC;

import it.pagopa.swclient.mil.bean.HeaderParamName;
import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
Expand All @@ -21,13 +24,14 @@
*/
@Provider
@PreMatching
@Priority(Priorities.USER + 100)
public class MappedDiagnosticContextFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String requestId = requestContext.getHeaderString("RequestId");
String requestId = requestContext.getHeaderString(HeaderParamName.REQUEST_ID);
if (requestId == null) {
requestId = UUID.randomUUID().toString();
requestContext.getHeaders().add("RequestId", requestId);
requestContext.getHeaders().add(HeaderParamName.REQUEST_ID, requestId);
}
MDC.put("requestId", requestId);
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/it/pagopa/swclient/mil/RequestIdEchoFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import java.io.IOException;

import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
Expand All @@ -18,6 +20,7 @@
* @author Antonio Tarricone
*/
@Provider
@Priority(Priorities.USER)
public class RequestIdEchoFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/it/pagopa/swclient/mil/bean/CommonHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import it.pagopa.swclient.mil.validation.constraints.MerchantIdNotNullForPos;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import jakarta.ws.rs.HeaderParam;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -36,15 +35,16 @@ public class CommonHeader {
*/
@HeaderParam(HeaderParamName.REQUEST_ID)
@NotNull(message = ErrorCode.REQUEST_ID_MUST_NOT_BE_NULL_MSG)
@Pattern(regexp = ValidationPattern.REQUEST_ID, message = ErrorCode.REQUEST_ID_MUST_MATCH_REGEXP_MSG)
// It's verified by it.pagopa.swclient.mil.CommonHeadersValidatorFilter:
// @Pattern(regexp = ValidationPattern.REQUEST_ID, message = ErrorCode.REQUEST_ID_MUST_MATCH_REGEXP_MSG)
private String requestId;

/*
* Version of the required API
*/
@HeaderParam(HeaderParamName.VERSION)
@Size(max = 64, message = ErrorCode.VERSION_SIZE_MUST_BE_AT_MOST_MAX_MSG)
@Pattern(regexp = ValidationPattern.VERSION, message = ErrorCode.VERSION_MUST_MATCH_REGEXP_MSG)
// It's verified by it.pagopa.swclient.mil.CommonHeadersValidatorFilter:
// @Pattern(regexp = ValidationPattern.VERSION, message = ErrorCode.VERSION_MUST_MATCH_REGEXP_MSG)
private String version;

/*
Expand Down
18 changes: 7 additions & 11 deletions src/main/java/it/pagopa/swclient/mil/bean/Errors.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
Expand All @@ -23,10 +25,11 @@
*
* @author Antonio Tarricone
*/
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
@Setter
@NoArgsConstructor
@Getter
@Setter
@ToString
@Accessors(chain = true)
@RegisterForReflection
Expand All @@ -35,21 +38,14 @@ public class Errors {
/*
* List of error codes
*/
private List<String> errors;
@NonNull
private List<String> errors; // NOSONAR

/*
* List of error descriptions.
*/
private List<String> descriptions;

/**
*
* @param errors
*/
public Errors(List<String> errors) {
this.errors = errors;
}

/**
*
* @param error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import io.quarkus.mongodb.panache.common.MongoEntity;
import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase;
import io.quarkus.mongodb.reactive.ReactiveMongoCollection;
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
import jakarta.ws.rs.Priorities;

/**
* <p>
Expand All @@ -36,6 +38,7 @@
*/
@TraceReactivePanacheMongoRepository
@Interceptor
@Priority(Priorities.USER)
public class ReactivePanacheMongoRepositoryTraceInterceptor {
/*
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* CommonHeadersValidatorFilterTest.java
*
* 29 apr 2024
*/
package it.pagopa.swclient.mil;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.UUID;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import it.pagopa.swclient.mil.bean.HeaderParamName;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.container.ContainerRequestContext;

/**
*
* @author Antonio Tarricone
*/
@QuarkusTest
class CommonHeadersValidatorFilterTest {
@Test
void given_request_when_requestIdAndVersionAreOk_then_noExcpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);
when(context.getHeaderString(HeaderParamName.REQUEST_ID)).thenReturn(UUID.randomUUID().toString());
when(context.getHeaderString(HeaderParamName.VERSION)).thenReturn("1.0");

assertDoesNotThrow(() -> new CommonHeadersValidatorFilter().filter(context));
}

@Test
void given_request_when_requestIdAndVersionAreNotSet_then_noExcpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);

assertDoesNotThrow(() -> new CommonHeadersValidatorFilter().filter(context));
}

@Test
void given_request_when_requestIdIsInvalidAndVersionIsValid_then_excpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);
when(context.getHeaderString(HeaderParamName.REQUEST_ID)).thenReturn("");
when(context.getHeaderString(HeaderParamName.VERSION)).thenReturn("1.0");

CommonHeadersValidatorFilter filter = new CommonHeadersValidatorFilter();
assertThrows(BadRequestException.class, () -> filter.filter(context));
}

@Test
void given_request_when_requestIdIsInvalidAndVersionIsNotSet_then_excpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);
when(context.getHeaderString(HeaderParamName.REQUEST_ID)).thenReturn("");

CommonHeadersValidatorFilter filter = new CommonHeadersValidatorFilter();
assertThrows(BadRequestException.class, () -> filter.filter(context));
}

@Test
void given_request_when_requestIdIsValidAndVersionIsInvalid_then_excpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);
when(context.getHeaderString(HeaderParamName.REQUEST_ID)).thenReturn(UUID.randomUUID().toString());
when(context.getHeaderString(HeaderParamName.VERSION)).thenReturn(new String(new byte[] {
0
}));

CommonHeadersValidatorFilter filter = new CommonHeadersValidatorFilter();
assertThrows(BadRequestException.class, () -> filter.filter(context));
}

@Test
void given_request_when_requestIdIsNotSetAndVersionIsInvalid_then_excpetionMustBeThrown() {
ContainerRequestContext context = mock(ContainerRequestContext.class);
when(context.getHeaderString(HeaderParamName.VERSION)).thenReturn(new String(new byte[] {
0
}));

CommonHeadersValidatorFilter filter = new CommonHeadersValidatorFilter();
assertThrows(BadRequestException.class, () -> filter.filter(context));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import io.quarkus.test.junit.QuarkusTest;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.MultivaluedHashMap;
import jakarta.ws.rs.core.MultivaluedMap;

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.io.IOException;
import java.util.List;

import org.jboss.logging.MDC;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
Expand Down
10 changes: 0 additions & 10 deletions src/test/java/it/pagopa/swclient/mil/bean/ErrorsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package it.pagopa.swclient.mil.bean;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;

import java.util.List;

Expand All @@ -20,15 +19,6 @@
*/
@QuarkusTest
class ErrorsTest {
/**
*
*/
@Test
void given_listOfErrorsWithoutDescription_when_getList_then_returnGivenList() {
List<String> expected = List.of("error_code_1", "error_code_2");
assertIterableEquals(expected, new Errors(expected).getErrors());
}

/**
*
*/
Expand Down

0 comments on commit 6f29a60

Please sign in to comment.