package org.onap.policy.api.main.config;
-import org.onap.policy.api.main.rest.StatisticsReport;
+import org.onap.policy.api.main.rest.provider.statistics.StatisticsReport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. All rights reserved.
+ * ================================================================================
+ * 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.api.main.exception;
+
+import javax.ws.rs.core.Response;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.errors.concepts.ErrorResponse;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.TransactionException;
+
+@Aspect
+@Component
+public class ServiceExceptionHandler {
+
+ /**
+ * Handle any exceptions that are not already handled.
+ * For e.g., runtime exceptions that could happen during SQL query execution related to data integrity etc.
+ *
+ * @param joinPoint the point of execution
+ * @param exception the exception
+ */
+ @AfterThrowing(pointcut = "execution(* org.onap.policy.api.main.service.*.*(..))", throwing = "exception")
+ public ResponseEntity<Object> handleServiceException(JoinPoint joinPoint, RuntimeException exception) {
+ if (exception instanceof PolicyApiRuntimeException || exception instanceof PfModelRuntimeException) {
+ throw exception;
+ } else {
+ final var errorResponse = new ErrorResponse();
+ errorResponse.setResponseCode(Response.Status.INTERNAL_SERVER_ERROR);
+ errorResponse.setErrorMessage(exception.getMessage());
+ throw new PolicyApiRuntimeException(exception.getMessage(), exception.getCause(), errorResponse, null);
+ }
+ }
+
+ /**
+ * Handle DB Transaction related exceptions.
+ * All service classes in org.onap.policy.api.main.service are transactional and autowiring these service classes
+ * can cause TransactionException.
+ * For e.g., JDBC connection failure occurs and failed to open transaction at service level
+ *
+ * @param joinPoint the point of execution
+ * @param exception the exception
+ */
+ @AfterThrowing(pointcut = "execution(* org.onap.policy.api.main..*.*(..))"
+ + " && !execution(* org.onap.policy.api.main.rest.provider.statistics.*.*(..))", throwing = "exception")
+ public ResponseEntity<Object> handleTransactionException(JoinPoint joinPoint, TransactionException exception) {
+ final var errorResponse = new ErrorResponse();
+ errorResponse.setResponseCode(Response.Status.INTERNAL_SERVER_ERROR);
+ errorResponse.setErrorMessage(exception.getMessage());
+ throw new PolicyApiRuntimeException(exception.getMessage(), exception.getCause(), errorResponse, null);
+ }
+}
\ No newline at end of file
import javax.ws.rs.core.Response.Status;\r
import lombok.RequiredArgsConstructor;\r
import org.onap.policy.api.main.exception.PolicyApiRuntimeException;\r
-import org.onap.policy.api.main.rest.provider.HealthCheckProvider;\r
-import org.onap.policy.api.main.rest.provider.StatisticsProvider;\r
+import org.onap.policy.api.main.rest.provider.healthcheck.HealthCheckProvider;\r
+import org.onap.policy.api.main.rest.provider.statistics.ApiStatisticsManager;\r
+import org.onap.policy.api.main.rest.provider.statistics.StatisticsProvider;\r
+import org.onap.policy.api.main.rest.provider.statistics.StatisticsReport;\r
import org.onap.policy.api.main.service.ToscaServiceTemplateService;\r
import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;\r
import org.onap.policy.common.endpoints.report.HealthCheckReport;\r
import org.onap.policy.common.utils.coder.StandardCoder;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
-import org.springframework.http.HttpHeaders;\r
import org.springframework.http.ResponseEntity;\r
import org.springframework.web.bind.annotation.ExceptionHandler;\r
+import org.springframework.web.context.request.WebRequest;\r
\r
/**\r
* Super class from which REST controllers are derived.\r
protected static final String VERSION_LATEST_NAME = "X-LatestVersion";\r
protected static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version";\r
\r
- protected static final String REQUEST_ID_NAME = "X-ONAP-RequestID";\r
+ public static final String REQUEST_ID_NAME = "X-ONAP-RequestID";\r
protected static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose";\r
protected static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction";\r
\r
protected final Coder coder = new StandardCoder();\r
\r
protected <T> ResponseEntity<T> makeOkResponse(UUID requestId, T respEntity) {\r
- HttpHeaders headers = new HttpHeaders();\r
- addVersionControlHeaders(headers);\r
- addLoggingHeaders(headers, requestId);\r
- return ResponseEntity.ok().headers(headers).body(respEntity);\r
+ return CommonRestController.addLoggingHeaders(addVersionControlHeaders(ResponseEntity.ok()), requestId)\r
+ .body(respEntity);\r
}\r
\r
- protected <T> ResponseEntity<T> makeErrorResponse(UUID requestId, T respEntity, int status) {\r
- HttpHeaders headers = new HttpHeaders();\r
- addVersionControlHeaders(headers);\r
- addLoggingHeaders(headers, requestId);\r
- return ResponseEntity.status(status).headers(headers).body(respEntity);\r
- }\r
-\r
- private void addVersionControlHeaders(HttpHeaders headers) {\r
- headers.add("X-MinorVersion", "0");\r
- headers.add("X-PatchVersion", "0");\r
- headers.add("X-LatestVersion", "1.0.0");\r
+ /**\r
+ * Adds version headers to the response.\r
+ *\r
+ * @param respBuilder response builder\r
+ * @return the response builder, with version headers\r
+ */\r
+ public static ResponseEntity.BodyBuilder addVersionControlHeaders(ResponseEntity.BodyBuilder respBuilder) {\r
+ return respBuilder.header(VERSION_MINOR_NAME, "0").header(VERSION_PATCH_NAME, "0").header(VERSION_LATEST_NAME,\r
+ API_VERSION);\r
}\r
\r
- private void addLoggingHeaders(HttpHeaders headers, UUID requestId) {\r
+ /**\r
+ * Adds logging headers to the response.\r
+ *\r
+ * @param respBuilder response builder\r
+ * @return the response builder, with version logging\r
+ */\r
+ public static ResponseEntity.BodyBuilder addLoggingHeaders(ResponseEntity.BodyBuilder respBuilder, UUID requestId) {\r
if (requestId == null) {\r
// Generate a random uuid if client does not embed requestId in rest request\r
- headers.add("X-ONAP-RequestID", UUID.randomUUID().toString());\r
- } else {\r
- headers.add("X-ONAP-RequestID", requestId.toString());\r
+ return respBuilder.header(REQUEST_ID_NAME, UUID.randomUUID().toString());\r
}\r
+\r
+ return respBuilder.header(REQUEST_ID_NAME, requestId.toString());\r
}\r
\r
/**\r
}\r
\r
@ExceptionHandler(value = {PolicyApiRuntimeException.class})\r
- protected ResponseEntity<Object> handleException(PolicyApiRuntimeException ex) {\r
+ protected ResponseEntity<Object> handleException(PolicyApiRuntimeException ex, WebRequest req) {\r
LOGGER.warn(ex.getMessage(), ex.getCause());\r
- return makeErrorResponse(ex.getRequestId(), ex.getErrorResponse(),\r
- ex.getErrorResponse().getResponseCode().getStatusCode());\r
+ final var requestId = req.getHeader(CommonRestController.REQUEST_ID_NAME);\r
+ final var status = ex.getErrorResponse().getResponseCode().getStatusCode();\r
+ return CommonRestController.addLoggingHeaders(\r
+ CommonRestController.addVersionControlHeaders(ResponseEntity.status(status)),\r
+ requestId != null ? UUID.fromString(requestId) : ex.getRequestId()).body(ex.getErrorResponse());\r
}\r
}
\ No newline at end of file
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.api.main.rest.provider;
+package org.onap.policy.api.main.rest.provider.healthcheck;
import lombok.RequiredArgsConstructor;
-import org.onap.policy.api.main.rest.PolicyFetchMode;
import org.onap.policy.api.main.service.ToscaServiceTemplateService;
import org.onap.policy.common.endpoints.report.HealthCheckReport;
import org.onap.policy.common.utils.network.NetworkUtil;
-import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.base.PfModelRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.api.main.rest;
+package org.onap.policy.api.main.rest.provider.statistics;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.api.main.rest.provider;
+package org.onap.policy.api.main.rest.provider.statistics;
import lombok.RequiredArgsConstructor;
-import org.onap.policy.api.main.rest.StatisticsReport;
import org.springframework.stereotype.Service;
/**
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.api.main.rest;
+package org.onap.policy.api.main.rest.provider.statistics;
import lombok.Getter;
import lombok.Setter;
protected long policyTypeGetFailureCount;
protected long policyTypePostSuccessCount;
protected long policyTypePostFailureCount;
-}
+}
\ No newline at end of file
import org.junit.Test;
import org.junit.runner.RunWith;
import org.onap.policy.api.main.PolicyApiApplication;
+import org.onap.policy.api.main.rest.provider.statistics.ApiStatisticsManager;
+import org.onap.policy.api.main.rest.provider.statistics.StatisticsReport;
import org.onap.policy.api.main.rest.utils.CommonTestRestController;
import org.onap.policy.common.endpoints.report.HealthCheckReport;
import org.onap.policy.common.utils.coder.StandardCoder;
import static org.junit.Assert.assertEquals;
-import lombok.RequiredArgsConstructor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.onap.policy.api.main.PolicyApiApplication;
+import org.onap.policy.api.main.rest.provider.statistics.ApiStatisticsManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import com.openpojo.validation.test.impl.GetterTester;
import com.openpojo.validation.test.impl.SetterTester;
import org.junit.Test;
+import org.onap.policy.api.main.rest.provider.statistics.StatisticsReport;
import org.onap.policy.common.utils.test.ToStringTester;
/**
validator.validate(StatisticsReport.class.getPackage().getName(),
new FilterClassName(StatisticsReport.class.getName()));
}
-}
+}
\ No newline at end of file