From 35c6f2df3df2de7f54f717c2167f7b170494cdc9 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Tue, 26 Mar 2019 09:26:00 +0000 Subject: [PATCH] Add ErrorResponse to policy framework exceptions The ErrorResponse object is now contained in Policy Framework exceptions. Issue-ID: POLICY-1095 Change-Id: Ib0ce6cdbbead939afefc4afa3f507eb1a28c4a5c Signed-off-by: liamfallon --- models-base/pom.xml | 11 ++++- .../onap/policy/models/base/PfModelException.java | 54 ++++----------------- .../models/base/PfModelRuntimeException.java | 36 ++++---------- .../onap/policy/models/base/ExceptionsTest.java | 9 ++-- .../models/base/PfModelExceptionInfoTest.java | 11 +++-- models-errors/pom.xml | 2 +- .../models/errors/concepts/ErrorResponse.java | 4 +- .../models/errors/concepts/ErrorResponseInfo.java | 35 +++----------- .../models/errors/concepts/ErrorResponseUtils.java | 56 ++++++++++++++++++++++ .../errors/concepts/ErrorResponseUtilsTest.java | 53 ++++++++++++++++++++ 10 files changed, 160 insertions(+), 111 deletions(-) rename models-base/src/main/java/org/onap/policy/models/base/PfModelExceptionInfo.java => models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseInfo.java (52%) create mode 100644 models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseUtils.java create mode 100644 models-errors/src/test/java/org/onap/policy/models/errors/concepts/ErrorResponseUtilsTest.java diff --git a/models-base/pom.xml b/models-base/pom.xml index 712bc9108..0523c3324 100644 --- a/models-base/pom.xml +++ b/models-base/pom.xml @@ -17,8 +17,7 @@ SPDX-License-Identifier: Apache-2.0 ============LICENSE_END========================================================= --> - 4.0.0 @@ -30,4 +29,12 @@ policy-models-base ${project.artifactId} [${project.parent.artifactId}] module provides basic model handling for the ONAP Policy Framework + + + + org.onap.policy.models + policy-models-errors + ${project.version} + + diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java index ce44e51f3..46c5bd311 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java @@ -25,18 +25,20 @@ import javax.ws.rs.core.Response; import lombok.Getter; import lombok.ToString; -import org.apache.commons.lang3.exception.ExceptionUtils; +import org.onap.policy.models.errors.concepts.ErrorResponse; +import org.onap.policy.models.errors.concepts.ErrorResponseInfo; +import org.onap.policy.models.errors.concepts.ErrorResponseUtils; /** * This class is a base exception from which all model exceptions are sub classes. */ @Getter @ToString -public class PfModelException extends Exception implements PfModelExceptionInfo { +public class PfModelException extends Exception implements ErrorResponseInfo { private static final long serialVersionUID = -8507246953751956974L; - // The status code on the exception - private final Response.Status statusCode; + // The error response of the exception + private final ErrorResponse errorResponse = new ErrorResponse(); // The object on which the exception was thrown private final transient Object object; @@ -60,7 +62,8 @@ public class PfModelException extends Exception implements PfModelExceptionInfo */ public PfModelException(final Response.Status statusCode, final String message, final Object object) { super(message); - this.statusCode = statusCode; + errorResponse.setResponseCode(statusCode); + ErrorResponseUtils.getExceptionMessages(errorResponse, this); this.object = object; } @@ -86,45 +89,8 @@ public class PfModelException extends Exception implements PfModelExceptionInfo public PfModelException(final Response.Status statusCode, final String message, final Exception exception, final Object object) { super(message, exception); - this.statusCode = statusCode; + errorResponse.setResponseCode(statusCode); + ErrorResponseUtils.getExceptionMessages(errorResponse, this); this.object = object; } - - /** - * Get the message from this exception and its causes. - * - * @return the cascaded messages from this exception and the exceptions that caused it - */ - @Override - public String getCascadedMessage() { - return buildCascadedMessage(this); - } - - /** - * Build a cascaded message from an exception and all its nested exceptions. - * - * @param throwable the top level exception - * @return cascaded message string - */ - public static String buildCascadedMessage(Throwable throwable) { - final StringBuilder builder = new StringBuilder(); - builder.append(throwable.getMessage()); - - for (Throwable t = throwable; t != null; t = t.getCause()) { - builder.append("\ncaused by: "); - builder.append(t.getMessage()); - } - - return builder.toString(); - } - - /** - * Get the stack trace of the exception as a string. - * - * @return the stack trace of this message as a string - */ - @Override - public String getStackTraceAsString() { - return ExceptionUtils.getStackTrace(this); - } } diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java index 32855c2a4..472412865 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java @@ -25,18 +25,20 @@ import javax.ws.rs.core.Response; import lombok.Getter; import lombok.ToString; -import org.apache.commons.lang3.exception.ExceptionUtils; +import org.onap.policy.models.errors.concepts.ErrorResponse; +import org.onap.policy.models.errors.concepts.ErrorResponseInfo; +import org.onap.policy.models.errors.concepts.ErrorResponseUtils; /** * This class is a base model run time exception from which all model run time exceptions are sub classes. */ @Getter @ToString -public class PfModelRuntimeException extends RuntimeException implements PfModelExceptionInfo { +public class PfModelRuntimeException extends RuntimeException implements ErrorResponseInfo { private static final long serialVersionUID = -8507246953751956974L; - // The return code on the exception - private final Response.Status statusCode; + // The error response of the exception + private final ErrorResponse errorResponse = new ErrorResponse(); // The object on which the exception was thrown private final transient Object object; @@ -61,7 +63,8 @@ public class PfModelRuntimeException extends RuntimeException implements PfModel public PfModelRuntimeException(final Response.Status statusCode, final String message, final Object object) { super(message); this.object = object; - this.statusCode = statusCode; + errorResponse.setResponseCode(statusCode); + ErrorResponseUtils.getExceptionMessages(errorResponse, this); } /** @@ -87,26 +90,7 @@ public class PfModelRuntimeException extends RuntimeException implements PfModel final Object object) { super(message, exception); this.object = object; - this.statusCode = statusCode; - } - - /** - * Get the message from this exception and its causes. - * - * @return the message of this exception and all the exceptions that caused this exception - */ - @Override - public String getCascadedMessage() { - return PfModelException.buildCascadedMessage(this); - } - - /** - * Get the stack trace of the exception as a string. - * - * @return the stack trace of this message as a string - */ - @Override - public String getStackTraceAsString() { - return ExceptionUtils.getStackTrace(this); + errorResponse.setResponseCode(statusCode); + ErrorResponseUtils.getExceptionMessages(errorResponse, this); } } diff --git a/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java b/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java index 0a5b6a0a6..664e3ddbc 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java +++ b/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java @@ -28,6 +28,7 @@ import java.io.IOException; import javax.ws.rs.core.Response; import org.junit.Test; +import org.onap.policy.models.errors.concepts.ErrorResponse; public class ExceptionsTest { @@ -41,7 +42,8 @@ public class ExceptionsTest { String key = "A String"; PfModelException ae = new PfModelException(Response.Status.OK, "Message", new IOException("IO exception message"), key); - assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ae.getCascadedMessage()); + ErrorResponse errorResponse = ae.getErrorResponse(); + assertEquals("Message\nIO exception message", String.join("\n", errorResponse.getErrorDetails())); assertEquals(key, ae.getObject()); assertNotNull(new PfModelRuntimeException(Response.Status.OK, "Message")); @@ -52,8 +54,9 @@ public class ExceptionsTest { String rkey = "A String"; PfModelRuntimeException re = new PfModelRuntimeException(Response.Status.OK, "Runtime Message", new IOException("IO runtime exception message"), rkey); - assertEquals("Runtime Message\ncaused by: Runtime Message\ncaused by: IO runtime exception message", - re.getCascadedMessage()); + errorResponse = re.getErrorResponse(); + assertEquals("Runtime Message\nIO runtime exception message", + String.join("\n", errorResponse.getErrorDetails())); assertEquals(key, re.getObject()); } } diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfModelExceptionInfoTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfModelExceptionInfoTest.java index 1257975ad..183b44c13 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/PfModelExceptionInfoTest.java +++ b/models-base/src/test/java/org/onap/policy/models/base/PfModelExceptionInfoTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertEquals; import javax.ws.rs.core.Response; import org.junit.Test; +import org.onap.policy.models.errors.concepts.ErrorResponseInfo; /** * Test PfModelExceptionInfo interface. @@ -49,15 +50,15 @@ public class PfModelExceptionInfoTest { } } - private String getErrorMessage(final PfModelExceptionInfo pfme) { + private String getErrorMessage(final ErrorResponseInfo eri) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("Server returned: "); - stringBuilder.append(pfme.getStatusCode().toString()); + stringBuilder.append(eri.getErrorResponse().getResponseCode().toString()); + stringBuilder.append("Error Message:\n"); + stringBuilder.append(eri.getErrorResponse().getErrorMessage()); stringBuilder.append("\nDetailed Message:\n"); - stringBuilder.append(pfme.getCascadedMessage()); - stringBuilder.append("\nStack Trace:\n"); - stringBuilder.append(pfme.getStackTraceAsString()); + stringBuilder.append(String.join("\n", eri.getErrorResponse().getErrorDetails())); return stringBuilder.toString(); } diff --git a/models-errors/pom.xml b/models-errors/pom.xml index ab998537e..4e297868e 100644 --- a/models-errors/pom.xml +++ b/models-errors/pom.xml @@ -27,7 +27,7 @@ 2.0.0-SNAPSHOT - models-errors + policy-models-errors ${project.artifactId} The models for Policy API's to return Error/warning message details. diff --git a/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponse.java b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponse.java index b072ba1f6..88960f8ae 100644 --- a/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponse.java +++ b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponse.java @@ -22,6 +22,7 @@ package org.onap.policy.models.errors.concepts; import com.google.gson.annotations.SerializedName; +import java.io.Serializable; import java.util.List; import javax.ws.rs.core.Response; @@ -36,7 +37,8 @@ import lombok.Data; * */ @Data -public class ErrorResponse { +public class ErrorResponse implements Serializable { + private static final long serialVersionUID = 6760066094588944729L; @SerializedName("code") private Response.Status responseCode; diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelExceptionInfo.java b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseInfo.java similarity index 52% rename from models-base/src/main/java/org/onap/policy/models/base/PfModelExceptionInfo.java rename to models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseInfo.java index 2fe244cec..ed7104b04 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfModelExceptionInfo.java +++ b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseInfo.java @@ -18,42 +18,19 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.models.base; - -import javax.ws.rs.core.Response; +package org.onap.policy.models.errors.concepts; /** - * Interface implemented bu Policy framework model exceptions to allow uniform reading of status codes and cascaded - * messages. + * Interface implemented by Policy framework model exceptions to allow uniform reading of error responses. * * @author Liam Fallon (liam.fallon@est.tech) */ -public interface PfModelExceptionInfo { - - /** - * Get the status code associated with an exception. - * @return the status code - */ - public Response.Status getStatusCode(); - - /** - * Get the messages for all the cascaded exceptions in an exception. - * - * @return the cascaded message - */ - public String getCascadedMessage(); - - /** - * Get the object associated with an exception. - * - * @return the object associated with an exception - */ - public Object getObject(); +public interface ErrorResponseInfo { /** - * Get the stack trace of the exception as a string. + * Get the error response. * - * @return the stack trace of this message as a string + * @return the error response */ - public String getStackTraceAsString(); + public ErrorResponse getErrorResponse(); } diff --git a/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseUtils.java b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseUtils.java new file mode 100644 index 000000000..6346f9a90 --- /dev/null +++ b/models-errors/src/main/java/org/onap/policy/models/errors/concepts/ErrorResponseUtils.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.errors.concepts; + +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class for managing {@link ErrorResponse objects} + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +public final class ErrorResponseUtils { + /** + * Private constructor used to prevent sub class instantiation. + */ + private ErrorResponseUtils() {} + + /** + * Store the cascaded messages from an exception and all its nested exceptions in an ErrorResponse object. + * + * @param throwable the top level exception + */ + public static void getExceptionMessages(final ErrorResponse errorResponse, final Throwable throwable) { + errorResponse.setErrorMessage(throwable.getMessage()); + + List cascascadedErrorMessages = new ArrayList<>(); + + for (Throwable t = throwable; t != null; t = t.getCause()) { + cascascadedErrorMessages.add(t.getMessage()); + } + + if (!cascascadedErrorMessages.isEmpty()) { + errorResponse.setErrorDetails(cascascadedErrorMessages); + } + } +} + diff --git a/models-errors/src/test/java/org/onap/policy/models/errors/concepts/ErrorResponseUtilsTest.java b/models-errors/src/test/java/org/onap/policy/models/errors/concepts/ErrorResponseUtilsTest.java new file mode 100644 index 000000000..4f4ef395a --- /dev/null +++ b/models-errors/src/test/java/org/onap/policy/models/errors/concepts/ErrorResponseUtilsTest.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.errors.concepts; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +/** + * Test the {@link ErrorResponseUtils} class. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +public class ErrorResponseUtilsTest { + @Test + public void testErrorResponseUtils() { + try { + try { + throw new NumberFormatException("Exception 0"); + } + catch (Exception nfe) { + throw new IOException("Exception 1", nfe); + } + } catch (Exception ioe) { + ErrorResponse errorResponse = new ErrorResponse(); + ErrorResponseUtils.getExceptionMessages(errorResponse, ioe); + + assertEquals("Exception 1", errorResponse.getErrorMessage()); + assertEquals("Exception 1", errorResponse.getErrorDetails().get(0)); + assertEquals("Exception 0", errorResponse.getErrorDetails().get(1)); + } + } +} -- 2.16.6