// Path: ngsi2-client/src/main/java/com/orange/ngsi2/exception/Ngsi2Exception.java
// public class Ngsi2Exception extends RuntimeException {
// 
//     private Error error = new Error();
// 
//     /**
//      * Return specialized exception based on the HTTP status code and error
//      * @param statusCode the response code
//      * @param error the error
//      * @return the corresponding Ngsi2Exception
//      */
//     public static Ngsi2Exception fromError(int statusCode, Error error) {
//         switch (statusCode) {
//             case 409: return new ConflictingEntitiesException(error);
//             case 400: return new InvalidatedSyntaxException(error);
//             default: return new Ngsi2Exception(error);
//         }
//     }
// 
//     public Ngsi2Exception(Error error) {
//         this(error.getError(), error.getDescription().orElse(""), error.getAffectedItems().orElse(Collections.emptyList()));
//     }
// 
//     public Ngsi2Exception(String error, String description, Collection<String> affectedItems) {
//         this.error.setError(error);
//         if (description != null) {
//             this.error.setDescription(Optional.of(description));
//         } else {
//             this.error.setDescription(Optional.empty());
//         }
//         if (affectedItems != null) {
//             this.error.setAffectedItems(Optional.of(affectedItems));
//         } else {
//             this.error.setAffectedItems(Optional.empty());
//         }
//     }
// 
//     public Error getError() {
//         return error;
//     }
// 
//     public String getMessage() {
//         return error.toString();
//     }
// }
// 
// Path: ngsi2-client/src/main/java/com/orange/ngsi2/model/Error.java
// public class Error {
// 
//     private String error;
// 
//     @JsonInclude(JsonInclude.Include.NON_EMPTY)
//     private Optional<String> description;
// 
//     @JsonInclude(JsonInclude.Include.NON_EMPTY)
//     private Optional<Collection<String>> affectedItems;
// 
//     public Error() {
//     }
// 
//     public Error(String error) {
//         this.error = error;
//     }
// 
//     public Error(String error, Optional<String> description, Optional<Collection<String>> affectedItems) {
//         this.error = error;
//         this.description = description;
//         this.affectedItems = affectedItems;
//     }
// 
//     public String getError() {
//         return error;
//     }
// 
//     public void setError(String error) {
//         this.error = error;
//     }
// 
//     public Optional<String> getDescription() {
//         return description;
//     }
// 
//     public void setDescription(Optional<String> description) {
//         this.description = description;
//     }
// 
//     public Optional<Collection<String>> getAffectedItems() {
//         return affectedItems;
//     }
// 
//     public void setAffectedItems(Optional<Collection<String>> affectedItems) {
//         this.affectedItems = affectedItems;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("error: %s | description: %s | affectedItems: %s", error, description.orElse(""), affectedItems.orElse(Collections.emptyList()));
//     }
// }


import com.fasterxml.jackson.databind.ObjectMapper;
import com.orange.ngsi2.exception.Ngsi2Exception;
import com.orange.ngsi2.model.Error;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;
import java.io.IOException;
package com.orange.ngsi2.client;



/**
 * Error responses should contain an Error json structure.
 * Handle all errors by throwing an Ngsi2Exception containing the error.
 */
class Ngsi2ResponseErrorHandler implements ResponseErrorHandler {

    private ObjectMapper objectMapper;

    Ngsi2ResponseErrorHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return response.getStatusCode().is4xxClientError() || response.getStatusCode().is5xxServerError();
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        Ngsi2Exception ex;
        try {
// Path: ngsi2-client/src/main/java/com/orange/ngsi2/exception/Ngsi2Exception.java
// public class Ngsi2Exception extends RuntimeException {
// 
//     private Error error = new Error();
// 
//     /**
//      * Return specialized exception based on the HTTP status code and error
//      * @param statusCode the response code
//      * @param error the error
//      * @return the corresponding Ngsi2Exception
//      */
//     public static Ngsi2Exception fromError(int statusCode, Error error) {
//         switch (statusCode) {
//             case 409: return new ConflictingEntitiesException(error);
//             case 400: return new InvalidatedSyntaxException(error);
//             default: return new Ngsi2Exception(error);
//         }
//     }
// 
//     public Ngsi2Exception(Error error) {
//         this(error.getError(), error.getDescription().orElse(""), error.getAffectedItems().orElse(Collections.emptyList()));
//     }
// 
//     public Ngsi2Exception(String error, String description, Collection<String> affectedItems) {
//         this.error.setError(error);
//         if (description != null) {
//             this.error.setDescription(Optional.of(description));
//         } else {
//             this.error.setDescription(Optional.empty());
//         }
//         if (affectedItems != null) {
//             this.error.setAffectedItems(Optional.of(affectedItems));
//         } else {
//             this.error.setAffectedItems(Optional.empty());
//         }
//     }
// 
//     public Error getError() {
//         return error;
//     }
// 
//     public String getMessage() {
//         return error.toString();
//     }
// }
// 
// Path: ngsi2-client/src/main/java/com/orange/ngsi2/model/Error.java
// public class Error {
// 
//     private String error;
// 
//     @JsonInclude(JsonInclude.Include.NON_EMPTY)
//     private Optional<String> description;
// 
//     @JsonInclude(JsonInclude.Include.NON_EMPTY)
//     private Optional<Collection<String>> affectedItems;
// 
//     public Error() {
//     }
// 
//     public Error(String error) {
//         this.error = error;
//     }
// 
//     public Error(String error, Optional<String> description, Optional<Collection<String>> affectedItems) {
//         this.error = error;
//         this.description = description;
//         this.affectedItems = affectedItems;
//     }
// 
//     public String getError() {
//         return error;
//     }
// 
//     public void setError(String error) {
//         this.error = error;
//     }
// 
//     public Optional<String> getDescription() {
//         return description;
//     }
// 
//     public void setDescription(Optional<String> description) {
//         this.description = description;
//     }
// 
//     public Optional<Collection<String>> getAffectedItems() {
//         return affectedItems;
//     }
// 
//     public void setAffectedItems(Optional<Collection<String>> affectedItems) {
//         this.affectedItems = affectedItems;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("error: %s | description: %s | affectedItems: %s", error, description.orElse(""), affectedItems.orElse(Collections.emptyList()));
//     }
// }


// Path: ngsi2-client/src/main/java/com/orange/ngsi2/client/Ngsi2ResponseErrorHandler.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.orange.ngsi2.exception.Ngsi2Exception;
import com.orange.ngsi2.model.Error;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;
import java.io.IOException;

package com.orange.ngsi2.client;



/**
 * Error responses should contain an Error json structure.
 * Handle all errors by throwing an Ngsi2Exception containing the error.
 */
class Ngsi2ResponseErrorHandler implements ResponseErrorHandler {

    private ObjectMapper objectMapper;

    Ngsi2ResponseErrorHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return response.getStatusCode().is4xxClientError() || response.getStatusCode().is5xxServerError();
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        Ngsi2Exception ex;
        try {
            ex = Ngsi2Exception.fromError(response.getStatusCode().value(), objectMapper.readValue(response.getBody(), Error.class));