diff options
author | 2018-03-28 17:22:56 +0100 | |
---|---|---|
committer | 2018-03-29 18:38:17 +0100 | |
commit | 837cbcdc2562c0cd041ed558d05bb7dbba4be603 (patch) | |
tree | 370e72f52e0420e0fa633de73a6fd47d03d17422 /src/main/java/org/onap/crud/event | |
parent | 0c19b1386259b7144bc6c95954f965c469835522 (diff) |
Update published event to include header and body
Originally, the published event only contained the raw graph
request payload.
This has now been updated to include the following changes:
- encapsulate the graph request in a body property
- add new event header with details such as timestamp, request-id,
event-type
Issue-ID: AAI-954
Change-Id: I780b6f52a01aafdcd7d09156e9d3a99c25be90a3
Signed-off-by: Michael Arrastia <MArrasti@amdocs.com>
Diffstat (limited to 'src/main/java/org/onap/crud/event')
4 files changed, 525 insertions, 0 deletions
diff --git a/src/main/java/org/onap/crud/event/envelope/GraphEventEnvelope.java b/src/main/java/org/onap/crud/event/envelope/GraphEventEnvelope.java new file mode 100644 index 0000000..13370a2 --- /dev/null +++ b/src/main/java/org/onap/crud/event/envelope/GraphEventEnvelope.java @@ -0,0 +1,130 @@ +/** + * ============LICENSE_START======================================================= + * Gizmo + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.crud.event.envelope; + +import javax.ws.rs.core.Response; +import org.onap.crud.event.GraphEvent; +import org.onap.crud.event.GraphEventEdge; +import org.onap.crud.event.GraphEventVertex; +import org.onap.crud.exception.CrudException; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; + +/** + * Defines the top-level structure of the Gizmo events. Primarily serves as a wrapper for the graph details and includes + * an event header to describe and identify the event. + */ +public class GraphEventEnvelope { + + private GraphEventHeader header; + private GraphEvent body; + private JsonElement policyViolations; + + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); + + /** + * Construct the event. + * + * @param header the event header to describe the event + * @param body the body of the event with graph details + */ + public GraphEventEnvelope(GraphEventHeader header, GraphEvent body) { + this.header = header; + this.body = body; + } + + /** + * Construct the envelope header from the provided GraphEvent. + * + * @param event the graph event for a vertex or edge operation + */ + public GraphEventEnvelope(GraphEvent event) { + this.header = new GraphEventHeader.Builder().requestId(event.getTransactionId()) + .validationEntityType(getType(event)).build(); + this.body = event; + } + + public GraphEvent getBody() { + return body; + } + + public GraphEventHeader getHeader() { + return header; + } + + public JsonElement getPolicyViolations() { + return policyViolations != null ? policyViolations : new JsonArray(); + } + + /** + * Serializes this object into a JSON string representation. + * + * @return a JSON format string representation of this object. + */ + public String toJson() { + return gson.toJson(this); + } + + /** + * Deserializes a JSON string into a GraphEventEnvelope object. + * + * @param json the JSON string + * @return a GraphEventEnvelope object + * @throws CrudException + */ + public static GraphEventEnvelope fromJson(String json) throws CrudException { + try { + if (json == null || json.isEmpty()) { + throw new CrudException("Empty or null JSON string.", Response.Status.BAD_REQUEST); + } + return gson.fromJson(json, GraphEventEnvelope.class); + } catch (Exception ex) { + throw new CrudException("Unable to parse JSON string: " + json, Response.Status.BAD_REQUEST); + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return this.toJson(); + } + + private String getType(GraphEvent event) { + GraphEventVertex vertex = event.getVertex(); + GraphEventEdge edge = event.getEdge(); + if (vertex != null) { + return vertex.getType(); + } else if (edge != null) { + return edge.getType(); + } + return null; + } + +} diff --git a/src/main/java/org/onap/crud/event/envelope/GraphEventHeader.java b/src/main/java/org/onap/crud/event/envelope/GraphEventHeader.java new file mode 100644 index 0000000..f70127d --- /dev/null +++ b/src/main/java/org/onap/crud/event/envelope/GraphEventHeader.java @@ -0,0 +1,197 @@ +/** + * ============LICENSE_START======================================================= + * Gizmo + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.crud.event.envelope; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.Objects; +import java.util.UUID; +import org.apache.commons.lang3.builder.EqualsBuilder; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +public class GraphEventHeader { + + @SerializedName("request-id") + private String requestId; + + private String timestamp; + + @SerializedName("source-name") + private String sourceName; + + @SerializedName("event-type") + private String eventType; + + @SerializedName("validation-entity-type") + private String validationEntityType; + + @SerializedName("validation-top-entity-type") + private String validationTopEntityType; + + @SerializedName("entity-link") + private String entityLink; + + private static final String MICROSERVICE_NAME = "GIZMO"; + private static final String EVENT_TYPE_PENDING_UPDATE = "pending-update"; + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); + + public static class Builder { + + private String requestId; + private String validationEntityType; + private String validationTopEntityType; + private String entityLink; + + public Builder requestId(String val) { + requestId = val; + return this; + } + + public Builder validationEntityType(String val) { + validationEntityType = val; + return this; + } + + public Builder validationTopEntityType(String val) { + validationTopEntityType = val; + return this; + } + + public Builder entityLink(String val) { + entityLink = val; + return this; + } + + public GraphEventHeader build() { + return new GraphEventHeader(this); + } + } + + private GraphEventHeader(Builder builder) { + requestId = builder.requestId != null ? builder.requestId : UUID.randomUUID().toString(); + timestamp = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX").withZone(ZoneOffset.UTC).format(Instant.now()); + sourceName = MICROSERVICE_NAME; + eventType = EVENT_TYPE_PENDING_UPDATE; + + validationEntityType = builder.validationEntityType; + validationTopEntityType = builder.validationTopEntityType; + entityLink = builder.entityLink; + } + + /** + * Serializes this object into a JSON string representation. + * + * @return a JSON format string representation of this object. + */ + public String toJson() { + return gson.toJson(this); + } + + /////////////////////////////////////////////////////////////////////////// + // GETTERS + /////////////////////////////////////////////////////////////////////////// + + public String getRequestId() { + return requestId; + } + + public String getTimestamp() { + return timestamp; + } + + public String getSourceName() { + return sourceName; + } + + public String getEventType() { + return eventType; + } + + public String getValidationEntityType() { + return validationEntityType; + } + + public String getValidationTopEntityType() { + return validationTopEntityType; + } + + public String getEntityLink() { + return entityLink; + } + + /////////////////////////////////////////////////////////////////////////// + // OVERRIDES + /////////////////////////////////////////////////////////////////////////// + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return Objects.hash(this.requestId, this.timestamp, this.sourceName, this.eventType, this.validationEntityType, + this.validationTopEntityType, this.entityLink); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof GraphEventHeader)) { + return false; + } else if (obj == this) { + return true; + } + GraphEventHeader rhs = (GraphEventHeader) obj; + // @formatter:off + return new EqualsBuilder() + .append(requestId, rhs.requestId) + .append(timestamp, rhs.timestamp) + .append(sourceName, rhs.sourceName) + .append(eventType, rhs.sourceName) + .append(validationEntityType, rhs.validationEntityType) + .append(validationTopEntityType, rhs.validationTopEntityType) + .append(entityLink, rhs.entityLink) + .isEquals(); + // @formatter:on + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return this.toJson(); + } + +} diff --git a/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java b/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java new file mode 100644 index 0000000..1fa056e --- /dev/null +++ b/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java @@ -0,0 +1,142 @@ +/** + * ============LICENSE_START======================================================= + * Gizmo + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.crud.event.response; + +import javax.ws.rs.core.Response.Status; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.crud.event.GraphEvent; +import org.onap.crud.event.GraphEvent.GraphEventResult; +import org.onap.crud.event.envelope.GraphEventEnvelope; +import org.onap.crud.exception.CrudException; +import org.onap.crud.logging.CrudServiceMsgs; +import org.onap.crud.parser.CrudResponseBuilder; +import org.onap.schema.OxmModelValidator; +import org.onap.schema.RelationshipSchemaValidator; + +/** + * Reads event responses, logs and generates exceptions if errors are found. + * + */ +public class GraphEventResponseHandler { + + private static Logger logger = LoggerFactory.getInstance().getLogger(GraphEventResponseHandler.class.getName()); + + public String handleVertexResponse(String version, GraphEvent event, GraphEventEnvelope response) + throws CrudException { + handlePolicyViolations(event, response); + logResponse(event, response.getBody()); + + if (isErrorResponse(response.getBody())) { + throwOperationException(response); + } + + return CrudResponseBuilder.buildUpsertVertexResponse( + OxmModelValidator.validateOutgoingPayload(version, response.getBody().getVertex().toVertex()), version); + } + + public String handleEdgeResponse(String version, GraphEvent event, GraphEventEnvelope response) + throws CrudException { + handlePolicyViolations(event, response); + logResponse(event, response.getBody()); + + if (isErrorResponse(response.getBody())) { + throwOperationException(response); + } + + return CrudResponseBuilder.buildUpsertEdgeResponse( + RelationshipSchemaValidator.validateOutgoingPayload(version, response.getBody().getEdge().toEdge()), + version); + } + + public String handleDeletionResponse(GraphEvent event, GraphEventEnvelope response) throws CrudException { + handlePolicyViolations(event, response); + logResponse(event, response.getBody()); + + if (isErrorResponse(response.getBody())) { + throwOperationException(response); + } + + return ""; + } + + public void handleBulkEventResponse(GraphEvent event, GraphEventEnvelope response) throws CrudException { + handlePolicyViolations(event, response); + logResponse(event, response.getBody()); + + if (isErrorResponse(response.getBody())) { + throwOperationException(response); + } + } + + public boolean hasPolicyViolations(GraphEventEnvelope event) { + return event.getPolicyViolations() != null && event.getPolicyViolations().isJsonArray() + && event.getPolicyViolations().getAsJsonArray().size() != 0; + } + + private void handlePolicyViolations(GraphEvent event, GraphEventEnvelope response) throws CrudException { + if (hasPolicyViolations(response)) { + logPolicyViolation(event, response); + throw new CrudException(GraphEventResponseMessage.POLICY_VIOLATION_EXCEPTION_MESSAGE.getMessage( + response.getBody().getTransactionId(), response.getPolicyViolations()), Status.BAD_REQUEST); + } + } + + private void logResponse(GraphEvent event, GraphEvent response) { + String message = GraphEventResponseMessage.BASE_OPERATION_LOG_MESSAGE.getMessage(response.getObjectType(), + response.getObjectKey(), response.getTransactionId(), event.getOperation().toString(), + response.getResult()); + if (isErrorResponse(response)) { + message = GraphEventResponseMessage.OPERATION_ERROR_LOG_MESSAGE.getMessage(message, + response.getErrorMessage()); + } + + logger.info(CrudServiceMsgs.ASYNC_DATA_SERVICE_INFO, message); + } + + private void logPolicyViolation(GraphEvent event, GraphEventEnvelope response) { + //@formatter:off + logger.info(CrudServiceMsgs.ASYNC_DATA_SERVICE_INFO, + GraphEventResponseMessage.POLICY_VIOLATION_LOG_MESSAGE.getMessage( + response.getBody().getTransactionId(), + response.getHeader().getSourceName(), + response.getHeader().getEventType(), + response.getBody().getObjectKey(), + response.getBody().getObjectType(), + event.getOperation().toString(), + response.getPolicyViolations().toString())); + //@formatter:on + } + + private void throwOperationException(GraphEventEnvelope response) throws CrudException { + throw new CrudException( + GraphEventResponseMessage.OPERATION_ERROR_EXCEPTION_MESSAGE + .getMessage(response.getBody().getTransactionId(), response.getBody().getErrorMessage()), + response.getBody().getHttpErrorStatus()); + } + + private boolean isErrorResponse(GraphEvent response) { + return GraphEventResult.FAILURE.equals(response.getResult()); + } +} diff --git a/src/main/java/org/onap/crud/event/response/GraphEventResponseMessage.java b/src/main/java/org/onap/crud/event/response/GraphEventResponseMessage.java new file mode 100644 index 0000000..5e4c6bd --- /dev/null +++ b/src/main/java/org/onap/crud/event/response/GraphEventResponseMessage.java @@ -0,0 +1,56 @@ +/** + * ============LICENSE_START======================================================= + * Gizmo + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.crud.event.response; + +import java.text.MessageFormat; + +/** + * Graph event handling messages, including logging and exceptions. + */ +public enum GraphEventResponseMessage { + + //@formatter:off + BASE_OPERATION_LOG_MESSAGE("Event response received: {0} with key: {1}, transaction-id: {2}, operation: {3}, result: {4}"), + OPERATION_ERROR_LOG_MESSAGE("{0}, error: {1}"), + OPERATION_ERROR_EXCEPTION_MESSAGE("Operation Failed with transaction-id: {0}. Error: {1}"), + POLICY_VIOLATION_LOG_MESSAGE("Event response received: transaction-id: {0}, event source: {1}, event type: {2}, object key: {3}, object type: {4}, operation: {5}, result: policy violations detected in request, error: {6}"), + POLICY_VIOLATION_EXCEPTION_MESSAGE("Operation Failed with transaction-id {0}. Error: policy violations detected in request, {1}"); + //@formatter:on + + private String message; + + private GraphEventResponseMessage(String message) { + this.message = message; + } + + /** + * @param args to be formatted + * @return the formatted error message + */ + public String getMessage(Object... args) { + MessageFormat formatter = new MessageFormat(""); + formatter.applyPattern(this.message); + return formatter.format(args); + } +} |