Skip to content

Commit

Permalink
Merge pull request #1083 from eclipse-tractusx/feature/965-policy-man…
Browse files Browse the repository at this point in the history
…agement-error-handling

feature(chore):965 added error handling for irs response
  • Loading branch information
ds-mmaul authored Jun 20, 2024
2 parents cd899fe + 85e2706 commit 3a4b787
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
package org.eclipse.tractusx.traceability.common.config;

import assets.importpoc.ErrorResponse;
import assets.importpoc.IRSErrorResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand Down Expand Up @@ -57,6 +59,7 @@
import org.eclipse.tractusx.traceability.notification.domain.notification.exception.NotificationSenderAndReceiverBPNEqualException;
import org.eclipse.tractusx.traceability.notification.domain.notification.exception.NotificationStatusTransitionNotAllowed;
import org.eclipse.tractusx.traceability.submodel.domain.model.SubmodelNotFoundException;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
Expand All @@ -69,7 +72,6 @@
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
Expand Down Expand Up @@ -109,16 +111,64 @@ ResponseEntity<ErrorResponse> handleHttpClientErrorException(HttpClientErrorExce
String errorMessage;

if (status.equals(BAD_REQUEST)) {
return ResponseEntity.status(BAD_REQUEST)
try {
ResponseEntity<ErrorResponse> errorResponse = mapIRSBadRequestToErrorResponse(exception);
if (errorResponse != null) return errorResponse;
}
catch (Exception e) {
ResponseEntity<ErrorResponse> body = ResponseEntity.status(BAD_REQUEST)
.body(new ErrorResponse(exception.getMessage()));
return body; // Handle the case where the message cannot be mapped to IRSErrorResponse
}

} else if (status.equals(NOT_FOUND)) {
return ResponseEntity.status(NOT_FOUND)
.body(new ErrorResponse(exception.getMessage()));
try {
ResponseEntity<ErrorResponse> errorResponse = mapIRSNotFoundToErrorResponse(exception);
if (errorResponse != null) return errorResponse;
}
catch (Exception e) {
ResponseEntity<ErrorResponse> body = ResponseEntity.status(NOT_FOUND)
.body(new ErrorResponse(exception.getMessage()));
return body; // Handle the case where the message cannot be mapped to IRSErrorResponse
}
} else {
errorMessage = exception.getMessage();
return ResponseEntity.status(status)
.body(new ErrorResponse(errorMessage));
}
return ResponseEntity.status(status).body(new ErrorResponse(exception.getMessage()));
}

private @Nullable ResponseEntity<ErrorResponse> mapIRSBadRequestToErrorResponse(HttpClientErrorException exception) throws JsonProcessingException {
String rawMessage = exception.getMessage().replaceAll("<EOL>", "");
// Extract the JSON part of the message
int jsonStart = rawMessage.indexOf("{");
int jsonEnd = rawMessage.lastIndexOf("}");
if (jsonStart != -1 && jsonEnd != -1) {
String jsonString = rawMessage.substring(jsonStart, jsonEnd + 1);
IRSErrorResponse badRequestResponse = objectMapper.readValue(jsonString, IRSErrorResponse.class);
if (badRequestResponse != null && badRequestResponse.getMessage() != null) {
ErrorResponse errorResponse = new ErrorResponse(badRequestResponse.getMessage());
return ResponseEntity.status(400).body(errorResponse);
}
}
return null;
}

private @Nullable ResponseEntity<ErrorResponse> mapIRSNotFoundToErrorResponse(HttpClientErrorException exception) throws JsonProcessingException {
String rawMessage = exception.getMessage().replaceAll("<EOL>", "");
// Extract the JSON part of the message
int jsonStart = rawMessage.indexOf("{");
int jsonEnd = rawMessage.lastIndexOf("}");
if (jsonStart != -1 && jsonEnd != -1) {
String jsonString = rawMessage.substring(jsonStart, jsonEnd + 1);
IRSErrorResponse irsError = objectMapper.readValue(jsonString, IRSErrorResponse.class);
if (irsError != null && irsError.getMessage() != null) {
ErrorResponse errorResponse = new ErrorResponse(irsError.getMessage());
return ResponseEntity.status(404).body(errorResponse);
}
}
return null;
}

