From 2b653a3e248cc91e02b12b4e91bc0022919f6089 Mon Sep 17 00:00:00 2001 From: Jennie Jia Date: Fri, 3 Aug 2018 18:33:40 +0000 Subject: Merge the POMBA code to ONAP AAI data router Issue-ID: LOG-588 Change-Id: I5d121121e1f6b8167cc0f6b3326b488aedf01430 Signed-off-by: Jennie Jia --- .../onap/aai/datarouter/entity/POAAuditEvent.java | 88 +++++ .../entity/POAServiceInstanceEntity.java | 173 +++++++++ .../datarouter/exception/POAAuditException.java | 87 +++++ .../aai/datarouter/logging/DataRouterMsgs.java | 417 +++++++++++---------- .../logging/ServiceIntegrityValidationsMsgs.java | 63 ++++ .../policy/ServiceIntegrityValidationPolicy.java | 213 +++++++++++ .../onap/aai/datarouter/service/AuditService.java | 205 ++++++++++ .../aai/datarouter/util/DataRouterProperties.java | 120 +++--- .../org/onap/aai/datarouter/util/LoggingUtil.java | 96 +++++ .../resources/auditservice_validation_schema.json | 20 + .../resources/auditservice_violation_schema.json | 16 + .../ServiceIntegrityValidationsMsgs.properties | 37 ++ 12 files changed, 1279 insertions(+), 256 deletions(-) create mode 100644 src/main/java/org/onap/aai/datarouter/entity/POAAuditEvent.java create mode 100644 src/main/java/org/onap/aai/datarouter/entity/POAServiceInstanceEntity.java create mode 100644 src/main/java/org/onap/aai/datarouter/exception/POAAuditException.java create mode 100644 src/main/java/org/onap/aai/datarouter/logging/ServiceIntegrityValidationsMsgs.java create mode 100644 src/main/java/org/onap/aai/datarouter/policy/ServiceIntegrityValidationPolicy.java create mode 100644 src/main/java/org/onap/aai/datarouter/service/AuditService.java create mode 100644 src/main/java/org/onap/aai/datarouter/util/LoggingUtil.java create mode 100644 src/main/resources/auditservice_validation_schema.json create mode 100644 src/main/resources/auditservice_violation_schema.json create mode 100644 src/main/resources/logging/ServiceIntegrityValidationsMsgs.properties (limited to 'src/main') diff --git a/src/main/java/org/onap/aai/datarouter/entity/POAAuditEvent.java b/src/main/java/org/onap/aai/datarouter/entity/POAAuditEvent.java new file mode 100644 index 0000000..19c4da1 --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/entity/POAAuditEvent.java @@ -0,0 +1,88 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.entity; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.ArrayList; +import java.util.List; +import javax.ws.rs.core.Response.Status; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.datarouter.exception.POAAuditException; +import org.onap.aai.datarouter.logging.DataRouterMsgs; + +/** + * Wrapper class for POMBA rest call message body + * + */ +public class POAAuditEvent +{ + private static final String ATTR_SERVICE_INST_LIST = "serviceInstanceList"; + + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + private List serviceInstanceList = new ArrayList(); + + private static Logger logger = LoggerFactory.getInstance().getLogger(POAAuditEvent.class.getName()); + + public String toJson() { + return gson.toJson(this); + } + + public static POAAuditEvent fromJson(String payload) throws POAAuditException { + if (payload == null || payload.isEmpty()) { + throw new POAAuditException("Invalid Json Payload", Status.BAD_REQUEST); + } + + try { + return gson.fromJson(payload, POAAuditEvent.class); + } catch (Exception ex) { + logger.debug("Invalid Json Payload: " + payload); + throw new POAAuditException("Invalid Json Payload", Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, ex.getMessage()); + } + } + + public List getServiceInstanceList() { + return serviceInstanceList; + } + + public void setServiceInstanceList(List instances) { + this.serviceInstanceList = instances; + } + + + /** + * Validates this service instance list + * @throws POAAuditException if the list is absent or empty + */ + public void validate() throws POAAuditException { + + if((serviceInstanceList == null) || serviceInstanceList.isEmpty()) { + String error = "Missing attribute list: " + ATTR_SERVICE_INST_LIST; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + } + + @Override + public String toString() { + return "AuditEvent [serviceInstances=" + serviceInstanceList + "]"; + } +} diff --git a/src/main/java/org/onap/aai/datarouter/entity/POAServiceInstanceEntity.java b/src/main/java/org/onap/aai/datarouter/entity/POAServiceInstanceEntity.java new file mode 100644 index 0000000..419db87 --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/entity/POAServiceInstanceEntity.java @@ -0,0 +1,173 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.entity; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import javax.ws.rs.core.Response.Status; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.datarouter.exception.POAAuditException; +import org.onap.aai.datarouter.logging.DataRouterMsgs; +import org.onap.aai.datarouter.service.AuditService; + +/** + * This class includes the POMBA rest call message body which triggers the audit process + * + */ +public class POAServiceInstanceEntity +{ + private static final String ATTR_SERVICE_INST_ID = "serviceInstanceId"; + private static final String ATTR_SERVICE_TYPE = "serviceType"; + private static final String ATTR_MODEL_VERSION_ID = "modelVersionId"; + private static final String ATTR_MODEL_INVARIANT_ID = "modelInvariantId"; + private static final String ATTR_CUSTOMER_ID = "customerId"; + + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + private String xFromAppId; + private String xTransactionId; + private String serviceInstanceId; + private String serviceType; + private String modelVersionId; + private String modelInvariantId; + private String customerId; + + private static Logger logger = LoggerFactory.getInstance().getLogger(POAServiceInstanceEntity.class.getName()); + + + public String getxFromAppId() { + return xFromAppId; + } + + public void setxFromAppId(String xFromAppId) { + this.xFromAppId = xFromAppId; + } + + public String getxTransactionId() { + return xTransactionId; + } + + public void setxTransactionId(String xTransactionId) { + this.xTransactionId = xTransactionId; + } + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public String getModelVersionId() { + return modelVersionId; + } + + public void setModelVersionId(String modelVersionId) { + this.modelVersionId = modelVersionId; + } + + public String getModelInvariantId() { + return modelInvariantId; + } + + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + public String getCustomerId() { + return customerId; + } + + public void setCustomerId(String customerId) { + this.customerId = customerId; + } + + + public String toJson() { + return gson.toJson(this); + } + + + public static POAServiceInstanceEntity fromJson(String payload) throws POAAuditException { + + if (payload == null || payload.isEmpty()) { + throw new POAAuditException("Invalid Json Payload", Status.BAD_REQUEST); + } + + try { + return gson.fromJson(payload, POAServiceInstanceEntity.class); + } catch (Exception ex) { + logger.debug("Invalid Json Payload: " + payload); + throw new POAAuditException("Invalid Json Payload", Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, ex.getMessage()); + } + } + + + /** + * Validates this service instance; only the attributes that are expected in request body are verified. + * @throws POAAuditException if the service instance is invalid + */ + public void validate() throws POAAuditException { + + if(serviceInstanceId == null || serviceInstanceId.isEmpty()) { + String error = "Missing attribute: " + ATTR_SERVICE_INST_ID; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + + if(serviceType == null || serviceType.isEmpty()) { + String error = "Missing attribute: " + ATTR_SERVICE_TYPE; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + + if(modelVersionId == null || modelVersionId.isEmpty()) { + String error = "Missing attribute: " + ATTR_MODEL_VERSION_ID; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + + if(modelInvariantId == null || modelInvariantId.isEmpty()) { + String error = "Missing attribute: " + ATTR_MODEL_INVARIANT_ID; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + + if(customerId == null || customerId.isEmpty()) { + String error = "Missing attribute: " + ATTR_CUSTOMER_ID; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + } + + + @Override + public String toString() { + return "ServiceInstance [xFromAppId=" + xFromAppId + ", xTransactionId=" + xTransactionId + + ", serviceInstanceId=" + serviceInstanceId + ", serviceType=" + serviceType + ", modelVersionId=" + + modelVersionId + ", modelInvariantId=" + modelInvariantId + ", customerId=" + customerId + "]"; + } +} diff --git a/src/main/java/org/onap/aai/datarouter/exception/POAAuditException.java b/src/main/java/org/onap/aai/datarouter/exception/POAAuditException.java new file mode 100644 index 0000000..6d99640 --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/exception/POAAuditException.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.exception; + +import javax.ws.rs.core.Response.Status; +import org.onap.aai.datarouter.logging.DataRouterMsgs; + +/** + * This class is to handle the POMBA specific exception + * + */ +public class POAAuditException extends Exception { + + private static final long serialVersionUID = 8162385108397238865L; + + private Status httpStatus; + private DataRouterMsgs logCode; + private String[] logArguments; + + public POAAuditException(String messageForResponse, Status httpStatus) { + super(messageForResponse); + this.setHttpStatus(httpStatus); + } + + public POAAuditException(String message, Status httpStatus, Throwable cause) { + super(message, cause); + this.setHttpStatus(httpStatus); + } + + public POAAuditException(Throwable cause) { + super(cause); + } + + public POAAuditException(String message, Throwable cause) { + super(message, cause); + } + + public POAAuditException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public POAAuditException(String message, Status httpStatus, DataRouterMsgs logCode, String... logArgs) { + super(message); + this.setHttpStatus(httpStatus); + this.logCode = logCode; + logArguments = new String[logArgs.length]; + int i = 0; + for(String arg : logArgs) { + logArguments[i++] = arg; + } + } + + public Status getHttpStatus() { + return httpStatus; + } + + public void setHttpStatus(Status httpStatus) { + this.httpStatus = httpStatus; + } + + public DataRouterMsgs getLogCode() { + return logCode; + } + + public String[] getLogArguments() { + return logArguments; + } +} diff --git a/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java b/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java index 2443993..5a2f3fa 100644 --- a/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java +++ b/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java @@ -1,198 +1,219 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 Amdocs - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.datarouter.logging; - -import com.att.eelf.i18n.EELFResourceManager; - -import org.onap.aai.cl.eelf.LogMessageEnum; - -public enum DataRouterMsgs implements LogMessageEnum { - - /** Data Layer Service started. */ - SERVICE_STARTED, - - /** - * Data Layer Service failed to start. - * Arguments: {0} = Exception message. - */ - STARTUP_FAILURE, - - /** - * File has been changed. - * Arguments: {0} = File name. - */ - FILE_CHANGED, - - /** - * File has been reloaded. - * Arguments: {0} = File name. - */ - FILE_RELOADED, - - /** - * Reports the configuration watcher interval. - * Arguments: {0} = Interval - */ - REPORT_CONFIG_WATCHER_INT, - - /** - * Loading properties file. - * Arguments: {0} = File name. - */ - LOADING_PROPERTIES, - - /** - * Properties file has been loaded. - * Arguments: {0} = File name. - */ - PROPERTIES_LOADED, - - /** - * UEB no events received. - * Arguments: {0} = Topic name - */ - UEB_NO_EVENTS_RECEIVED, - - /** - * Routing policies are being configured. - */ - CONFIGURING_ROUTING_POLICIES, - - /** - * A properties file could not be successfully loaded. - * Arguments: {0} = File name. - */ - LOAD_PROPERTIES_FAILURE, - - /** - * Failed to register for an event topic with UEB. - * Arguments: {0} = Topic {1} = Error reason - */ - UEB_CONNECT_ERR, - - /** - * An error occurred while trying to route a query. - * Arguments: {0} = Query {1} = Error reason - */ - QUERY_ROUTING_ERR, - - /** - * Error in file monitor block. - */ - FILE_MON_BLOCK_ERR, - - /** - * Failure to create a property map. - */ - CREATE_PROPERTY_MAP_ERR, - - /** - * An error occurred reading from a file stream. - */ - FILE_STREAM_ERR, - - /** - * An error occurred while trying to configure a routing policy. - * Arguments: {0} = policy name {1} = source of the routing policy {2} = action of the routing - * policy - */ - ROUTING_POLICY_CONFIGURATION_ERROR, - - /** - * Received request {0} {1} from {2}. Sending response: {3} - * Arguments: {0} = operation {1} = target URL {2} = source {3} = response code - */ - PROCESS_REST_REQUEST, - - /** - * Index {0} may not exist in the search data store. Attempting to create it now. - */ - CREATE_MISSING_INDEX, - - /** - * Processed event {0}. Result: {1} - * Arguments: {0} = event topic {1} = result - */ - PROCESS_EVENT, - - /** - * Arguments: {0} = Error - */ - - BAD_REST_REQUEST, - - /** - * Arguments: {0} = Search index URL {1} = Reason - */ - FAIL_TO_CREATE_SEARCH_INDEX, - - /** - * Arguments: {0} = Successfully created index at endpoint - */ - SEARCH_INDEX_CREATE_SUCCESS, - - INVALID_OXM_FILE, - - INVALID_OXM_DIR, - LOAD_OXM_ERROR, - - /** - * Arguments: {0} = origin payload - */ - INVALID_ORIGIN_PAYLOAD, - - /** - * Arguments: {0} = Origin URL {1} = Target outbound URL - */ - ROUTING_FROM_TO, - - /** - * Arguments: {0} = Target outbound URL, {1} = Response - */ - ROUTING_RESPONSE, - - /** - * Failed to create or update document in index {0}. Cause: {1} - * - * Arguments: - * {0} = Index name - * {1} = Failure cause - */ - FAIL_TO_CREATE_UPDATE_DOC, - - /** - * Arguments: {0} = Operation, {1} = Time in ms - */ - OP_TIME, - - /** Arguments: {0} = Schema file location */ - READING_JSON_SCHEMA_ERROR, - - /** Arguments: {0} = Error message */ - JSON_CONVERSION_ERROR; - - /** - * Static initializer to ensure the resource bundles for this class are loaded... - */ - static { - EELFResourceManager.loadMessageBundle("logging/DataRouterMsgs"); - } -} +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.logging; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +public enum DataRouterMsgs implements LogMessageEnum { + + /** Data Layer Service started. */ + SERVICE_STARTED, + + /** + * Data Layer Service failed to start. + * Arguments: {0} = Exception message. + */ + STARTUP_FAILURE, + + /** + * File has been changed. + * Arguments: {0} = File name. + */ + FILE_CHANGED, + + /** + * File has been reloaded. + * Arguments: {0} = File name. + */ + FILE_RELOADED, + + /** + * Reports the configuration watcher interval. + * Arguments: {0} = Interval + */ + REPORT_CONFIG_WATCHER_INT, + + /** + * Loading properties file. + * Arguments: {0} = File name. + */ + LOADING_PROPERTIES, + + /** + * Properties file has been loaded. + * Arguments: {0} = File name. + */ + PROPERTIES_LOADED, + + /** + * UEB no events received. + * Arguments: {0} = Topic name + */ + UEB_NO_EVENTS_RECEIVED, + + /** + * Routing policies are being configured. + */ + CONFIGURING_ROUTING_POLICIES, + + /** + * A properties file could not be successfully loaded. + * Arguments: {0} = File name. + */ + LOAD_PROPERTIES_FAILURE, + + /** + * Failed to register for an event topic with UEB. + * Arguments: {0} = Topic {1} = Error reason + */ + UEB_CONNECT_ERR, + + /** + * An error occurred while trying to route a query. + * Arguments: {0} = Query {1} = Error reason + */ + QUERY_ROUTING_ERR, + + /** + * Error in file monitor block. + */ + FILE_MON_BLOCK_ERR, + + /** + * Failure to create a property map. + */ + CREATE_PROPERTY_MAP_ERR, + + /** + * An error occurred reading from a file stream. + */ + FILE_STREAM_ERR, + + /** + * An error occurred while trying to configure a routing policy. + * Arguments: {0} = policy name {1} = source of the routing policy {2} = action of the routing + * policy + */ + ROUTING_POLICY_CONFIGURATION_ERROR, + + /** + * Received request {0} {1} from {2}. Sending response: {3} + * Arguments: {0} = operation {1} = target URL {2} = source {3} = response code + */ + PROCESS_REST_REQUEST, + + /** + * Index {0} may not exist in the search data store. Attempting to create it now. + */ + CREATE_MISSING_INDEX, + + /** + * Processed event {0}. Result: {1} + * Arguments: {0} = event topic {1} = result + */ + PROCESS_EVENT, + + /** + * Arguments: {0} = Error + */ + + BAD_REST_REQUEST, + + /** + * Arguments: {0} = Search index URL {1} = Reason + */ + FAIL_TO_CREATE_SEARCH_INDEX, + + /** + * Arguments: {0} = Successfully created index at endpoint + */ + SEARCH_INDEX_CREATE_SUCCESS, + + INVALID_OXM_FILE, + + INVALID_OXM_DIR, + LOAD_OXM_ERROR, + + /** + * Arguments: {0} = origin payload + */ + INVALID_ORIGIN_PAYLOAD, + + /** + * Arguments: {0} = Origin URL {1} = Target outbound URL + */ + ROUTING_FROM_TO, + + /** + * Arguments: {0} = Target outbound URL, {1} = Response + */ + ROUTING_RESPONSE, + + /** + * Failed to create or update document in index {0}. Cause: {1} + * + * Arguments: + * {0} = Index name + * {1} = Failure cause + */ + FAIL_TO_CREATE_UPDATE_DOC, + + /** + * Arguments: {0} = Operation, {1} = Time in ms + */ + OP_TIME, + + /** Arguments: {0} = Schema file location */ + READING_JSON_SCHEMA_ERROR, + + /** Arguments: {0} = Error message */ + JSON_CONVERSION_ERROR, + + /** + * Operation: {0}; URI: {1}; Exception: {2} + */ + EXCEPTION_DURING_METHOD_CALL, + + /** + * Failed to publish {0} event(s) to DMaaP; cause: {1} + * Arguments: {0} = number of events; {1} = cause + */ + FAIL_TO_SEND_TO_DMAAP, + + /** + * Failed to authenticate: {0} + * Arguments: {0} = reason + */ + FAIL_TO_AUTHENTICATE, + + /** + * Invalid value for configuration '{0}'; using default value {1} + * Arguments: {0} config attribute; {1} default value + */ + WARN_USING_DEFAULT; + /** + * Static initializer to ensure the resource bundles for this class are loaded... + */ + static { + EELFResourceManager.loadMessageBundle("logging/DataRouterMsgs"); + } +} diff --git a/src/main/java/org/onap/aai/datarouter/logging/ServiceIntegrityValidationsMsgs.java b/src/main/java/org/onap/aai/datarouter/logging/ServiceIntegrityValidationsMsgs.java new file mode 100644 index 0000000..8d06da4 --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/logging/ServiceIntegrityValidationsMsgs.java @@ -0,0 +1,63 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.logging; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +/** + * ENUM class to handle ElasticSearch validation log message + * + */ +public enum ServiceIntegrityValidationsMsgs implements LogMessageEnum { + + /** + * Arguments: N/A + */ + SI_POLICY_REGISTRATION, + /** + * Arguments: + * {0} = Result + * {1} = Additional information + */ + SI_POLICY_DECISION, + + /** + * {0} = Operation + * {1} = Time for operation to complete + */ + OPERATION_RESULT_ERRORS, + + /** + * Arguments: + * {0} = Payload + * {1} = Error + */ + DOCUMENT_STORE_PAYLOAD_FAILURE; + + + /** + * Static initializer to ensure the resource bundles for this class are loaded... + */ + static { + EELFResourceManager.loadMessageBundle("logging/ServiceIntegrityValidationsMsgs"); + } +} diff --git a/src/main/java/org/onap/aai/datarouter/policy/ServiceIntegrityValidationPolicy.java b/src/main/java/org/onap/aai/datarouter/policy/ServiceIntegrityValidationPolicy.java new file mode 100644 index 0000000..31aa898 --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/policy/ServiceIntegrityValidationPolicy.java @@ -0,0 +1,213 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.policy; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.camel.Exchange; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.Headers; +import org.onap.aai.datarouter.logging.ServiceIntegrityValidationsMsgs; +import org.onap.aai.datarouter.util.SearchServiceAgent; +import org.slf4j.MDC; + +/** + * This class handles the logic which transformers the POA-AUDIT-RESULT event message to the ElasticSearch validation/violation message + * in order to prepare two Json structures, one for validation index and one for violation index and then submit POST request to + * Search-Data-Service to insert the document into ES. + * + */ +public class ServiceIntegrityValidationPolicy { + + private static final String SERVICE_VALIDATION_SCHEMA_FILE = "auditservice_validation_schema.json"; + private static final String SERVICE_VIOLATION_SCHEMA_FILE = "auditservice_violation_schema.json"; + + private static Logger logger = LoggerFactory.getInstance() + .getLogger(ServiceIntegrityValidationPolicy.class.getSimpleName()); + + private static JsonParser jsonParser = new JsonParser(); + + private String validationIndexName = null; + private String violationIndexName = null; + + private SearchServiceAgent searchAgent = null; + + public ServiceIntegrityValidationPolicy(String searchCertPath, + String searchCertTruststore, + String searchCertPassword, + String searchBaseURL, + String endpoint, + String validationIndexName, + String violationIndexName) { + searchAgent = new SearchServiceAgent(searchCertPath, + searchCertTruststore, + searchCertPassword, + concatSubURI(searchBaseURL, endpoint), + "documents", + logger); + + this.validationIndexName = validationIndexName; + this.violationIndexName = violationIndexName; + } + + public void startup(){ + + searchAgent.createSearchIndex(validationIndexName, SERVICE_VALIDATION_SCHEMA_FILE); + searchAgent.createSearchIndex(violationIndexName, SERVICE_VIOLATION_SCHEMA_FILE); + + logger.info(ServiceIntegrityValidationsMsgs.SI_POLICY_REGISTRATION); + } + + public void process(Exchange exchange) throws Exception { + + logger.debug("Invoking ServiceIntegrityViolationPolicy with payload" + exchange.getIn().getBody()); + + String payload = (String)exchange.getIn().getBody(); + + JsonObject serviceValidation = jsonParser.parse(payload).getAsJsonObject(); + JsonElement serviceViolationsElement = serviceValidation.get("violations"); + // Calculate the document id to use for this entity. + JsonElement id = serviceValidation.get("validationId"); + + if(serviceViolationsElement == null || serviceViolationsElement.getAsJsonArray().size() == 0) { + serviceValidation.addProperty("result", "Pass"); + logger.debug("Service integrity validation event processing for event with ID " + id + " as a Pass due to no violations."); + }else { + serviceValidation.addProperty("result", "Fail"); + logger.debug("Service integrity validation event processing for event with ID " + id + " as a Fail due to one or more violations."); + } + + if(serviceViolationsElement != null) { + JsonArray violationsArray = serviceViolationsElement.getAsJsonArray(); + Iterator vit = violationsArray.iterator(); + while(vit.hasNext()) { + JsonObject currentViolation = vit.next().getAsJsonObject(); + JsonObject oldViolationDetails = currentViolation.getAsJsonObject("violationDetails"); + JsonObject newViolationDetails = new JsonObject(); + for (Map.Entry e : oldViolationDetails.entrySet()) { + String oldKey = e.getKey(); + String newKey = oldKey.replace(".","-"); + newViolationDetails.add(newKey,e.getValue()); + } + currentViolation.remove("violationDetails"); + currentViolation.remove("modelName"); + currentViolation.add("violationDetails",newViolationDetails); + logger.debug("new violation:" + currentViolation.toString()); + JsonObject formattedViolation = buildViolation(serviceValidation, currentViolation); + + handleSearchDataServiceOperation(violationIndexName, null, formattedViolation.toString(), "POST"); + + } + } + logger.debug("validation: " + serviceValidation.toString()); + + JsonObject formattedValidation = buildValidation(serviceValidation); + // Persist the entity that we received from the event to the Search Service. + handleSearchDataServiceOperation(validationIndexName, id.getAsString(), formattedValidation.toString(), "PUT"); + + } + + + private JsonObject buildViolation(JsonObject validation, JsonObject violation) { + JsonObject formattedViolation = new JsonObject(); + + formattedViolation.addProperty("validationId", validation.get("validationId").getAsString()); + formattedViolation.addProperty("validationTimestamp", validation.get("validationTimestamp").getAsString()); + formattedViolation.addProperty("modelVersionId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelVersionId").getAsString()); + formattedViolation.addProperty("modelInvariantId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelInvariantId").getAsString()); + formattedViolation.addProperty("serviceInstanceId",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("serviceInstanceId").getAsString()); + + formattedViolation.addProperty("violationId", violation.get("violationId").getAsString()); + formattedViolation.addProperty("violationTimestamp", validation.get("validationTimestamp").getAsString()); + formattedViolation.addProperty("category", violation.get("category").getAsString()); + formattedViolation.addProperty("severity", violation.get("severity").getAsString()); + formattedViolation.addProperty("violationType", violation.get("violationType").getAsString()); + formattedViolation.addProperty("validationRule", violation.get("validationRule").getAsString()); + formattedViolation.addProperty("message", violation.get("errorMessage").getAsString()); + + //formattedViolation.add("violationDetails",violation.get("violationDetails")); + return formattedViolation; + } + + private JsonObject buildValidation(JsonObject validation) { + JsonObject formattedValidation = new JsonObject(); + + formattedValidation.add("violations", validation.get("violations")); + formattedValidation.addProperty("validationId", validation.get("validationId").getAsString()); + formattedValidation.addProperty("validationTimestamp", validation.get("validationTimestamp").getAsString()); + formattedValidation.addProperty("modelVersionId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelVersionId").getAsString()); + formattedValidation.addProperty("modelInvariantId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelInvariantId").getAsString()); + formattedValidation.addProperty("serviceInstanceId",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("serviceInstanceId").getAsString()); + + try { + formattedValidation.addProperty("modelName", validation.get("entity").getAsJsonObject().get("context-list").getAsJsonObject().get("sdc").getAsJsonObject().get("service").getAsJsonObject().get("name").getAsString()); + logger.debug("model name: " + validation.get("entity").getAsJsonObject().get("context-list").getAsJsonObject().get("sdc").getAsJsonObject().get("service").getAsJsonObject().get("name").getAsString()); + }catch (NullPointerException ex){ + ex.printStackTrace(); + formattedValidation.addProperty("modelName",""); + } + + return formattedValidation; + } + + + private static String concatSubURI(String... suburis) { + String finalURI = ""; + + for (String suburi : suburis) { + + if (suburi != null) { + // Remove any leading / since we only want to append / + suburi = suburi.replaceFirst("^/*", ""); + + // Add a trailing / if one isn't already there + finalURI += suburi.endsWith("/") ? suburi : suburi + "/"; + } + } + + return finalURI; + } + + + public void handleSearchDataServiceOperation(String index, String id, String payload, String action) { + + Map> headers = new HashMap<>(); + headers.put(Headers.FROM_APP_ID, Arrays.asList("DataRouter")); + headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID))); + + if (action.equalsIgnoreCase("PUT")) { + searchAgent.putDocument(index, id, payload, headers); + + }else if (action.equalsIgnoreCase("POST")) { + searchAgent.postDocument(index, payload, headers); + } + + } +} diff --git a/src/main/java/org/onap/aai/datarouter/service/AuditService.java b/src/main/java/org/onap/aai/datarouter/service/AuditService.java new file mode 100644 index 0000000..a0ab83c --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/service/AuditService.java @@ -0,0 +1,205 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.Encoded; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.datarouter.entity.POAAuditEvent; +import org.onap.aai.datarouter.entity.POAServiceInstanceEntity; +import org.onap.aai.datarouter.exception.POAAuditException; +import org.onap.aai.datarouter.logging.DataRouterMsgs; +import org.onap.aai.datarouter.util.LoggingUtil; +import org.onap.aai.event.api.EventPublisher; +import org.onap.aai.datarouter.util.DataRouterConstants; +import org.onap.aai.restclient.client.Headers; + + + +public class AuditService { + + private static Logger logger = LoggerFactory.getInstance().getLogger(AuditService.class.getName()); + private static Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(AuditService.class.getName()); + + private static final String MEDIA_TYPE = MediaType.APPLICATION_JSON; + private static final String DATA_ROUTER_APP = "Data-Router"; + private static final String UNKNOWN_APP = "[unknown_app_id]"; + private static final String RESULT_OK = "200 OK"; + + private EventPublisher publisher; + + public AuditService(EventPublisher publisher) throws Exception { + this.publisher = publisher; + } + + + /** + * Handles an incoming post-orchestration audit request. + * Generates and posts audit events to DMaaP. + * + * @param content - JSON structure containing the request payload + * @param uri - Http request uri + * @param headers - Http request headers + * @param uriInfo - Http URI info field + * @param req - Http request structure. + * @return - Standard HTTP response. + * + */ + @POST + @Path("/orchestration-event/") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public Response triggerPOA(String content, + @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo, + @Context HttpServletRequest req) { + + logger.debug("Incoming request..." + content); + Response response = null; + try { + Map headerAttributes = initializeLogging(req, headers); + + List serviceInstanceEvents = generateServiceInstanceEvents(headerAttributes, content); + processEvent(serviceInstanceEvents); + + response = Response.status(Status.OK).entity(RESULT_OK).type(MEDIA_TYPE).build(); + LoggingUtil.logRestRequest(logger, auditLogger, req, response); + + } catch(POAAuditException e) { + response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build(); + LoggingUtil.logRestRequest(logger, auditLogger, req, response, e); + } finally { + LoggingUtil.closeMdc(); + } + return response; + } + + + /** + * Initialize MDC logging using attributes from the request + * @param httpReq + * @param httpHeaders + * @return Returns a map of required header attributes + * @throws POAAuditException + */ + private Map initializeLogging(HttpServletRequest httpReq, HttpHeaders httpHeaders) throws POAAuditException { + + Map headers = new HashMap(); + String remoteAddr = httpReq.getRemoteAddr(); + + if (httpHeaders.getRequestHeaders() == null) { + String error="Missing Header"; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + String transactionId = httpHeaders.getRequestHeaders().getFirst(Headers.TRANSACTION_ID); + if((transactionId == null) || transactionId.trim().isEmpty()) { + transactionId = UUID.randomUUID().toString(); + logger.debug("Header " + Headers.TRANSACTION_ID + "not present in request, generating new value: " + transactionId); + } + headers.put(Headers.TRANSACTION_ID, transactionId); + + String fromAppId = httpHeaders.getRequestHeaders().getFirst(Headers.FROM_APP_ID); + if((fromAppId == null) || fromAppId.trim().isEmpty()) { + // initialize the context before throwing the exception + MdcContext.initialize(transactionId, DataRouterConstants.DATA_ROUTER_SERVICE_NAME, "", UNKNOWN_APP, remoteAddr); + String error = "Missing header attribute: " + Headers.FROM_APP_ID; + throw new POAAuditException(error, Status.BAD_REQUEST, DataRouterMsgs.BAD_REST_REQUEST, error); + } + headers.put(Headers.FROM_APP_ID, fromAppId); + + LoggingUtil.initMdc(transactionId, fromAppId, remoteAddr); + + return headers; + } + + + + /** + * Extracts service instances and generates a list of events + * @param eventHeaders + * @param requestBody + * @return Returns a list of service instances + * @throws POAAuditException if the request contains errors + */ + private List generateServiceInstanceEvents(Map eventHeaders, String requestBody) throws POAAuditException { + + POAAuditEvent auditEvent = POAAuditEvent.fromJson(requestBody); + auditEvent.validate(); + + List eventMessages = new ArrayList(); + for (POAServiceInstanceEntity serviceInstance: auditEvent.getServiceInstanceList()) { + serviceInstance.validate(); + serviceInstance.setxFromAppId(DATA_ROUTER_APP); + serviceInstance.setxTransactionId(eventHeaders.get(Headers.TRANSACTION_ID)); + eventMessages.add(serviceInstance.toJson()); + } + return eventMessages; + } + + + /** + * Publish events to DMaaP. + * @param eventMessages + * @throws POAAuditException + * + * Note: The Default Transport Type in the DMaaPEventPublisher is defined as "HTTPAAF". Based on the deployment of DMaap, currently + * by default the "HTTPAUTH" transport type is supported. + */ + private void processEvent(List eventMessages) throws POAAuditException { + + int messagesSent = 0; + try { + messagesSent = publisher.sendSync(eventMessages); + logger.debug("The number of messages successfully sent: "+ messagesSent); + + if (messagesSent > 0) { + logger.debug("Published Message: " + eventMessages); + } else { + String exceptionStr = String.format("Failed to publish %d event(s) to DMaaP", eventMessages.size()); + logger.debug(exceptionStr); + } + + + } catch (Exception e) { + throw new POAAuditException("Failed to publish event to DMaaP: " + e.getMessage(), Status.INTERNAL_SERVER_ERROR, + DataRouterMsgs.EXCEPTION_DURING_METHOD_CALL, e.getMessage()); + } + + } +} + diff --git a/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java b/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java index 36e4a10..b24f5bd 100644 --- a/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java +++ b/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java @@ -1,58 +1,62 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 Amdocs - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.datarouter.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DataRouterProperties { - - private static final Logger LOGGER = LoggerFactory.getLogger(DataRouterProperties.class); - - private static Properties properties; - - static { - File file = new File(DataRouterConstants.DR_CONFIG_FILE); - loadProperties(file); - } - - static void loadProperties(File file) { - properties = new Properties(); - try (InputStream props = new FileInputStream(file)) { - properties.load(props); - } catch (FileNotFoundException e) { - LOGGER.error("FileNotFoundException: ", e); - } catch (IOException e) { - LOGGER.error("IOException: ", e); - } - } - - public static String get(String key) { - return properties.getProperty(key); - } - -} +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataRouterProperties { + + private static final Logger LOGGER = LoggerFactory.getLogger(DataRouterProperties.class); + + private static Properties properties; + + static { + File file = new File(DataRouterConstants.DR_CONFIG_FILE); + loadProperties(file); + } + + static void loadProperties(File file) { + properties = new Properties(); + try (InputStream props = new FileInputStream(file)) { + properties.load(props); + } catch (FileNotFoundException e) { + LOGGER.error("FileNotFoundException: ", e); + } catch (IOException e) { + LOGGER.error("IOException: ", e); + } + } + + public static String get(String key) { + return properties.getProperty(key); + } + + public static String get(String key, String defaultValue) { + return properties.getProperty(key, defaultValue); + } + +} diff --git a/src/main/java/org/onap/aai/datarouter/util/LoggingUtil.java b/src/main/java/org/onap/aai/datarouter/util/LoggingUtil.java new file mode 100644 index 0000000..2c9a94c --- /dev/null +++ b/src/main/java/org/onap/aai/datarouter/util/LoggingUtil.java @@ -0,0 +1,96 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.datarouter.util; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Response; +import org.onap.aai.cl.api.LogFields; +import org.onap.aai.cl.api.LogLine; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.datarouter.exception.POAAuditException; +import org.onap.aai.datarouter.logging.DataRouterMsgs; +import org.onap.aai.datarouter.util.DataRouterConstants; +import org.slf4j.MDC; + +public class LoggingUtil { + + private static String UNKNOWN = "unknown"; + + /** + * Initializes MDC context. + * Called when request processing begins. + * @param httpReq + * @param headers + */ + public static void initMdc(String transactionId, String fromAppId, String remoteAddr) { + MdcContext.initialize(transactionId, DataRouterConstants.DATA_ROUTER_SERVICE_NAME, "", fromAppId, remoteAddr); + } + + /** + * Clears the MDC context. + * Called when request processing ends. + */ + public static void closeMdc() { + MDC.clear(); + } + + + /** + * Generates error and audit logs + */ + public static void logRestRequest(Logger logger, Logger auditLogger, HttpServletRequest req, Response response) { + logRestRequest(logger, auditLogger, req, response, null); + } + + + /** + * Generates error and audit logs + * @param logger + * @param auditLogger + * @param req + * @param response + * @param exception + */ + public static void logRestRequest(Logger logger, Logger auditLogger, HttpServletRequest req, Response response, POAAuditException exception) { + + String respStatusString = UNKNOWN; + if(Response.Status.fromStatusCode(response.getStatus()) != null) { + respStatusString = Response.Status.fromStatusCode(response.getStatus()).toString(); + } + + LogFields logFields = new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, response.getStatus()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, respStatusString); + + if((exception != null) && (exception.getLogCode() != null)) { + logger.error(exception.getLogCode(), exception.getLogArguments()); + auditLogger.error(exception.getLogCode(), logFields, exception.getLogArguments()); + } + + String status = Integer.toString(response.getStatus()); + String method = (req != null) ? req.getMethod() : UNKNOWN; + String reqUrl = (req != null) ? req.getRequestURL().toString() : UNKNOWN; + String remoteHost = (req != null) ? req.getRemoteHost() : UNKNOWN; + + logger.info(DataRouterMsgs.PROCESS_REST_REQUEST, method, reqUrl, remoteHost, status); + auditLogger.info(DataRouterMsgs.PROCESS_REST_REQUEST, logFields, method, reqUrl, remoteHost, status); + } +} diff --git a/src/main/resources/auditservice_validation_schema.json b/src/main/resources/auditservice_validation_schema.json new file mode 100644 index 0000000..70d6845 --- /dev/null +++ b/src/main/resources/auditservice_validation_schema.json @@ -0,0 +1,20 @@ +{ + "fields": [ + {"name": "validationId", "data-type": "string", "searchable": "false"}, + {"name": "validationTimestamp", "data-type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "modelVersionId", "data-type": "string"}, + {"name": "modelInvariantId", "data-type": "string"}, + {"name": "serviceInstanceId", "data-type": "string"}, + {"name": "result", "data-type": "string"}, + {"name": "violations", "data-type": "nested", "sub-fields": [ + {"name": "violationId", "data-type": "string", "searchable": "false"}, + {"name": "violationTimestamp", "data-type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "modelName", "data-type": "string"}, + {"name": "category", "data-type": "string", "searchable": "false"}, + {"name": "severity", "data-type": "string", "searchable": "false"}, + {"name": "violationType", "data-type": "string", "searchable": "false"}, + {"name": "validationRule", "data-type": "string"}, + {"name": "errorMessage", "data-type": "string"} + ]} + ] +} \ No newline at end of file diff --git a/src/main/resources/auditservice_violation_schema.json b/src/main/resources/auditservice_violation_schema.json new file mode 100644 index 0000000..da88809 --- /dev/null +++ b/src/main/resources/auditservice_violation_schema.json @@ -0,0 +1,16 @@ +{ + "fields": [ + {"name": "validationId", "data-type": "string", "searchable": "false"}, + {"name": "validationTimestamp", "data-type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "modelVersionId", "data-type": "string"}, + {"name": "modelInvariantId", "data-type": "string"}, + {"name": "serviceInstanceId", "data-type": "string"}, + {"name": "violationId", "data-type": "string", "searchable": "false"}, + {"name": "violationTimestamp", "data-type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "category", "data-type": "string", "searchable": "false"}, + {"name": "severity", "data-type": "string", "searchable": "false"}, + {"name": "violationType", "data-type": "string", "searchable": "false"}, + {"name": "validationRule", "data-type": "string"}, + {"name": "message", "data-type": "string"} + ] +} \ No newline at end of file diff --git a/src/main/resources/logging/ServiceIntegrityValidationsMsgs.properties b/src/main/resources/logging/ServiceIntegrityValidationsMsgs.properties new file mode 100644 index 0000000..c8fb270 --- /dev/null +++ b/src/main/resources/logging/ServiceIntegrityValidationsMsgs.properties @@ -0,0 +1,37 @@ +#Resource key=Error Code|Message text|Resolution text |Description text +####### +#Newlines can be utilized to add some clarity ensuring continuing line +#has atleast one leading space +#ResourceKey=\ +# ERR0000E\ +# Sample error msg txt\ +# Sample resolution msg\ +# Sample description txt +# +###### +#Error code classification category +#000 Info/Debug +#100 Permission errors +#200 Availability errors/Timeouts +#300 Data errors +#400 Schema Interface type/validation errors +#500 Business process errors +#900 Unknown errors +# +######################################################################## + +SI_POLICY_REGISTRATION=\ + SI0000I|\ + Service Integrity Validation policy successfully registered. + +SI_POLICY_DECISION=\ + SI0001I|\ + Service Integrity Validation policy resulted in {0}. {1} + +OPERATION_RESULT_ERRORS=\ + SI0002I|\ + Operation {0} completed in {1} ms with some errors + +DOCUMENT_STORE_PAYLOAD_FAILURE=\ + SI0301E|\ + Failed to store Service Integrity Violation event in Document Store. Policy payload: {0} with error: {1} \ No newline at end of file -- cgit 1.2.3-korg