Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(chore):965 added error handling for irs response #1083

Merged
merged 1 commit into from
Jun 20, 2024
Merged
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
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;
}

Loading