@ExceptionHandler(PolicyBadRequestException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ public void irsApiReturnsPolicies() {
);
}

public void irsApiReturnsPoliciesNotFound(String id) {
whenHttp(restitoProvider.stubServer()).match(
Condition.get("/irs/policies/" +id)
).then(
Action.status(HttpStatus.NOT_FOUND_404),
Action.header("Content-Type", "application/json"),
restitoProvider.jsonResponseFromFile("./stubs/irs/policies/response_404_get_policyById.json")
);
}

public void irsApiReturnsPolicyById(String policyId) {
whenHttp(restitoProvider.stubServer()).match(
Condition.get("/irs/policies/" + policyId)
Expand All @@ -132,6 +142,15 @@ public void irsApiCreatesPolicy() {
restitoProvider.jsonResponseFromFile("./stubs/irs/policies/response_200_createPolicy.json")
);
}
public void irsApiCreatesPolicyBadRequest() {
whenHttp(restitoProvider.stubServer()).match(
Condition.post("/irs/policies")
).then(
Action.status(HttpStatus.BAD_REQUEST_400),
Action.header("Content-Type", "application/json"),
restitoProvider.jsonResponseFromFile("./stubs/irs/policies/response_400_createPolicy.json")
);
}

public void irsApiUpdatesPolicy() {
whenHttp(restitoProvider.stubServer()).match(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@
import policies.request.UpdatePolicyRequest;

import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

import static io.restassured.RestAssured.given;
import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;

class PolicyControllerIT extends IntegrationTestSpecification {
Expand Down Expand Up @@ -74,6 +75,23 @@ void shouldReturnGetPolicyById() throws JoseException {
.log().all();
}

@Test
void shouldReturnNotFoundGetPolicyById() throws JoseException {
// GIVEN
String policyId = "default-policy-not-exist";
irsApiSupport.irsApiReturnsPoliciesNotFound(policyId);

given()
.header(oAuth2Support.jwtAuthorization(ADMIN))
.contentType(ContentType.JSON)
.when()
.get("/api/policies/" + policyId)
.then()
.statusCode(404)
.body(containsString("404 Not Found: [no body]"))
.log().all();
}

@Test
void shouldCreatePolicy() throws JoseException {
// GIVEN
Expand All @@ -93,6 +111,32 @@ void shouldCreatePolicy() throws JoseException {
.log().all();
}


@Test
void shouldThorwBadRequestCreatePolicy() throws JoseException {
// GIVEN
irsApiSupport.irsApiCreatesPolicyBadRequest();

// Sample data
List<String> businessPartnerNumbers = Arrays.asList("BPN-123", "BPN-456");
List<String> policyIds = Arrays.asList("POLICY-789", "POLICY-101");
Instant validUntil = Instant.parse("2025-12-31T23:59:59.00Z");

// WRONG REQUEST OBJECT
UpdatePolicyRequest request = new UpdatePolicyRequest(businessPartnerNumbers, policyIds, validUntil);
// when/then
given()
.header(oAuth2Support.jwtAuthorization(ADMIN))
.contentType(ContentType.JSON)
.body(request)
.when()
.post("/api/policies")
.then()
.statusCode(400)
.body(containsString("Request does not contain all required fields. Missing: odrl:permission"))
.log().all();
}

@Test
void shouldUpdatePolicy() throws JoseException {
// GIVEN
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"message" : "Request does not contain all required fields. Missing: odrl:permission"
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"statusCode": "BAD_REQUEST",
"error": "Bad Request",
"messages": [
"Request does not contain all required fields. Missing: odrl:permission"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"message": "404 : \"{\"statusCode\":\"NOT_FOUND\",\"error\":\"Not Found\",\"messages\":[\"Policy with id 'default-paafdsasfdolicy' not found\"]}\""
}
30 changes: 30 additions & 0 deletions tx-models/src/main/java/assets/importpoc/IRSErrorResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/********************************************************************************
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package assets.importpoc;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class IRSErrorResponse {
private String message;
}

0 comments on commit 3a4b787

Please sign in to comment.