summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/onap
diff options
context:
space:
mode:
authorArul.Nambi <arul.nambi@amdocs.com>2017-10-12 10:42:00 -0400
committerArul.Nambi <arul.nambi@amdocs.com>2017-10-12 10:42:20 -0400
commit2a5ff133471c5a69b0dfd760d2743f48112da9a0 (patch)
treeb8382df01a396ccf8fdcea4f7328ee4dad29104b /src/main/java/org/onap
parente6be129e4865104321cdd6313f9729c4e7b07d22 (diff)
Renaming openecomp to onap
Issue-ID: AAI-208 Change-Id: Ib5dc63c9b2f4c580caec21414c2fafae904adca9 Signed-off-by: Arul.Nambi <arul.nambi@amdocs.com>
Diffstat (limited to 'src/main/java/org/onap')
-rw-r--r--src/main/java/org/onap/aai/datarouter/entity/AaiEventEntity.java2
-rw-r--r--src/main/java/org/onap/aai/datarouter/entity/AggregationEntity.java2
-rw-r--r--src/main/java/org/onap/aai/datarouter/entity/OxmEntityDescriptor.java2
-rw-r--r--src/main/java/org/onap/aai/datarouter/entity/SuggestionSearchEntity.java10
-rw-r--r--src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java87
-rw-r--r--src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java104
-rw-r--r--src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java207
-rw-r--r--src/main/java/org/onap/aai/datarouter/logging/EntityEventPolicyMsgs.java216
-rw-r--r--src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java1094
-rw-r--r--src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicyConfig.java127
-rw-r--r--src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterConfig.java112
-rw-r--r--src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterDataSourceConfig.java99
-rw-r--r--src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersConfig.java54
-rw-r--r--src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersSchemaUtility.java61
-rw-r--r--src/main/java/org/onap/aai/datarouter/service/EchoService.java95
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/AaiUiSvcPolicyUtil.java75
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/CrossEntityReference.java95
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/DataRouterConstants.java59
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java56
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/EntityOxmReferenceHelper.java60
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/ExternalOxmModelProcessor.java35
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/FileWatcher.java48
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/NodeUtils.java177
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/OxmModelLoader.java139
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/RouterServiceUtil.java271
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/SearchServiceAgent.java366
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/SearchSuggestionPermutation.java98
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/Version.java27
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/VersionedOxmEntities.java347
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/client/NoAuthRestClient.java222
-rw-r--r--src/main/java/org/onap/aai/datarouter/util/client/SvcRoutingRestClient.java52
31 files changed, 4391 insertions, 8 deletions
diff --git a/src/main/java/org/onap/aai/datarouter/entity/AaiEventEntity.java b/src/main/java/org/onap/aai/datarouter/entity/AaiEventEntity.java
index 0391ae3..fafa7ad 100644
--- a/src/main/java/org/onap/aai/datarouter/entity/AaiEventEntity.java
+++ b/src/main/java/org/onap/aai/datarouter/entity/AaiEventEntity.java
@@ -59,7 +59,7 @@ import java.util.List;
import javax.json.Json;
import javax.json.JsonObject;
-import org.openecomp.datarouter.util.NodeUtils;
+import org.onap.aai.datarouter.util.NodeUtils;
/**
* Note: AAIEventEntity is a port forward of IndexDocument Has been renamed here to move forward
diff --git a/src/main/java/org/onap/aai/datarouter/entity/AggregationEntity.java b/src/main/java/org/onap/aai/datarouter/entity/AggregationEntity.java
index 56ef6fd..8a9f5e4 100644
--- a/src/main/java/org/onap/aai/datarouter/entity/AggregationEntity.java
+++ b/src/main/java/org/onap/aai/datarouter/entity/AggregationEntity.java
@@ -29,7 +29,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
-import org.openecomp.datarouter.util.NodeUtils;
+import org.onap.aai.datarouter.util.NodeUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/src/main/java/org/onap/aai/datarouter/entity/OxmEntityDescriptor.java b/src/main/java/org/onap/aai/datarouter/entity/OxmEntityDescriptor.java
index ed8b9fd..54bd081 100644
--- a/src/main/java/org/onap/aai/datarouter/entity/OxmEntityDescriptor.java
+++ b/src/main/java/org/onap/aai/datarouter/entity/OxmEntityDescriptor.java
@@ -24,7 +24,7 @@ package org.onap.aai.datarouter.entity;
import java.util.List;
-import org.openecomp.datarouter.util.CrossEntityReference;
+import org.onap.aai.datarouter.util.CrossEntityReference;
public class OxmEntityDescriptor {
diff --git a/src/main/java/org/onap/aai/datarouter/entity/SuggestionSearchEntity.java b/src/main/java/org/onap/aai/datarouter/entity/SuggestionSearchEntity.java
index bd3c5b7..57ab616 100644
--- a/src/main/java/org/onap/aai/datarouter/entity/SuggestionSearchEntity.java
+++ b/src/main/java/org/onap/aai/datarouter/entity/SuggestionSearchEntity.java
@@ -32,11 +32,11 @@ import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
-import org.openecomp.datarouter.search.filters.config.UiFilterConfig;
-import org.openecomp.datarouter.search.filters.config.UiFiltersConfig;
-import org.openecomp.datarouter.search.filters.config.UiFiltersSchemaUtility;
-import org.openecomp.datarouter.util.NodeUtils;
-import org.openecomp.datarouter.util.SearchSuggestionPermutation;
+import org.onap.aai.datarouter.search.filters.config.UiFilterConfig;
+import org.onap.aai.datarouter.search.filters.config.UiFiltersConfig;
+import org.onap.aai.datarouter.search.filters.config.UiFiltersSchemaUtility;
+import org.onap.aai.datarouter.util.NodeUtils;
+import org.onap.aai.datarouter.util.SearchSuggestionPermutation;
import com.fasterxml.jackson.databind.JsonNode;
diff --git a/src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java b/src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java
new file mode 100644
index 0000000..64ce48b
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java
@@ -0,0 +1,87 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.exception;
+
+/*
+ * COPYRIGHT NOTICE: Copyright (c) 2016 Team Pacifica (Amdocs & AT&T) The contents and intellectual
+ * property contained herein, remain the property of Team Pacifica (Amdocs & AT&T).
+ */
+
+import java.util.Locale;
+
+/**
+ * Base SMAdaptor exception class.
+ */
+public class BaseDataRouterException extends Exception {
+
+ /** Force serialVersionUID. */
+ private static final long serialVersionUID = -6663403070792969748L;
+
+ /** Default locale. */
+ public static final Locale LOCALE = Locale.US;
+
+ /** Exception id. */
+ private final String id;
+
+ /**
+ * Constructor.
+ *
+ * @param id the incoming id.
+ */
+ public BaseDataRouterException(final String id) {
+ super();
+ this.id = id;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id the incoming id
+ * @param message the incoming message
+ */
+ public BaseDataRouterException(final String id, final String message) {
+ super(message);
+ this.id = id;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id the incoming id
+ * @param message the incoming message
+ * @param cause the incoming throwable
+ */
+ public BaseDataRouterException(final String id, final String message, final Throwable cause) {
+ super(message, cause);
+ this.id = id;
+ }
+
+ /**
+ * Get the exception id.
+ *
+ * @return the exception id
+ */
+ public String getId() {
+ return this.id;
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java b/src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java
new file mode 100644
index 0000000..87fc3fc
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java
@@ -0,0 +1,104 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.exception;
+
+/*
+ * COPYRIGHT NOTICE: Copyright (c) 2016 Team Pacifica (Amdocs & AT&T) The contents and intellectual
+ * property contained herein, remain the property of Team Pacifica (Amdocs & AT&T).
+ */
+
+import java.text.MessageFormat;
+
+import javax.ws.rs.core.Response.Status;
+
+/**
+ * DL enum for error conditions.
+ */
+public enum DataRouterError {
+
+ /** Parsing exceptions - Range 100..199. */
+ DL_PARSE_100("DL-100", "Unable to find resource {0} in the model", Status.BAD_REQUEST),
+ DL_PARSE_101("DL-101", "Unable to parse ", Status.BAD_REQUEST),
+ DL_PARSE_102("DL-102", "Sot Filter error: {0} ", Status.INTERNAL_SERVER_ERROR),
+ DL_PARSE_103("DL-103", "URL Parsing error: {0} ", Status.BAD_REQUEST),
+ DL_PARSE_104("DL-104", "Missing Ids filter: {0} ", Status.BAD_REQUEST),
+ DL_PARSE_105("DL-105", "Invalid Ids filter: {0} ", Status.BAD_REQUEST),
+
+ /** Validation exceptions - Range 200..299. */
+ DL_VALIDATION_200("DL-200", "Missing X-TransactionId in header ", Status.BAD_REQUEST),
+
+ /** Other components integration errors - Range 300..399. */
+ DL_INTEGRATION_300("DL-300", "Unable to decorate Graph ", Status.INTERNAL_SERVER_ERROR),
+
+ /** Environment related exceptions - Range 400..499. */
+ DL_ENV_400("DL-400", "Unable to find file {0} ", Status.INTERNAL_SERVER_ERROR),
+ DL_ENV_401("DL-401", "Unable to Load OXM Models", Status.INTERNAL_SERVER_ERROR),
+
+ /** Other components integration errors - Range 500..599. */
+ DL_AUTH_500("DL-500", "Unable to authorize User ", Status.FORBIDDEN);
+
+ /** The error id. */
+ private String id;
+ /** The error message. */
+ private String message;
+ /** The error http return code. */
+ private Status status;
+
+ /**
+ * Constructor.
+ *
+ * @param id the error id
+ * @param message the error message
+ */
+ DataRouterError(final String id, final String message, final Status status) {
+ this.id = id;
+ this.message = message;
+ this.status = status;
+ }
+
+ /**
+ * Get the id.
+ *
+ * @return the error id
+ */
+ public String getId() {
+ return this.id;
+ }
+
+ /**
+ * Get the message.
+ *
+ * @param args the error arguments
+ * @return the error message
+ */
+ public String getMessage(final Object... args) {
+ final MessageFormat formatter = new MessageFormat("");
+ formatter.applyPattern(this.message);
+ return formatter.format(args);
+ }
+
+ public Status getHttpStatus() {
+ return this.status;
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java b/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java
new file mode 100644
index 0000000..6551016
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java
@@ -0,0 +1,207 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+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,
+ /**
+ * Successfully loaded schema: {0}
+ *
+ * <p>Arguments:
+ * {0} = oxm filename
+ */
+ LOADED_OXM_FILE,
+
+ /**
+ * 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");
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/logging/EntityEventPolicyMsgs.java b/src/main/java/org/onap/aai/datarouter/logging/EntityEventPolicyMsgs.java
new file mode 100644
index 0000000..a32216b
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/logging/EntityEventPolicyMsgs.java
@@ -0,0 +1,216 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.logging;
+
+import com.att.eelf.i18n.EELFResourceManager;
+
+import org.onap.aai.cl.eelf.LogMessageEnum;
+
+public enum EntityEventPolicyMsgs implements LogMessageEnum {
+
+ // Error Messages
+ /**
+ * Discarding event.
+ * Arguments:
+ * {0} = reason
+ * {1} = Payload:
+ */
+ DISCARD_AAI_EVENT_VERBOSE,
+
+ /**
+ * Discarding event.
+ * Arguments:
+ * {0} = Reason
+ */
+ DISCARD_AAI_EVENT_NONVERBOSE,
+
+ /**
+ * OXM version: {0} is not supported.
+ * Arguments:
+ * {0} = OXM Version
+ */
+ OXM_VERSION_NOT_SUPPORTED,
+
+ /**
+ * Failed to parse UEB payload.
+ * Arguments:
+ * {0}
+ * {1}
+ */
+ FAILED_TO_PARSE_UEB_PAYLOAD,
+
+ /**
+ * Unable to retrieve etag at {0} for entity with id {1}
+ * Arguments:
+ * {0} = Resource endpoint.
+ * {1} = Entity id.
+ */
+ NO_ETAG_AVAILABLE_FAILURE,
+
+ /**
+ * Failed to update entity {0} with operation {1}.
+ * Arguments:
+ * {0} = Entity
+ * {1} = Operation
+ */
+ FAILED_TO_UPDATE_ENTITY_IN_DOCSTORE,
+
+
+ /**
+ * Action: {0} is not supported.
+ * Argument:
+ * {0} = Operation
+ */
+ ENTITY_OPERATION_NOT_SUPPORTED,
+
+ /**
+ * Arguments:
+ * {0} = reason
+ */
+ DISCARD_UPDATING_SEARCH_SUGGESTION_DATA,
+
+ /**
+ * Discarding topographical data. Reason: {0}. Payload: {1}
+ * Arguments:
+ * {0} = Reason for discarding data.
+ * {1} = Payload
+ */
+ DISCARD_UPDATING_TOPOGRAPHY_DATA_VERBOSE,
+
+ /**
+ * Discarding topographical data. Reason: {0}
+ * Arguments:
+ * {0} = Reason for discarding data.
+ */
+ DISCARD_UPDATING_TOPOGRAPHY_DATA_NONVERBOSE,
+
+ /**
+ * Failed to load OXM Model.
+ */
+ PROCESS_OXM_MODEL_MISSING,
+
+ /**
+ * Failed to create Search index {0} due to: {1}
+ *
+ * Arguments:
+ * {0} = Search index
+ * {1} = Error cause
+ */
+ FAIL_TO_CREATE_SEARCH_INDEX,
+
+ /**
+ * Failed to find OXM version in UEB payload. {0}
+ * Arguments:
+ * {0} = OXM version.
+ */
+ FAILED_TO_FIND_OXM_VERSION,
+
+
+ // Info Messages
+
+ /**
+ * Processing AAI Entity Event Policy:
+ * Arguments:
+ * {0} = Action
+ * {1} = Entity Type
+ * {2} = Payload
+ */
+ PROCESS_AAI_ENTITY_EVENT_POLICY_VERBOSE,
+
+ /**
+ * Processing AAI Entity Event Policy:
+ * Arguments:
+ * {0} = Action
+ * {1} = Entity Type
+ */
+ PROCESS_AAI_ENTITY_EVENT_POLICY_NONVERBOSE,
+
+ /**
+ * Cross Entity Reference synchronization {0}
+ * Arguments:
+ * {0} = Error string
+ *
+ */
+ CROSS_ENTITY_REFERENCE_SYNC,
+
+ /**
+ * Operation {0} completed in {1} ms with no errors
+ * Arguments:
+ * {0} = Operation type
+ * {1} = Time in ms.
+ */
+ OPERATION_RESULT_NO_ERRORS,
+
+ /**
+ * Found OXM model: {0}
+ * Arguments:
+ * {0} = Key pair.
+ */
+ PROCESS_OXM_MODEL_FOUND,
+
+ /**
+ * Successfully created index at {0}
+ *
+ * Arguments:
+ * {0} = Index resource endpoint
+ */
+ SEARCH_INDEX_CREATE_SUCCESS,
+
+ /**
+ * Entity Event Policy component started.
+ */
+ ENTITY_EVENT_POLICY_REGISTERED,
+
+ /**
+ * Arguments:
+ * {0} = Entity name
+ */
+ PRIMARY_KEY_NULL_FOR_ENTITY_TYPE,
+
+ /**
+ * Arguments: {0} = UEB payload
+ */
+ UEB_INVALID_PAYLOAD_JSON_FORMAT,
+
+ /**
+ * Arguments: {0} = Event header
+ */
+ UEB_FAILED_TO_PARSE_PAYLOAD,
+
+ /**
+ * Arguments: {0} = Exception
+ */
+ UEB_FAILED_UEBEVENTHEADER_CONVERSION,
+
+ /**
+ * Arguments: {0} = UEB event header
+ */
+ UEB_EVENT_HEADER_PARSED;
+
+ /**
+ * Static initializer to ensure the resource bundles for this class are loaded...
+ */
+ static {
+ EELFResourceManager.loadMessageBundle("logging/EntityEventPolicyMsgs");
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java
new file mode 100644
index 0000000..7c7965e
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java
@@ -0,0 +1,1094 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.policy;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.internal.helper.DatabaseField;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.onap.aai.datarouter.entity.AaiEventEntity;
+import org.onap.aai.datarouter.entity.AggregationEntity;
+import org.onap.aai.datarouter.entity.DocumentStoreDataEntity;
+import org.onap.aai.datarouter.entity.OxmEntityDescriptor;
+import org.onap.aai.datarouter.entity.SuggestionSearchEntity;
+import org.onap.aai.datarouter.entity.TopographicalEntity;
+import org.onap.aai.datarouter.entity.UebEventHeader;
+import org.onap.aai.datarouter.logging.EntityEventPolicyMsgs;
+import org.onap.aai.datarouter.util.CrossEntityReference;
+import org.onap.aai.datarouter.util.EntityOxmReferenceHelper;
+import org.onap.aai.datarouter.util.ExternalOxmModelProcessor;
+import org.onap.aai.datarouter.util.NodeUtils;
+import org.onap.aai.datarouter.util.OxmModelLoader;
+import org.onap.aai.datarouter.util.RouterServiceUtil;
+import org.onap.aai.datarouter.util.SearchServiceAgent;
+import org.onap.aai.datarouter.util.SearchSuggestionPermutation;
+import org.onap.aai.datarouter.util.Version;
+import org.onap.aai.datarouter.util.VersionedOxmEntities;
+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.restclient.client.OperationResult;
+import org.onap.aai.restclient.rest.HttpUtil;
+import org.slf4j.MDC;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class EntityEventPolicy implements Processor {
+
+ public static final String additionalInfo = "Response of AAIEntityEventPolicy";
+ private static final String entitySearchSchema = "entitysearch_schema.json";
+ private static final String topographicalSearchSchema = "topographysearch_schema.json";
+ private Collection<ExternalOxmModelProcessor> externalOxmModelProcessors;
+
+ private final String EVENT_HEADER = "event-header";
+ private final String ENTITY_HEADER = "entity";
+ private final String ACTION_CREATE = "create";
+ private final String ACTION_DELETE = "delete";
+ private final String ACTION_UPDATE = "update";
+ private final String PROCESS_AAI_EVENT = "Process AAI Event";
+ private final String TOPO_LAT = "latitude";
+ private final String TOPO_LONG = "longitude";
+
+ private final List<String> SUPPORTED_ACTIONS =
+ Arrays.asList(ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE);
+
+ Map<String, DynamicJAXBContext> oxmVersionContextMap = new HashMap<>();
+ private String oxmVersion = null;
+
+ /** Agent for communicating with the Search Service. */
+ private SearchServiceAgent searchAgent = null;
+
+ /** Search index name for storing AAI event entities. */
+ private String entitySearchIndex;
+
+ /** Search index name for storing topographical search data. */
+ private String topographicalSearchIndex;
+
+ /** Search index name for suggestive search data. */
+ private String aggregateGenericVnfIndex;
+
+ private String autosuggestIndex;
+
+ private String srcDomain;
+
+ private Logger logger;
+ private Logger metricsLogger;
+
+ public enum ResponseType {
+ SUCCESS, PARTIAL_SUCCESS, FAILURE;
+ };
+
+ public EntityEventPolicy(EntityEventPolicyConfig config) throws FileNotFoundException {
+ LoggerFactory loggerFactoryInstance = LoggerFactory.getInstance();
+ logger = loggerFactoryInstance.getLogger(EntityEventPolicy.class.getName());
+ metricsLogger = loggerFactoryInstance.getMetricsLogger(EntityEventPolicy.class.getName());
+
+
+ srcDomain = config.getSourceDomain();
+
+ // Populate the index names.
+ entitySearchIndex = config.getSearchEntitySearchIndex();
+ topographicalSearchIndex = config.getSearchTopographySearchIndex();
+ aggregateGenericVnfIndex = config.getSearchAggregationVnfIndex();
+
+ // Instantiate the agent that we will use for interacting with the Search Service.
+ searchAgent = new SearchServiceAgent(config.getSearchCertName(),
+ config.getSearchKeystore(),
+ config.getSearchKeystorePwd(),
+ EntityEventPolicy.concatSubUri(config.getSearchBaseUrl(),
+ config.getSearchEndpoint()),
+ config.getSearchEndpointDocuments(),
+ logger);
+
+ this.externalOxmModelProcessors = new ArrayList<>();
+ this.externalOxmModelProcessors.add(EntityOxmReferenceHelper.getInstance());
+ OxmModelLoader.registerExternalOxmModelProcessors(externalOxmModelProcessors);
+ OxmModelLoader.loadModels();
+ oxmVersionContextMap = OxmModelLoader.getVersionContextMap();
+ parseLatestOxmVersion();
+ }
+
+ private void parseLatestOxmVersion() {
+ int latestVersion = -1;
+ if (oxmVersionContextMap != null) {
+ Iterator it = oxmVersionContextMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pair = (Map.Entry) it.next();
+
+ String version = pair.getKey().toString();
+ int versionNum = Integer.parseInt(version.substring(1, version.length()));
+
+ if (versionNum > latestVersion) {
+ latestVersion = versionNum;
+ oxmVersion = pair.getKey().toString();
+ }
+
+ logger.info(EntityEventPolicyMsgs.PROCESS_OXM_MODEL_FOUND, pair.getKey().toString());
+ }
+ } else {
+ logger.error(EntityEventPolicyMsgs.PROCESS_OXM_MODEL_MISSING, "");
+ }
+ }
+
+ public void startup() {
+
+ // Create the indexes in the search service if they do not already exist.
+ searchAgent.createSearchIndex(entitySearchIndex, entitySearchSchema);
+ searchAgent.createSearchIndex(topographicalSearchIndex, topographicalSearchSchema);
+
+ logger.info(EntityEventPolicyMsgs.ENTITY_EVENT_POLICY_REGISTERED);
+ }
+
+
+ /**
+ * Convert object to json.
+ *
+ * @param object the object
+ * @param pretty the pretty
+ * @return the string
+ * @throws JsonProcessingException the json processing exception
+ */
+ public static String convertObjectToJson(Object object, boolean pretty)
+ throws JsonProcessingException {
+ ObjectWriter ow;
+
+ if (pretty) {
+ ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
+
+ } else {
+ ow = new ObjectMapper().writer();
+ }
+
+ return ow.writeValueAsString(object);
+ }
+
+ public void returnWithError(Exchange exchange, String payload, String errorMsg){
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE, errorMsg);
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE, errorMsg, payload);
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ }
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ long startTime = System.currentTimeMillis();
+
+ String uebPayload = exchange.getIn().getBody().toString();
+
+ JsonNode uebAsJson =null;
+ ObjectMapper mapper = new ObjectMapper();
+ try{
+ uebAsJson = mapper.readTree(uebPayload);
+ } catch (IOException e){
+ returnWithError(exchange, uebPayload, "Invalid Payload");
+ return;
+ }
+
+ // Load the UEB payload data, any errors will result in a failure and discard
+ JSONObject uebObjHeader = getUebContentAsJson(uebPayload, EVENT_HEADER);
+ if (uebObjHeader == null) {
+ returnWithError(exchange, uebPayload, "Payload is missing " + EVENT_HEADER);
+ return;
+ }
+
+ JSONObject uebObjEntity = getUebContentAsJson(uebPayload, ENTITY_HEADER);
+ if (uebObjEntity == null) {
+ returnWithError(exchange, uebPayload, "Payload is missing " + ENTITY_HEADER);
+ return;
+ }
+
+ UebEventHeader eventHeader;
+ eventHeader = initializeUebEventHeader(uebObjHeader.toString());
+
+ // Get src domain from header; discard event if not originated from same domain
+ String payloadSrcDomain = eventHeader.getDomain();
+ if (payloadSrcDomain == null || !payloadSrcDomain.equalsIgnoreCase(this.srcDomain)) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Unrecognized source domain '" + payloadSrcDomain + "'", uebPayload);
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Unrecognized source domain '" + payloadSrcDomain + "'");
+
+ setResponse(exchange, ResponseType.SUCCESS, additionalInfo);
+ return;
+ }
+
+ DynamicJAXBContext oxmJaxbContext = loadOxmContext(oxmVersion.toLowerCase());
+ if (oxmJaxbContext == null) {
+ logger.error(EntityEventPolicyMsgs.OXM_VERSION_NOT_SUPPORTED, oxmVersion);
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE, "OXM version mismatch",
+ uebPayload);
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ String action = eventHeader.getAction();
+ if (action == null || !SUPPORTED_ACTIONS.contains(action.toLowerCase())) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Unrecognized action '" + action + "'", uebPayload);
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Unrecognized action '" + action + "'");
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ String entityType = eventHeader.getEntityType();
+ if (entityType == null) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload header missing entity type", uebPayload);
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload header missing entity type");
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ String topEntityType = eventHeader.getTopEntityType();
+ if (topEntityType == null) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload header missing top entity type", uebPayload);
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload header top missing entity type");
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ String entityLink = eventHeader.getEntityLink();
+ if (entityLink == null) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload header missing entity link", uebPayload);
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload header missing entity link");
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ // log the fact that all data are in good shape
+ logger.info(EntityEventPolicyMsgs.PROCESS_AAI_ENTITY_EVENT_POLICY_NONVERBOSE, action,
+ entityType);
+ logger.debug(EntityEventPolicyMsgs.PROCESS_AAI_ENTITY_EVENT_POLICY_VERBOSE, action, entityType,
+ uebPayload);
+
+
+ // Process for building AaiEventEntity object
+ String[] entityTypeArr = entityType.split("-");
+ String oxmEntityType = "";
+ for (String entityWord : entityTypeArr) {
+ oxmEntityType += entityWord.substring(0, 1).toUpperCase() + entityWord.substring(1);
+ }
+
+ List<String> searchableAttr =
+ getOxmAttributes(uebPayload, oxmJaxbContext, oxmEntityType, entityType, "searchable");
+ if (searchableAttr == null) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Searchable attribute not found for payload entity type '" + entityType + "'");
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Searchable attribute not found for payload entity type '" + entityType + "'",
+ uebPayload);
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ String entityPrimaryKeyFieldName =
+ getEntityPrimaryKeyFieldName(oxmJaxbContext, uebPayload, oxmEntityType, entityType);
+ String entityPrimaryKeyFieldValue = lookupValueUsingKey(uebPayload, entityPrimaryKeyFieldName);
+ if (entityPrimaryKeyFieldValue == null || entityPrimaryKeyFieldValue.isEmpty()) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload missing primary key attribute");
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload missing primary key attribute", uebPayload);
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ AaiEventEntity aaiEventEntity = new AaiEventEntity();
+
+ /*
+ * Use the OXM Model to determine the primary key field name based on the entity-type
+ */
+
+ aaiEventEntity.setEntityPrimaryKeyName(entityPrimaryKeyFieldName);
+ aaiEventEntity.setEntityPrimaryKeyValue(entityPrimaryKeyFieldValue);
+ aaiEventEntity.setEntityType(entityType);
+ aaiEventEntity.setLink(entityLink);
+
+ if (!getSearchTags(aaiEventEntity, searchableAttr, uebPayload, action)) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload missing searchable attribute for entity type '" + entityType + "'");
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload missing searchable attribute for entity type '" + entityType + "'", uebPayload);
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+
+ }
+
+ try {
+ aaiEventEntity.deriveFields();
+
+ } catch (NoSuchAlgorithmException e) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Cannot create unique SHA digest");
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Cannot create unique SHA digest", uebPayload);
+
+ setResponse(exchange, ResponseType.FAILURE, additionalInfo);
+ return;
+ }
+
+ handleSearchServiceOperation(aaiEventEntity, action, entitySearchIndex);
+
+ handleTopographicalData(uebPayload, action, entityType, oxmEntityType, oxmJaxbContext,
+ entityPrimaryKeyFieldName, entityPrimaryKeyFieldValue);
+
+ /*
+ * Use the versioned OXM Entity class to get access to cross-entity reference helper collections
+ */
+ VersionedOxmEntities oxmEntities =
+ EntityOxmReferenceHelper.getInstance().getVersionedOxmEntities(Version.valueOf(oxmVersion));
+
+ /**
+ * NOTES:
+ * 1. If the entity type is "customer", the below check will return true if any nested entityType
+ * in that model could contain a CER based on the OXM model version that has been loaded.
+ * 2. For a DELETE operation on outer/parent entity (handled by the regular flow:
+ * handleSearchServiceOperation()), ignore processing for cross-entity-reference under the
+ * assumption that AAI will push down all required cascade-deletes for nested entities as well
+ * 3. Handling the case where UEB events arrive out of order: CREATE customer is received before
+ * CREATE service-instance.
+ */
+
+ if (!action.equalsIgnoreCase(ACTION_DELETE) && oxmEntities != null
+ && oxmEntities.entityModelContainsCrossEntityReference(topEntityType)) {
+
+ // We know the model "can" contain a CER reference definition, let's process a bit more
+
+ HashMap<String, CrossEntityReference> crossEntityRefMap =
+ oxmEntities.getCrossEntityReferences();
+
+ JSONObject entityJsonObject = getUebEntity(uebPayload);
+
+ JsonNode entityJsonNode = convertToJsonNode(entityJsonObject.toString());
+
+ String parentEntityType = entityType;
+
+ String targetEntityUrl = entityLink;
+
+ for (Map.Entry<String, CrossEntityReference> entry : crossEntityRefMap.entrySet()) {
+
+ /*
+ * if we know service-subscription is in the tree, then we can pull our all instances and
+ * process from there.
+ */
+
+ String key = entry.getKey();
+ CrossEntityReference cerDescriptor = entry.getValue();
+
+ ArrayList<JsonNode> foundNodes = new ArrayList<>();
+
+ RouterServiceUtil.extractObjectsByKey(entityJsonNode, key, foundNodes);
+
+ if (!foundNodes.isEmpty()) {
+
+ for (JsonNode n : foundNodes) {
+ if ("customer".equalsIgnoreCase(parentEntityType)){
+ /*
+ * NOTES:
+ * 1. prepare to hand-create url for service-instance
+ * 2. this will break if the URL structure for service-instance changes
+ */
+ if (n.has("service-type")){
+ targetEntityUrl += "/service-subscriptions/service-subscription/"
+ + RouterServiceUtil.getNodeFieldAsText(n, "service-type")
+ + "/service-instances/service-instance/";
+ }
+
+ }
+
+ List<String> extractedParentEntityAttributeValues = new ArrayList<>();
+
+ RouterServiceUtil.extractFieldValuesFromObject(n, cerDescriptor.getAttributeNames(),
+ extractedParentEntityAttributeValues);
+
+ List<JsonNode> nestedTargetEntityInstances = new ArrayList<>();
+ RouterServiceUtil.extractObjectsByKey(n, cerDescriptor.getTargetEntityType(),
+ nestedTargetEntityInstances);
+
+ for (JsonNode targetEntityInstance : nestedTargetEntityInstances) {
+ /*
+ * Now:
+ * 1. build the AAIEntityType (IndexDocument) based on the extract entity
+ * 2. Get data from ES
+ * 3. Extract ETAG
+ * 4. Merge ES Doc + AAIEntityType + Extracted Parent Cross-Entity-Reference Values
+ * 5. Put data into ES with ETAG + updated doc
+ */
+
+ // Get the complete URL for target entity
+ if (targetEntityInstance.has("link")) { // nested SI has url mentioned
+ targetEntityUrl = RouterServiceUtil.getNodeFieldAsText(targetEntityInstance,
+ "link");
+ } else if ("customer".equalsIgnoreCase(parentEntityType) &&
+ targetEntityInstance.has("service-instance-id")){
+ targetEntityUrl += "/" + RouterServiceUtil.getNodeFieldAsText(targetEntityInstance,
+ "service-instance-id");
+ }
+
+ OxmEntityDescriptor searchableDescriptor =
+ oxmEntities.getSearchableEntityDescriptor(cerDescriptor.getTargetEntityType());
+
+ if (searchableDescriptor != null) {
+
+ if (!searchableDescriptor.getSearchableAttributes().isEmpty()) {
+
+ AaiEventEntity entityToSync = null;
+
+ try {
+
+ entityToSync = getPopulatedEntity(targetEntityInstance, searchableDescriptor);
+
+ /*
+ * Ready to do some ElasticSearch ops
+ */
+
+ for (String parentCrossEntityReferenceAttributeValue : extractedParentEntityAttributeValues) {
+ entityToSync
+ .addCrossEntityReferenceValue(parentCrossEntityReferenceAttributeValue);
+ }
+
+ entityToSync.setLink(targetEntityUrl);
+ entityToSync.deriveFields();
+
+ updateCerInEntity(entityToSync);
+
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ }
+ } else {
+ logger.debug(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC,
+ "failure to find searchable descriptor for type "
+ + cerDescriptor.getTargetEntityType());
+ }
+ }
+
+ }
+
+ } else {
+ logger.debug(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC,
+ "failed to find 0 instances of cross-entity-reference with entity " + key);
+ }
+
+ }
+
+ } else {
+ logger.info(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC, "skipped due to OXM model for "
+ + topEntityType + " does not contain a cross-entity-reference entity");
+ }
+
+ /*
+ * Process for autosuggestable entities
+ */
+ if (oxmEntities != null) {
+ Map<String, OxmEntityDescriptor> rootDescriptor =
+ oxmEntities.getSuggestableEntityDescriptors();
+ if (!rootDescriptor.isEmpty()) {
+ List<String> suggestibleAttrInPayload = new ArrayList<>();
+ List<String> suggestibleAttrInOxm = extractSuggestableAttr(oxmEntities, entityType);
+ if (suggestibleAttrInOxm != null) {
+ for (String attr: suggestibleAttrInOxm){
+ if ( uebObjEntity.has(attr) ){
+ suggestibleAttrInPayload.add(attr);
+ }
+ }
+ }
+
+ if (suggestibleAttrInPayload.isEmpty()) {
+ return;
+ }
+
+ List<String> suggestionAliases = extractAliasForSuggestableEntity(oxmEntities, entityType);
+ AggregationEntity ae = new AggregationEntity();
+ ae.setLink(entityLink);
+ ae.deriveFields(uebAsJson);
+
+ handleSearchServiceOperation(ae, action, aggregateGenericVnfIndex);
+
+ /*
+ * It was decided to silently ignore DELETE requests for resources we don't allow to be
+ * deleted. e.g. auto-suggestion deletion is not allowed while aggregation deletion is.
+ */
+ if (!ACTION_DELETE.equalsIgnoreCase(action)) {
+ List<ArrayList<String>> listOfValidPowerSetElements =
+ SearchSuggestionPermutation.getNonEmptyUniqueLists(suggestibleAttrInPayload);
+
+ // Now we have a list containing the power-set (minus empty element) for the status that are
+ // available in the payload. Try inserting a document for every combination.
+ for (ArrayList<String> list : listOfValidPowerSetElements) {
+ SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity();
+ suggestionSearchEntity.setEntityType(entityType);
+ suggestionSearchEntity.setSuggestableAttr(list);
+ suggestionSearchEntity.setEntityTypeAliases(suggestionAliases);
+ suggestionSearchEntity.setFilterBasedPayloadFromResponse(uebAsJson.get("entity"),
+ suggestibleAttrInOxm, list);
+ suggestionSearchEntity.setSuggestionInputPermutations(
+ suggestionSearchEntity.generateSuggestionInputPermutations());
+
+ if (suggestionSearchEntity.isSuggestableDoc()) {
+ try {
+ suggestionSearchEntity.generateSearchSuggestionDisplayStringAndId();
+ } catch (NoSuchAlgorithmException e) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_UPDATING_SEARCH_SUGGESTION_DATA,
+ "Cannot create unique SHA digest for search suggestion data. Exception: "
+ + e.getLocalizedMessage());
+ }
+
+ handleSearchServiceOperation(suggestionSearchEntity, action, autosuggestIndex);
+ }
+ }
+ }
+ }
+ }
+
+ long stopTime = System.currentTimeMillis();
+
+ metricsLogger.info(EntityEventPolicyMsgs.OPERATION_RESULT_NO_ERRORS, PROCESS_AAI_EVENT,
+ String.valueOf(stopTime - startTime));
+
+ setResponse(exchange, ResponseType.SUCCESS, additionalInfo);
+ return;
+ }
+
+ public List<String> extractSuggestableAttr(VersionedOxmEntities oxmEntities, String entityType) {
+ // Extract suggestable attributeshandleTopographicalData
+ Map<String, OxmEntityDescriptor> rootDescriptor = oxmEntities.getSuggestableEntityDescriptors();
+
+ if (rootDescriptor == null) {
+ return Collections.emptyList();
+ }
+
+ OxmEntityDescriptor desc = rootDescriptor.get(entityType);
+
+ if (desc == null) {
+ return Collections.emptyList();
+ }
+
+ return desc.getSuggestableAttributes();
+ }
+
+ public List<String> extractAliasForSuggestableEntity(VersionedOxmEntities oxmEntities,
+ String entityType) {
+
+ // Extract alias
+ Map<String, OxmEntityDescriptor> rootDescriptor = oxmEntities.getEntityAliasDescriptors();
+
+ if (rootDescriptor == null) {
+ return Collections.emptyList();
+ }
+
+ OxmEntityDescriptor desc = rootDescriptor.get(entityType);
+ return desc.getAlias();
+ }
+
+ private void setResponse(Exchange exchange, ResponseType responseType, String additionalInfo) {
+
+ exchange.getOut().setHeader("ResponseType", responseType.toString());
+ exchange.getOut().setBody(additionalInfo);
+ }
+
+ public void extractDetailsForAutosuggestion(VersionedOxmEntities oxmEntities, String entityType,
+ List<String> suggestableAttr, List<String> alias) {
+
+ // Extract suggestable attributes
+ Map<String, OxmEntityDescriptor> rootDescriptor = oxmEntities.getSuggestableEntityDescriptors();
+
+ OxmEntityDescriptor desc = rootDescriptor.get(entityType);
+ suggestableAttr = desc.getSuggestableAttributes();
+
+ // Extract alias
+ rootDescriptor = oxmEntities.getEntityAliasDescriptors();
+ desc = rootDescriptor.get(entityType);
+ alias = desc.getAlias();
+ }
+
+ /*
+ * Load the UEB JSON payload, any errors would result to a failure case response.
+ */
+ private JSONObject getUebContentAsJson(String payload, String contentKey) {
+
+ JSONObject uebJsonObj;
+ JSONObject uebObjContent;
+
+ try {
+ uebJsonObj = new JSONObject(payload);
+ } catch (JSONException e) {
+ logger.debug(EntityEventPolicyMsgs.UEB_INVALID_PAYLOAD_JSON_FORMAT, payload);
+ logger.error(EntityEventPolicyMsgs.UEB_INVALID_PAYLOAD_JSON_FORMAT, payload);
+ return null;
+ }
+
+ if (uebJsonObj.has(contentKey)) {
+ uebObjContent = uebJsonObj.getJSONObject(contentKey);
+ } else {
+ logger.debug(EntityEventPolicyMsgs.UEB_FAILED_TO_PARSE_PAYLOAD, contentKey);
+ logger.error(EntityEventPolicyMsgs.UEB_FAILED_TO_PARSE_PAYLOAD, contentKey);
+ return null;
+ }
+
+ return uebObjContent;
+ }
+
+
+ private UebEventHeader initializeUebEventHeader(String payload) {
+
+ UebEventHeader eventHeader = null;
+ ObjectMapper mapper = new ObjectMapper();
+
+ // Make sure that were were actually passed in a valid string.
+ if (payload == null || payload.isEmpty()) {
+ logger.debug(EntityEventPolicyMsgs.UEB_FAILED_TO_PARSE_PAYLOAD, EVENT_HEADER);
+ logger.error(EntityEventPolicyMsgs.UEB_FAILED_TO_PARSE_PAYLOAD, EVENT_HEADER);
+
+ return eventHeader;
+ }
+
+ // Marshal the supplied string into a UebEventHeader object.
+ try {
+ eventHeader = mapper.readValue(payload, UebEventHeader.class);
+ } catch (JsonProcessingException e) {
+ logger.error(EntityEventPolicyMsgs.UEB_FAILED_UEBEVENTHEADER_CONVERSION, e.toString());
+ } catch (Exception e) {
+ logger.error(EntityEventPolicyMsgs.UEB_FAILED_UEBEVENTHEADER_CONVERSION, e.toString());
+ }
+
+ if (eventHeader != null) {
+ logger.debug(EntityEventPolicyMsgs.UEB_EVENT_HEADER_PARSED, eventHeader.toString());
+ }
+
+ return eventHeader;
+
+ }
+
+
+ private String getEntityPrimaryKeyFieldName(DynamicJAXBContext oxmJaxbContext, String payload,
+ String oxmEntityType, String entityType) {
+
+ DynamicType entity = oxmJaxbContext.getDynamicType(oxmEntityType);
+ if (entity == null) {
+ return null;
+ }
+
+ List<DatabaseField> list = entity.getDescriptor().getPrimaryKeyFields();
+ if (list != null && !list.isEmpty()) {
+ String keyName = list.get(0).getName();
+ return keyName.substring(0, keyName.indexOf('/'));
+ }
+
+ return "";
+ }
+
+ private String lookupValueUsingKey(String payload, String key) throws JSONException {
+ JsonNode jsonNode = convertToJsonNode(payload);
+ return RouterServiceUtil.recursivelyLookupJsonPayload(jsonNode, key);
+ }
+
+ private JsonNode convertToJsonNode(String payload) {
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = null;
+ try {
+ jsonNode = mapper.readTree(mapper.getJsonFactory().createJsonParser(payload));
+ } catch (IOException e) {
+ logger.debug(EntityEventPolicyMsgs.FAILED_TO_PARSE_UEB_PAYLOAD, ENTITY_HEADER + " missing",
+ payload);
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_PARSE_UEB_PAYLOAD, ENTITY_HEADER + " missing",
+ "");
+ }
+
+ return jsonNode;
+ }
+
+ private boolean getSearchTags(AaiEventEntity aaiEventEntity, List<String> searchableAttr,
+ String payload, String action) {
+
+ boolean hasSearchableAttr = false;
+ for (String searchTagField : searchableAttr) {
+ String searchTagValue;
+ if (searchTagField.equalsIgnoreCase(aaiEventEntity.getEntityPrimaryKeyName())) {
+ searchTagValue = aaiEventEntity.getEntityPrimaryKeyValue();
+ } else {
+ searchTagValue = this.lookupValueUsingKey(payload, searchTagField);
+ }
+
+ if (searchTagValue != null && !searchTagValue.isEmpty()) {
+ hasSearchableAttr = true;
+ aaiEventEntity.addSearchTagWithKey(searchTagValue, searchTagField);
+ }
+ }
+ return hasSearchableAttr;
+ }
+
+ /*
+ * Check if OXM version is available. If available, load it.
+ */
+ private DynamicJAXBContext loadOxmContext(String version) {
+ if (version == null) {
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_FIND_OXM_VERSION, version);
+ return null;
+ }
+
+ return oxmVersionContextMap.get(version);
+ }
+
+ private List<String> getOxmAttributes(String payload, DynamicJAXBContext oxmJaxbContext,
+ String oxmEntityType, String entityType, String fieldName) {
+
+ DynamicType entity = (DynamicType) oxmJaxbContext.getDynamicType(oxmEntityType);
+ if (entity == null) {
+ return null;
+ }
+
+ /*
+ * Check for searchable XML tag
+ */
+ List<String> fieldValues = null;
+ Map<String, String> properties = entity.getDescriptor().getProperties();
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase(fieldName)) {
+ fieldValues = Arrays.asList(entry.getValue().split(","));
+ break;
+ }
+ }
+
+ return fieldValues;
+ }
+
+ private JSONObject getUebEntity(String payload) {
+ JSONObject uebJsonObj;
+
+ try {
+ uebJsonObj = new JSONObject(payload);
+ } catch (JSONException e) {
+ logger.debug(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_VERBOSE,
+ "Payload has invalid JSON Format", payload.toString());
+ logger.error(EntityEventPolicyMsgs.DISCARD_AAI_EVENT_NONVERBOSE,
+ "Payload has invalid JSON Format");
+ return null;
+ }
+
+ if (uebJsonObj.has(ENTITY_HEADER)) {
+ return uebJsonObj.getJSONObject(ENTITY_HEADER);
+ } else {
+ logger.debug(EntityEventPolicyMsgs.FAILED_TO_PARSE_UEB_PAYLOAD, ENTITY_HEADER + " missing",
+ payload.toString());
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_PARSE_UEB_PAYLOAD, ENTITY_HEADER + " missing");
+ return null;
+ }
+ }
+
+ protected AaiEventEntity getPopulatedEntity(JsonNode entityNode,
+ OxmEntityDescriptor resultDescriptor) {
+ AaiEventEntity d = new AaiEventEntity();
+
+ d.setEntityType(resultDescriptor.getEntityName());
+
+ List<String> primaryKeyValues = new ArrayList<>();
+ List<String> primaryKeyNames = new ArrayList<>();
+ String pkeyValue;
+
+ for (String keyName : resultDescriptor.getPrimaryKeyAttributeName()) {
+ pkeyValue = RouterServiceUtil.getNodeFieldAsText(entityNode, keyName);
+ if (pkeyValue != null) {
+ primaryKeyValues.add(pkeyValue);
+ primaryKeyNames.add(keyName);
+ } else {
+ // logger.warn("getPopulatedDocument(), pKeyValue is null for entityType = " +
+ // resultDescriptor.getEntityName());
+ logger.error(EntityEventPolicyMsgs.PRIMARY_KEY_NULL_FOR_ENTITY_TYPE,
+ resultDescriptor.getEntityName());
+ }
+ }
+
+ final String primaryCompositeKeyValue = RouterServiceUtil.concatArray(primaryKeyValues, "/");
+ d.setEntityPrimaryKeyValue(primaryCompositeKeyValue);
+ final String primaryCompositeKeyName = RouterServiceUtil.concatArray(primaryKeyNames, "/");
+ d.setEntityPrimaryKeyName(primaryCompositeKeyName);
+
+ final List<String> searchTagFields = resultDescriptor.getSearchableAttributes();
+
+ /*
+ * Based on configuration, use the configured field names for this entity-Type to build a
+ * multi-value collection of search tags for elastic search entity search criteria.
+ */
+
+
+ for (String searchTagField : searchTagFields) {
+ String searchTagValue = RouterServiceUtil.getNodeFieldAsText(entityNode, searchTagField);
+ if (searchTagValue != null && !searchTagValue.isEmpty()) {
+ d.addSearchTagWithKey(searchTagValue, searchTagField);
+ }
+ }
+
+ return d;
+ }
+
+ private void updateCerInEntity(AaiEventEntity aaiEventEntity) {
+ try {
+ Map<String, List<String>> headers = new HashMap<>();
+ headers.put(Headers.FROM_APP_ID, Arrays.asList("Data Router"));
+ headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
+
+ String entityId = aaiEventEntity.getId();
+ String jsonPayload;
+
+ // Run the GET to retrieve the ETAG from the search service
+ OperationResult storedEntity = searchAgent.getDocument(entitySearchIndex, entityId);
+
+ if (HttpUtil.isHttpResponseClassSuccess(storedEntity.getResultCode())) {
+ /*
+ * NOTES: aaiEventEntity (ie the nested entity) may contain a subset of properties of
+ * the pre-existing object,
+ * so all we want to do is update the CER on the pre-existing object (if needed).
+ */
+
+ List<String> etag = storedEntity.getHeaders().get(Headers.ETAG);
+
+ if (etag != null && !etag.isEmpty()) {
+ headers.put(Headers.IF_MATCH, etag);
+ } else {
+ logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE,
+ entitySearchIndex, entityId);
+ }
+
+ ArrayList<JsonNode> sourceObject = new ArrayList<>();
+ NodeUtils.extractObjectsByKey(
+ NodeUtils.convertJsonStrToJsonNode(storedEntity.getResult()),
+ "content", sourceObject);
+
+ if (!sourceObject.isEmpty()) {
+ JsonNode node = sourceObject.get(0);
+ final String sourceCer = NodeUtils.extractFieldValueFromObject(node,
+ "crossEntityReferenceValues");
+ String newCer = aaiEventEntity.getCrossReferenceEntityValues();
+ boolean hasNewCer = true;
+ if (sourceCer != null && sourceCer.length() > 0){ // already has CER
+ if ( !sourceCer.contains(newCer)){//don't re-add
+ newCer = sourceCer + ";" + newCer;
+ } else {
+ hasNewCer = false;
+ }
+ }
+
+ if (hasNewCer){
+ // Do the PUT with new CER
+ ((ObjectNode)node).put("crossEntityReferenceValues", newCer);
+ jsonPayload = NodeUtils.convertObjectToJson(node, false);
+ searchAgent.putDocument(entitySearchIndex, entityId, jsonPayload, headers);
+ }
+ }
+ } else {
+
+ if (storedEntity.getResultCode() == 404) {
+ // entity not found, so attempt to do a PUT
+ searchAgent.putDocument(entitySearchIndex, entityId, aaiEventEntity.getAsJson(), headers);
+ } else {
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_UPDATE_ENTITY_IN_DOCSTORE,
+ aaiEventEntity.getId(), "SYNC_ENTITY");
+ }
+ }
+ } catch (IOException e) {
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_UPDATE_ENTITY_IN_DOCSTORE,
+ aaiEventEntity.getId(), "SYNC_ENTITY");
+ }
+ }
+
+ /**
+ * Perform create, read, update or delete (CRUD) operation on search engine's suggestive search
+ * index
+ *
+ * @param eventEntity Entity/data to use in operation
+ * @param action The operation to perform
+ * @param target Resource to perform the operation on
+ * @param allowDeleteEvent Allow delete operation to be performed on resource
+ */
+ protected void handleSearchServiceOperation(DocumentStoreDataEntity eventEntity,
+ String action,
+ String index) {
+ try {
+
+ Map<String, List<String>> headers = new HashMap<>();
+ headers.put(Headers.FROM_APP_ID, Arrays.asList("DataLayer"));
+ headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
+
+ String entityId = eventEntity.getId();
+
+ // System.out.println("aaiEventEntity as json = " + aaiEventEntity.getAsJson());
+
+ if ((action.equalsIgnoreCase(ACTION_CREATE) && entityId != null)
+ || action.equalsIgnoreCase(ACTION_UPDATE)) {
+
+ // Run the GET to retrieve the ETAG from the search service
+ OperationResult storedEntity = searchAgent.getDocument(index, entityId);
+
+ if (HttpUtil.isHttpResponseClassSuccess(storedEntity.getResultCode())) {
+ List<String> etag = storedEntity.getHeaders().get(Headers.ETAG);
+
+ if (etag != null && !etag.isEmpty()) {
+ headers.put(Headers.IF_MATCH, etag);
+ } else {
+ logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE, index,
+ entityId);
+ }
+ }
+
+ // Write the entity to the search service.
+ // PUT
+ searchAgent.putDocument(index, entityId, eventEntity.getAsJson(), headers);
+ } else if (action.equalsIgnoreCase(ACTION_CREATE)) {
+ // Write the entry to the search service.
+ searchAgent.postDocument(index, eventEntity.getAsJson(), headers);
+
+ } else if (action.equalsIgnoreCase(ACTION_DELETE)) {
+ // Run the GET to retrieve the ETAG from the search service
+ OperationResult storedEntity = searchAgent.getDocument(index, entityId);
+
+ if (HttpUtil.isHttpResponseClassSuccess(storedEntity.getResultCode())) {
+ List<String> etag = storedEntity.getHeaders().get(Headers.ETAG);
+
+ if (etag != null && !etag.isEmpty()) {
+ headers.put(Headers.IF_MATCH, etag);
+ } else {
+ logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE, index,
+ entityId);
+ }
+
+ searchAgent.deleteDocument(index, eventEntity.getId(), headers);
+ } else {
+ logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE, index,
+ entityId);
+ }
+ } else {
+ logger.error(EntityEventPolicyMsgs.ENTITY_OPERATION_NOT_SUPPORTED, action);
+ }
+ } catch (IOException e) {
+ logger.error(EntityEventPolicyMsgs.FAILED_TO_UPDATE_ENTITY_IN_DOCSTORE, eventEntity.getId(),
+ action);
+ }
+ }
+
+ private void handleTopographicalData(String payload, String action, String entityType,
+ String oxmEntityType, DynamicJAXBContext oxmJaxbContext, String entityPrimaryKeyFieldName,
+ String entityPrimaryKeyFieldValue) {
+
+ Map<String, String> topoData = new HashMap<>();
+ String entityLink;
+ List<String> topographicalAttr =
+ getOxmAttributes(payload, oxmJaxbContext, oxmEntityType, entityType, "geoProps");
+ if (topographicalAttr == null) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_UPDATING_TOPOGRAPHY_DATA_NONVERBOSE,
+ "Topograhical attribute not found for payload entity type '" + entityType + "'");
+ logger.debug(EntityEventPolicyMsgs.DISCARD_UPDATING_TOPOGRAPHY_DATA_VERBOSE,
+ "Topograhical attribute not found for payload entity type '" + entityType + "'",
+ payload);
+ } else {
+ entityLink = lookupValueUsingKey(payload, "entity-link");
+ for (String topoAttr : topographicalAttr) {
+ topoData.put(topoAttr, lookupValueUsingKey(payload, topoAttr));
+ }
+ updateTopographicalSearchDb(topoData, entityType, action, entityPrimaryKeyFieldName,
+ entityPrimaryKeyFieldValue, entityLink);
+ }
+
+ }
+
+ private void updateTopographicalSearchDb(Map<String, String> topoData, String entityType,
+ String action, String entityPrimaryKeyName, String entityPrimaryKeyValue, String entityLink) {
+
+ TopographicalEntity topoEntity = new TopographicalEntity();
+ topoEntity.setEntityPrimaryKeyName(entityPrimaryKeyName);
+ topoEntity.setEntityPrimaryKeyValue(entityPrimaryKeyValue);
+ topoEntity.setEntityType(entityType);
+ topoEntity.setLatitude(topoData.get(TOPO_LAT));
+ topoEntity.setLongitude(topoData.get(TOPO_LONG));
+ topoEntity.setSelfLink(entityLink);
+ try {
+ topoEntity.setId(TopographicalEntity.generateUniqueShaDigest(entityType, entityPrimaryKeyName,
+ entityPrimaryKeyValue));
+ } catch (NoSuchAlgorithmException e) {
+ logger.error(EntityEventPolicyMsgs.DISCARD_UPDATING_TOPOGRAPHY_DATA_VERBOSE,
+ "Cannot create unique SHA digest for topographical data.");
+ }
+
+ this.handleSearchServiceOperation(topoEntity, action, topographicalSearchIndex);
+ }
+
+
+ // put this here until we find a better spot
+ /**
+ * Helper utility to concatenate substrings of a URI together to form a proper URI.
+ *
+ * @param suburis the list of substrings to concatenate together
+ * @return the concatenated list of substrings
+ */
+ public 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;
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicyConfig.java b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicyConfig.java
new file mode 100644
index 0000000..ac81466
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicyConfig.java
@@ -0,0 +1,127 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.policy;
+
+public class EntityEventPolicyConfig {
+
+ private String sourceDomain;
+ private String searchBaseUrl;
+ private String searchEndpoint;
+ private String searchEndpointDocuments;
+ private String searchEntitySearchIndex;
+ private String searchTopographySearchIndex;
+ private String searchEntityAutoSuggestIndex;
+ private String searchAggregationVnfIndex;
+ private String searchCertName;
+ private String searchKeystorePwd;
+ private String searchKeystore;
+
+
+ public String getSourceDomain() {
+ return sourceDomain;
+ }
+
+ public void setSourceDomain(String sourceDomain) {
+ this.sourceDomain = sourceDomain;
+ }
+
+ public String getSearchBaseUrl() {
+ return searchBaseUrl;
+ }
+
+ public void setSearchBaseUrl(String searchBaseUrl) {
+ this.searchBaseUrl = searchBaseUrl;
+ }
+
+ public String getSearchEndpoint() {
+ return searchEndpoint;
+ }
+
+ public void setSearchEndpoint(String searchEndpoint) {
+ this.searchEndpoint = searchEndpoint;
+ }
+
+ public String getSearchEndpointDocuments() {
+ return searchEndpointDocuments;
+ }
+
+ public void setSearchEndpointDocuments(String searchEndpointDocuments) {
+ this.searchEndpointDocuments = searchEndpointDocuments;
+ }
+
+ public String getSearchEntitySearchIndex() {
+ return searchEntitySearchIndex;
+ }
+
+ public void setSearchEntitySearchIndex(String searchEntitySearchIndex) {
+ this.searchEntitySearchIndex = searchEntitySearchIndex;
+ }
+
+ public String getSearchTopographySearchIndex() {
+ return searchTopographySearchIndex;
+ }
+
+ public void setSearchTopographySearchIndex(String searchTopographySearchIndex) {
+ this.searchTopographySearchIndex = searchTopographySearchIndex;
+ }
+
+ public String getSearchEntityAutoSuggestIndex() {
+ return searchEntityAutoSuggestIndex;
+ }
+
+ public void setSearchEntityAutoSuggestIndex(String autoSuggestibleSearchEntitySearchIndex) {
+ this.searchEntityAutoSuggestIndex = autoSuggestibleSearchEntitySearchIndex;
+ }
+
+ public String getSearchCertName() {
+ return searchCertName;
+ }
+
+ public void setSearchCertName(String searchCertName) {
+ this.searchCertName = searchCertName;
+ }
+
+ public String getSearchKeystore() {
+ return searchKeystore;
+ }
+
+ public void setSearchKeystore(String searchKeystore) {
+ this.searchKeystore = searchKeystore;
+ }
+
+ public String getSearchKeystorePwd() {
+ return searchKeystorePwd;
+ }
+
+ public void setSearchKeystorePwd(String searchKeystorePwd) {
+ this.searchKeystorePwd = searchKeystorePwd;
+ }
+
+ public String getSearchAggregationVnfIndex() {
+ return searchAggregationVnfIndex;
+ }
+
+ public void setSearchAggregationVnfIndex(String searchAggregationVnfIndex) {
+ this.searchAggregationVnfIndex = searchAggregationVnfIndex;
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterConfig.java b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterConfig.java
new file mode 100644
index 0000000..dbef742
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterConfig.java
@@ -0,0 +1,112 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.search.filters.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonInclude(Include.NON_NULL)
+public class UiFilterConfig {
+
+ @JsonProperty("filterId")
+ private String filterId;
+
+ @JsonProperty("filterName")
+ private String filterName;
+
+ @JsonProperty("displayName")
+ private String displayName;
+
+ @JsonProperty("dataType")
+ private String dataType;
+
+ @JsonProperty("dataSource")
+ private UiFilterDataSourceConfig dataSource = new UiFilterDataSourceConfig();
+
+ @JsonCreator
+ public UiFilterConfig(@JsonProperty("filterId") final String filterId,
+ @JsonProperty("filterName") final String filterName,
+ @JsonProperty("displayName") final String displayName,
+ @JsonProperty("dataType") final String dataType,
+ @JsonProperty("dataSource") final UiFilterDataSourceConfig dataSource
+ ) {
+ this.filterId = filterId;
+ this.filterName = filterName;
+ this.displayName = displayName;
+ this.dataType = dataType;
+ this.dataSource = dataSource;
+ }
+
+ @JsonProperty("filterId")
+ public String getFilterId() {
+ return filterId;
+ }
+
+ public void setFilterId(String filterId) {
+ this.filterId = filterId;
+ }
+
+ @JsonProperty("filterName")
+ public String getFilterName() {
+ return filterName;
+ }
+
+ public void setFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ @JsonProperty("displayName")
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ @JsonProperty("dataType")
+ public String getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(String dataType) {
+ this.dataType = dataType;
+ }
+
+ @JsonProperty("dataSource")
+ public UiFilterDataSourceConfig getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(UiFilterDataSourceConfig dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ @Override
+ public String toString() {
+ return "UiFilterConfig [filterId=" + filterId + ", filterName=" + filterName + ", displayName="
+ + displayName + ", dataType=" + dataType + ", dataSource=" + dataSource + "]";
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterDataSourceConfig.java b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterDataSourceConfig.java
new file mode 100644
index 0000000..812d456
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFilterDataSourceConfig.java
@@ -0,0 +1,99 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.search.filters.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonInclude(Include.NON_NULL)
+public class UiFilterDataSourceConfig {
+
+ @JsonProperty("indexName")
+ private String indexName;
+
+ @JsonProperty("docType")
+ private String docType;
+
+ @JsonProperty("fieldName")
+ private String fieldName;
+
+ @JsonProperty("pathToField")
+ private String pathToField;
+
+ public UiFilterDataSourceConfig(){}
+
+ @JsonCreator
+ public UiFilterDataSourceConfig(
+ @JsonProperty("indexName") final String indexName, @JsonProperty("docType") final String docType,
+ @JsonProperty("fieldName") final String fieldName, @JsonProperty("pathToField") final String pathToField) {
+ this.indexName = indexName;
+ this.docType = docType;
+ this.fieldName = fieldName;
+ this.pathToField = pathToField;
+ }
+
+ @JsonProperty("indexName")
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public void setIndexName(String indexName) {
+ this.indexName = indexName;
+ }
+
+ @JsonProperty("docType")
+ public String getDocType() {
+ return docType;
+ }
+
+ public void setDocType(String docType) {
+ this.docType = docType;
+ }
+
+ @JsonProperty("fieldName")
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public void setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ @JsonProperty("pathToField")
+ public String getPathToField() {
+ return pathToField;
+ }
+
+ public void setPathToField(String pathToField) {
+ this.pathToField = pathToField;
+ }
+
+ @Override
+ public String toString() {
+ return "UiFilterDataSourceConfig [indexName=" + indexName + ", docType=" + docType
+ + ", fieldName=" + fieldName + ", pathToField=" + pathToField + "]";
+ }
+}
+
diff --git a/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersConfig.java b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersConfig.java
new file mode 100644
index 0000000..870a5c0
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersConfig.java
@@ -0,0 +1,54 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.search.filters.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class UiFiltersConfig {
+ @JsonProperty("filters")
+ private List<UiFilterConfig> filters = new ArrayList<>();
+
+ public UiFiltersConfig() {}
+
+ @JsonCreator
+ public UiFiltersConfig(@JsonProperty("filters") final List<UiFilterConfig> filters) {
+ this.filters = filters;
+ }
+
+ public List<UiFilterConfig> getFilters() {
+ return filters;
+ }
+
+ public void setFilters(List<UiFilterConfig> filters) {
+ this.filters = filters;
+ }
+
+ @Override
+ public String toString() {
+ return "UiFiltersConfig [filters=" + filters + "]";
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersSchemaUtility.java b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersSchemaUtility.java
new file mode 100644
index 0000000..f2d2418
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/search/filters/config/UiFiltersSchemaUtility.java
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.search.filters.config;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Utility methods for interacting with the UI filters schema file
+ */
+public class UiFiltersSchemaUtility {
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(UiFiltersSchemaUtility.class);
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * Reads in the file and populates an object with that data
+ *
+ * @throws Exception
+ */
+ public UiFiltersConfig loadUiFiltersConfig() {
+ UiFiltersConfig filtersConfig = new UiFiltersConfig();
+
+ try {
+ filtersConfig = mapper.readValue(new File(DataRouterConstants.UI_FILTER_LIST_FILE), UiFiltersConfig.class);
+ } catch (IOException e) {
+ LOG.error(DataRouterMsgs.JSON_CONVERSION_ERROR, "Could not convert filters config file " +
+ DataRouterConstants.UI_FILTER_LIST_FILE + " to " + filtersConfig.getClass());
+ }
+
+ return filtersConfig;
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/service/EchoService.java b/src/main/java/org/onap/aai/datarouter/service/EchoService.java
new file mode 100644
index 0000000..708b391
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/service/EchoService.java
@@ -0,0 +1,95 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.service;
+
+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.eelf.LoggerFactory;
+import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+import org.slf4j.MDC;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+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.Response;
+import javax.ws.rs.core.UriInfo;
+
+public class EchoService {
+
+ private static Logger logger = LoggerFactory.getInstance().getLogger(EchoService.class.getName());
+ private static Logger auditLogger =
+ LoggerFactory.getInstance().getAuditLogger(EchoService.class.getName());
+
+ @GET
+ @Path("echo/{input}")
+ @Produces("text/plain")
+ public String ping(@PathParam("input") String input, @Context HttpHeaders headers,
+ @Context UriInfo info, @Context HttpServletRequest req) {
+
+ String fromIp = req.getRemoteAddr();
+ String fromAppId = "";
+ String transId;
+
+ if (headers.getRequestHeaders().getFirst("X-FromAppId") != null) {
+ fromAppId = headers.getRequestHeaders().getFirst("X-FromAppId");
+ }
+
+ if ((headers.getRequestHeaders().getFirst("X-TransactionId") == null)
+ || headers.getRequestHeaders().getFirst("X-TransactionId").isEmpty()) {
+ transId = java.util.UUID.randomUUID().toString();
+ } else {
+ transId = headers.getRequestHeaders().getFirst("X-TransactionId");
+ }
+
+ MdcContext.initialize(transId, DataRouterConstants.DATA_ROUTER_SERVICE_NAME, "", fromAppId,
+ fromIp);
+
+ int status = 200;
+ String respStatusString = "";
+ if (Response.Status.fromStatusCode(status) != null) {
+ respStatusString = Response.Status.fromStatusCode(status).toString();
+ }
+
+ // Generate error log
+ logger.info(DataRouterMsgs.PROCESS_REST_REQUEST, req.getMethod(),
+ req.getRequestURL().toString(), req.getRemoteHost(), Integer.toString(status));
+
+ // Generate audit log.
+ auditLogger.info(DataRouterMsgs.PROCESS_REST_REQUEST,
+ new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, status)
+ .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, respStatusString),
+ (req != null) ? req.getMethod() : "Unknown",
+ (req != null) ? req.getRequestURL().toString() : "Unknown",
+ (req != null) ? req.getRemoteHost() : "Unknown", Integer.toString(status));
+ MDC.clear();
+
+ return "Hello, " + input + ".";
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/AaiUiSvcPolicyUtil.java b/src/main/java/org/onap/aai/datarouter/util/AaiUiSvcPolicyUtil.java
new file mode 100644
index 0000000..b86dfc6
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/AaiUiSvcPolicyUtil.java
@@ -0,0 +1,75 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+public class AaiUiSvcPolicyUtil {
+
+ static ObjectMapper mapper = new ObjectMapper();
+
+ public static JsonNode getOriginPayload(JsonNode payload) throws Exception{
+ /*
+ *{
+ "origin-uri": "/routerService/1search1",
+ "origin-payload": {}
+ }
+ */
+ JsonNode origPayload = null;
+
+ if (payload.has("origin-payload")){
+ origPayload = payload.get("origin-payload");
+ }
+ return origPayload;
+ }
+
+ public static String getOriginUri ( JsonNode payload ) throws Exception {
+ String originUri = "";
+ if (payload.has("origin-uri")){
+ originUri = payload.get("origin-uri").textValue();
+ }
+ return originUri;
+ }
+
+ public static String getTargetUri(JsonNode payload) throws Exception{
+ /*
+ *{
+ "origin-uri": "/routerService/1search1",
+ "origin-payload": {}
+ }
+ */
+ String uri = "";
+ String originUri = getOriginUri(payload);
+ final Matcher m = Pattern.compile("/routerService/(.*)").matcher(originUri);
+ if ( m.find() ) {
+ uri = m.group(1);
+ }
+ return uri;
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/CrossEntityReference.java b/src/main/java/org/onap/aai/datarouter/util/CrossEntityReference.java
new file mode 100644
index 0000000..7ad9ade
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/CrossEntityReference.java
@@ -0,0 +1,95 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Processing and entity wrapper for property transposition logic and UEB processing
+ *
+ * @author DAVEA
+ */
+public class CrossEntityReference {
+
+ private String targetEntityType;
+
+ private List<String> attributeNames;
+
+ public CrossEntityReference() {
+ this.targetEntityType = null;
+ this.attributeNames = new ArrayList<>();
+ }
+
+ public String getTargetEntityType() {
+ return targetEntityType;
+ }
+
+ public void setTargetEntityType(String targetEntityType) {
+ this.targetEntityType = targetEntityType;
+ }
+
+ public List<String> getAttributeNames() {
+ return attributeNames;
+ }
+
+ public void setAttributeNames(List<String> attributeNames) {
+ this.attributeNames = attributeNames;
+ }
+
+ public void addAttributeName(String attributeName) {
+ if (!this.attributeNames.contains(attributeName)) {
+ this.attributeNames.add(attributeName);
+ }
+ }
+
+ public void initialize(String crossEntityReferenceValueFromModel) {
+
+ if (crossEntityReferenceValueFromModel == null
+ || crossEntityReferenceValueFromModel.length() == 0) {
+ // or throw an exception due to failure to initialize
+ return;
+ }
+
+ String[] tokens = crossEntityReferenceValueFromModel.split(",");
+
+ if (tokens.length >= 2) {
+ this.targetEntityType = tokens[0];
+
+ for (int x = 1; x < tokens.length; x++) {
+ this.attributeNames.add(tokens[x]);
+ }
+ } else {
+ // throw a CrossEntityReferenceInitializationException??
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return "CrossEntityReference ["
+ + (targetEntityType != null ? "entityType=" + targetEntityType + ", " : "")
+ + (attributeNames != null ? "attributeNames=" + attributeNames : "") + "]";
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/DataRouterConstants.java b/src/main/java/org/onap/aai/datarouter/util/DataRouterConstants.java
new file mode 100644
index 0000000..a7cae9c
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/DataRouterConstants.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+public class DataRouterConstants {
+ public static final String DR_FILESEP = (System.getProperty("file.separator") == null) ? "/"
+ : System.getProperty("file.separator");
+
+ public static final String DR_AJSC_HOME = System.getProperty("AJSC_HOME");
+
+ public static final String DR_SPECIFIC_CONFIG = System.getProperty("CONFIG_HOME") + DR_FILESEP;
+
+ public static final String DR_BUNDLECONFIG_NAME = (System.getProperty("BUNDLECONFIG_DIR") == null)
+ ? "bundleconfig" : System.getProperty("BUNDLECONFIG_DIR");
+
+ public static final String DR_HOME_BUNDLECONFIG = (DR_AJSC_HOME == null)
+ ? DR_FILESEP + "opt" + DR_FILESEP + "app" + DR_FILESEP
+ + "datalayer" + DR_FILESEP + DR_BUNDLECONFIG_NAME
+ : DR_AJSC_HOME + DR_FILESEP + DR_BUNDLECONFIG_NAME;
+
+ /** This is the etc directory, relative to AAI_HOME. */
+ public static final String DR_HOME_ETC = DR_HOME_BUNDLECONFIG + DR_FILESEP + "etc" + DR_FILESEP;
+
+ public static final String DR_HOME_MODEL = DR_SPECIFIC_CONFIG + "model" + DR_FILESEP;
+ public static final String DR_HOME_AUTH = DR_SPECIFIC_CONFIG + "auth" + DR_FILESEP;
+
+ public static final String DR_CONFIG_FILE = DR_SPECIFIC_CONFIG + "data-router.properties";
+
+ public static final String DR_HOME_ETC_OXM = DR_HOME_ETC + "oxm" + DR_FILESEP;
+
+ public static final String UI_FILTER_LIST_FILE =
+ DR_SPECIFIC_CONFIG + DR_FILESEP + "filters" + DR_FILESEP + "aaiui_filters.json";
+
+ // AAI Related
+ public static final String AAI_ECHO_SERVICE = "/util/echo";
+
+ // Logging related
+ public static final String DATA_ROUTER_SERVICE_NAME = "DataRouter";
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java b/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java
new file mode 100644
index 0000000..87097a8
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/DataRouterProperties.java
@@ -0,0 +1,56 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+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 {
+ properties = new Properties();
+ File file = new File(DataRouterConstants.DR_CONFIG_FILE);
+ try {
+ properties.load(new FileInputStream(file));
+ } catch (FileNotFoundException e) {
+ logger.error("FileNotFoundException: ", e);
+ } catch (IOException e) {
+ logger.error("IOException: ", e);
+ }
+ }
+
+ public static String get(String key) {
+ return properties.getProperty(key);
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/EntityOxmReferenceHelper.java b/src/main/java/org/onap/aai/datarouter/util/EntityOxmReferenceHelper.java
new file mode 100644
index 0000000..0375152
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/EntityOxmReferenceHelper.java
@@ -0,0 +1,60 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.util.HashMap;
+
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+public class EntityOxmReferenceHelper implements ExternalOxmModelProcessor {
+
+ private static EntityOxmReferenceHelper _instance = null;
+
+ private HashMap<Version, VersionedOxmEntities> versionedModels;
+
+ protected EntityOxmReferenceHelper() {
+ this.versionedModels = new HashMap<>();
+ }
+
+ public static EntityOxmReferenceHelper getInstance() {
+ if ( _instance == null ) {
+ _instance = new EntityOxmReferenceHelper();
+ }
+
+ return _instance;
+ }
+
+
+ @Override
+ public void onOxmVersionChange(Version version, DynamicJAXBContext context) {
+ VersionedOxmEntities oxmEntities = new VersionedOxmEntities();
+ oxmEntities.initialize(context);
+ this.versionedModels.put(version, oxmEntities);
+
+ }
+
+ public VersionedOxmEntities getVersionedOxmEntities(Version version){
+ return this.versionedModels.get(version);
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/ExternalOxmModelProcessor.java b/src/main/java/org/onap/aai/datarouter/util/ExternalOxmModelProcessor.java
new file mode 100644
index 0000000..9e61b8d
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/ExternalOxmModelProcessor.java
@@ -0,0 +1,35 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+/**
+ * Exposes a registration and processing contract so that any load/change of an oxm version will
+ * inform registered model processors.
+ *
+ * @author davea
+ */
+public interface ExternalOxmModelProcessor {
+ public void onOxmVersionChange(Version version, DynamicJAXBContext context);
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/FileWatcher.java b/src/main/java/org/onap/aai/datarouter/util/FileWatcher.java
new file mode 100644
index 0000000..6009302
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/FileWatcher.java
@@ -0,0 +1,48 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.io.File;
+import java.util.TimerTask;
+
+public abstract class FileWatcher extends TimerTask {
+ private long timeStamp;
+ private File file;
+
+ public FileWatcher(File file) {
+ this.file = file;
+ this.timeStamp = file.lastModified();
+ }
+
+ @Override
+ public final void run() {
+ long newTimeStamp = file.lastModified();
+
+ if ((newTimeStamp - this.timeStamp) > 500) {
+ this.timeStamp = newTimeStamp;
+ onChange(file);
+ }
+ }
+
+ protected abstract void onChange(File file);
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/NodeUtils.java b/src/main/java/org/onap/aai/datarouter/util/NodeUtils.java
new file mode 100644
index 0000000..84876fb
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/NodeUtils.java
@@ -0,0 +1,177 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+public class NodeUtils {
+ /**
+ * Generate unique sha digest. This method is copy over from NodeUtils class in AAIUI
+ *
+ * @param keys the keys
+ * @return the string
+ */
+ public static String generateUniqueShaDigest(String... keys) {
+ if ((keys == null) || keys.length == 0) {
+ return null;
+ }
+
+ final String keysStr = Arrays.asList(keys).toString();
+ final String hashedId = org.apache.commons.codec.digest.DigestUtils.sha256Hex(keysStr);
+
+ return hashedId;
+ }
+
+ /**
+ * Extract field value from object.
+ *
+ * @param node the node
+ * @param fieldName the field name
+ * @return the string
+ */
+ public static String extractFieldValueFromObject(JsonNode node, String fieldName) {
+
+ if (node == null) {
+ return null;
+ }
+
+ if (node.isObject()) {
+
+ JsonNode valueNode = node.get(fieldName);
+
+ if (valueNode != null) {
+
+ if (valueNode.isValueNode()) {
+ return valueNode.asText();
+ }
+ }
+
+ }
+ return null;
+
+ }
+
+ /**
+ * Convert json str to json node.
+ *
+ * @param jsonStr the json str
+ * @return the json node
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public static JsonNode convertJsonStrToJsonNode(String jsonStr) throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ if (jsonStr == null || jsonStr.length() == 0) {
+ return null;
+ }
+
+ return mapper.readTree(jsonStr);
+ }
+
+ /**
+ * Extract objects by key.
+ *
+ * @param node the node
+ * @param searchKey the search key
+ * @param foundObjects the found objects
+ */
+ public static void extractObjectsByKey(JsonNode node, String searchKey,
+ Collection<JsonNode> foundObjects) {
+
+ if ( node == null ) {
+ return;
+ }
+
+ if (node.isObject()) {
+ Iterator<Map.Entry<String, JsonNode>> nodeIterator = node.fields();
+
+ while (nodeIterator.hasNext()) {
+ Map.Entry<String, JsonNode> entry = nodeIterator.next();
+ if (!entry.getValue().isValueNode()) {
+ extractObjectsByKey(entry.getValue(), searchKey, foundObjects);
+ }
+
+ String name = entry.getKey();
+ if (name.equalsIgnoreCase(searchKey)) {
+
+ JsonNode entryNode = entry.getValue();
+
+ if (entryNode.isArray()) {
+
+ Iterator<JsonNode> arrayItemsIterator = entryNode.elements();
+ while (arrayItemsIterator.hasNext()) {
+ foundObjects.add(arrayItemsIterator.next());
+ }
+
+ } else {
+ foundObjects.add(entry.getValue());
+ }
+
+
+ }
+ }
+ } else if (node.isArray()) {
+ Iterator<JsonNode> arrayItemsIterator = node.elements();
+ while (arrayItemsIterator.hasNext()) {
+ extractObjectsByKey(arrayItemsIterator.next(), searchKey, foundObjects);
+ }
+
+ }
+
+ }
+
+ /**
+ * Convert object to json.
+ *
+ * @param object the object
+ * @param pretty the pretty
+ * @return the string
+ * @throws JsonProcessingException the json processing exception
+ */
+ public static String convertObjectToJson(Object object, boolean pretty)
+ throws JsonProcessingException {
+ ObjectWriter ow;
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+
+ if (pretty) {
+ ow = mapper.writer().withDefaultPrettyPrinter();
+
+ } else {
+ ow = mapper.writer();
+ }
+
+ return ow.writeValueAsString(object);
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/OxmModelLoader.java b/src/main/java/org/onap/aai/datarouter/util/OxmModelLoader.java
new file mode 100644
index 0000000..37713c4
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/OxmModelLoader.java
@@ -0,0 +1,139 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.Response.Status;
+import javax.xml.bind.JAXBException;
+
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.util.ExternalOxmModelProcessor;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class OxmModelLoader {
+
+ private static Map<String, DynamicJAXBContext> versionContextMap = new ConcurrentHashMap<>();
+ private static List<ExternalOxmModelProcessor> oxmModelProcessorRegistry = new ArrayList<>();
+ final static Pattern p = Pattern.compile("aai_oxm_(.*).xml");
+
+
+
+ private static org.onap.aai.cl.api.Logger logger = LoggerFactory.getInstance()
+ .getLogger(OxmModelLoader.class.getName());
+
+ public synchronized static void loadModels() throws FileNotFoundException {
+
+ ClassLoader cl = OxmModelLoader.class.getClassLoader();
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
+ Resource[] resources;
+ try {
+ resources = resolver.getResources("classpath*:/oxm/aai_oxm*.xml");
+ } catch (IOException ex) {
+ logger.error(DataRouterMsgs.LOAD_OXM_ERROR, ex.getMessage());
+ throw new FileNotFoundException("Unable to load OXM models from schema path : /oxm/aai_oxm*.xml");
+ }
+
+ if (resources.length == 0) {
+ logger.error(DataRouterMsgs.LOAD_OXM_ERROR, "No OXM schema files found on classpath");
+ throw new FileNotFoundException("Unable to load OXM models from schema path : /oxm/aai_oxm*.xml");
+ }
+
+ for (Resource resource : resources) {
+ Matcher matcher = p.matcher(resource.getFilename());
+
+ if (matcher.matches()) {
+ try {
+ OxmModelLoader.loadModel(matcher.group(1), resource.getFilename(),resource.getInputStream());
+ } catch (Exception e) {
+ logger.error(DataRouterMsgs.LOAD_OXM_ERROR, "Failed to load " + resource.getFilename()
+ + ": " + e.getMessage());
+ }
+ }
+ }
+
+
+ }
+
+
+
+ private synchronized static void loadModel(String version,String resourceName,InputStream inputStream) throws JAXBException, FileNotFoundException {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, inputStream);
+ final DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory
+ .createContextFromOXM(Thread.currentThread().getContextClassLoader(), properties);
+ versionContextMap.put(version, jaxbContext);
+ if ( oxmModelProcessorRegistry != null) {
+ for ( ExternalOxmModelProcessor processor : oxmModelProcessorRegistry ) {
+ processor.onOxmVersionChange(Version.valueOf(version), jaxbContext );
+ }
+ }
+ logger.info(DataRouterMsgs.LOADED_OXM_FILE, resourceName);
+ }
+
+ public static DynamicJAXBContext getContextForVersion(String version) throws Exception {
+ if (versionContextMap == null || versionContextMap.isEmpty()) {
+ loadModels();
+ } else if (!versionContextMap.containsKey(version)) {
+ throw new Exception(Status.NOT_FOUND.toString());
+
+ }
+
+ return versionContextMap.get(version);
+ }
+
+ public static Map<String, DynamicJAXBContext> getVersionContextMap() {
+ return versionContextMap;
+ }
+
+ public static void setVersionContextMap(Map<String, DynamicJAXBContext> versionContextMap) {
+ OxmModelLoader.versionContextMap = versionContextMap;
+ }
+
+ public synchronized static void registerExternalOxmModelProcessors(Collection<ExternalOxmModelProcessor> processors) {
+ if(processors != null) {
+ for(ExternalOxmModelProcessor processor : processors) {
+ if(!oxmModelProcessorRegistry.contains(processor)) {
+ oxmModelProcessorRegistry.add(processor);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/RouterServiceUtil.java b/src/main/java/org/onap/aai/datarouter/util/RouterServiceUtil.java
new file mode 100644
index 0000000..ae0efee
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/RouterServiceUtil.java
@@ -0,0 +1,271 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.cxf.common.message.CxfConstants;
+import org.apache.cxf.message.Message;
+import org.json.JSONObject;
+import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.restclient.client.Headers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.servlet.ServletRequest;
+
+public class RouterServiceUtil {
+
+ public static void setMdcContext(Exchange exchange){
+ String txnID = exchange.getIn().getHeader(Headers.TRANSACTION_ID,
+ Arrays.asList(UUID.randomUUID())).toString();
+ String remote = exchange.getIn().getHeader(Headers.FROM_APP_ID, "").toString();
+ String remoteAddress = "";
+ Message cxfMessage = exchange.getIn().getHeader(CxfConstants.CAMEL_CXF_MESSAGE, Message.class);
+ if (cxfMessage != null) {
+ ServletRequest request = (ServletRequest) cxfMessage.get("HTTP.REQUEST");
+ if ( request != null)
+ remoteAddress = request.getRemoteAddr();
+ }
+
+ MdcContext.initialize(txnID, "Synapse", "", remote, remoteAddress);
+ }
+
+ public static Map<String, String> parseJsonPayloadIntoMap(String jsonPayload) {
+
+ JSONObject jsonObject = new JSONObject(jsonPayload);
+ Map<String, String> map = new HashMap<>();
+ Iterator iter = jsonObject.keys();
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ String value = jsonObject.getString(key);
+ map.put(key, value);
+ }
+ return map;
+ }
+
+ public static String getNodeFieldAsText(JsonNode node, String fieldName) {
+
+ String fieldValue = null;
+
+ JsonNode valueNode = node.get(fieldName);
+
+ if (valueNode != null) {
+ fieldValue = valueNode.asText();
+ }
+
+ return fieldValue;
+ }
+
+ public static String concatArray(List<String> list) {
+ return concatArray(list, " ");
+ }
+
+ public static String concatArray(List<String> list, String delimiter) {
+
+ if (list == null || !list.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder result = new StringBuilder(64);
+
+ boolean firstValue = true;
+
+ for (String item : list) {
+
+ if (firstValue) {
+ result.append(item);
+ firstValue = false;
+ } else {
+ result.append(delimiter).append(item);
+ }
+ }
+
+ return result.toString();
+
+ }
+
+ public static String concatArray(String[] values) {
+
+ if (values == null || values.length == 0) {
+ return "";
+ }
+
+ StringBuilder result = new StringBuilder(64);
+
+ boolean firstValue = true;
+
+ for (String item : values) {
+
+ if (firstValue) {
+ result.append(item);
+ firstValue = false;
+ } else {
+ result.append(".").append(item);
+ }
+
+ }
+
+ return result.toString();
+
+ }
+
+ public static String recursivelyLookupJsonPayload(JsonNode node, String key) {
+ String value = null;
+ if (node.isObject()) {
+ Iterator<Map.Entry<String, JsonNode>> nodeIterator = node.fields();
+
+ while (nodeIterator.hasNext()) {
+ Map.Entry<String, JsonNode> entry = (Map.Entry<String, JsonNode>) nodeIterator.next();
+ if (!entry.getValue().isValueNode()) {
+ value = recursivelyLookupJsonPayload(entry.getValue(), key);
+ if (value != null) {
+ return value;
+ }
+ }
+
+ String name = entry.getKey();
+ if (name.equalsIgnoreCase(key)) {
+ return entry.getValue().asText();
+ }
+ }
+ } else if (node.isArray()) {
+ Iterator<JsonNode> arrayItemsIterator = node.elements();
+ while (arrayItemsIterator.hasNext()) {
+ value = recursivelyLookupJsonPayload(arrayItemsIterator.next(), key);
+ if (value != null) {
+ return value;
+ }
+ }
+ }
+ return value;
+ }
+
+ public static void extractObjectsByKey(JsonNode node, String searchKey,
+ Collection<JsonNode> foundObjects) {
+
+ if (node.isObject()) {
+ Iterator<Map.Entry<String, JsonNode>> nodeIterator = node.fields();
+
+ while (nodeIterator.hasNext()) {
+ Map.Entry<String, JsonNode> entry = (Map.Entry<String, JsonNode>) nodeIterator.next();
+ if (!entry.getValue().isValueNode()) {
+ extractObjectsByKey(entry.getValue(), searchKey, foundObjects);
+ }
+
+ String name = entry.getKey();
+ if (name.equalsIgnoreCase(searchKey)) {
+
+ JsonNode entryValue = entry.getValue();
+
+ if (entryValue.isArray()) {
+
+ Iterator<JsonNode> arrayItemsIterator = entryValue.elements();
+ while (arrayItemsIterator.hasNext()) {
+ foundObjects.add(arrayItemsIterator.next());
+ }
+
+ } else {
+ foundObjects.add(entry.getValue());
+ }
+ }
+ }
+ } else if (node.isArray()) {
+ Iterator<JsonNode> arrayItemsIterator = node.elements();
+ while (arrayItemsIterator.hasNext()) {
+ extractObjectsByKey(arrayItemsIterator.next(), searchKey, foundObjects);
+ }
+ }
+ }
+
+ public static void convertArrayIntoList(JsonNode node, Collection<JsonNode> instances) {
+
+ if (node.isArray()) {
+ Iterator<JsonNode> arrayItemsIterator = node.elements();
+ while (arrayItemsIterator.hasNext()) {
+ instances.add(arrayItemsIterator.next());
+ }
+ } else {
+ instances.add(node);
+ }
+ }
+
+ public static void extractFieldValuesFromObject(JsonNode node,
+ Collection<String> attributesToExtract, Collection<String> fieldValues) {
+
+ if (node.isObject()) {
+
+ JsonNode valueNode;
+
+ for (String attrToExtract : attributesToExtract) {
+
+ valueNode = node.get(attrToExtract);
+
+ if (valueNode != null) {
+
+ if (valueNode.isValueNode()) {
+ fieldValues.add(valueNode.asText());
+ }
+ }
+ }
+ }
+ }
+
+
+ public static String objToJson(Object obj) {
+ JSONObject jsonObject = new JSONObject(obj);
+ String json = jsonObject.toString();
+ return json;
+ }
+
+ /**
+ * Helper utility to concatenate substrings of a URI together to form a proper URI.
+ *
+ * @param suburis the list of substrings to concatenate together
+ * @return the concatenated list of substrings
+ */
+ public 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;
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/SearchServiceAgent.java b/src/main/java/org/onap/aai/datarouter/util/SearchServiceAgent.java
new file mode 100644
index 0000000..20d0981
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/SearchServiceAgent.java
@@ -0,0 +1,366 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+import org.eclipse.jetty.util.security.Password;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.policy.EntityEventPolicy;
+import org.onap.aai.restclient.client.Headers;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.aai.restclient.enums.RestAuthenticationMode;
+import org.onap.aai.restclient.rest.HttpUtil;
+import org.slf4j.MDC;
+
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+
+public class SearchServiceAgent {
+
+ private Logger logger;
+
+ private RestClient searchClient = null;
+ private Map<String, String> indexSchemaMapping = new HashMap<>();
+
+ private String searchUrl = null;
+ private String documentEndpoint = null;
+
+
+ /**
+ * Creates a new instance of the search service agent.
+ *
+ * @param certName - Certificate to use for talking to the Search Service.
+ * @param keystore - Keystore to use for talking to the Search Service.
+ * @param keystorePwd - Keystore password for talking to the Search Service.
+ * @param searchUrl - URL at which the Search Service can be reached.
+ * @param documentEndpoint - Endpoint for accessing document resources on the Search Service.
+ * @param logger - Logger to use for system logs.
+ */
+ public SearchServiceAgent(String certName,
+ String keystore,
+ String keystorePwd,
+ String searchUrl,
+ String documentEndpoint,
+ Logger logger) {
+
+ initialize(certName, keystore, keystorePwd, searchUrl, documentEndpoint, logger);
+ }
+
+
+ /**
+ * Performs all one-time initialization required for the search agent.
+ *
+ * @param certName - Certificate to use for talking to the Search Service.
+ * @param keystore - Keystore to use for talking to the Search Service.
+ * @param keystorePwd - Keystore password for talking to the Search Service.
+ * @param searchUrl - URL at which the Search Service can be reached.
+ * @param documentEndpoint - Endpoint for accessing document resources on the Search Service.
+ * @param logger - Logger to use for system logs.
+ */
+ private void initialize(String certName,
+ String keystore,
+ String keystorePwd,
+ String searchUrl,
+ String documentEndpoint,
+ Logger logger) {
+
+ // Create REST client for search service
+ searchClient = new RestClient()
+ .authenticationMode(RestAuthenticationMode.SSL_CERT)
+ .validateServerHostname(false)
+ .validateServerCertChain(true)
+ .clientCertFile(DataRouterConstants.DR_HOME_AUTH + certName)
+ .clientCertPassword(Password.deobfuscate(keystorePwd))
+ .trustStore(DataRouterConstants.DR_HOME_AUTH + keystore);
+
+ this.searchUrl = searchUrl;
+ this.documentEndpoint = documentEndpoint;
+
+ this.logger = logger;
+ }
+
+
+ /**
+ * Creates an index through the search db abstraction
+ *
+ * @param index - The name of the index to be created.
+ * @param schemaLocation - The name of the schema file for the index.
+ */
+ public void createSearchIndex(String index, String schemaLocation) {
+
+ // Create a mapping of the index name to schema location
+ indexSchemaMapping.put(index, schemaLocation);
+
+ // Now, create the index.
+ createIndex(index, schemaLocation);
+ }
+
+
+ /**
+ * This method performs the actual work of creating a search index.
+ *
+ * @param index - The name of the index to be created.
+ * @param schemaLocation - The name of the schema file for the index.
+ */
+ private void createIndex(String index, String schemaLocation) {
+
+ logger.debug("Creating search index, index name: = " + index + ", schemaLocation = " + schemaLocation);
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.put("Accept", Arrays.asList("application/json"));
+ headers.put(Headers.FROM_APP_ID, Arrays.asList("DL"));
+ headers.put(Headers.TRANSACTION_ID, Arrays.asList(UUID.randomUUID().toString()));
+
+ String url = concatSubUri(searchUrl, index);
+ try {
+
+ OperationResult result = searchClient.put(url, loadFileData(schemaLocation), headers,
+ MediaType.APPLICATION_JSON_TYPE, null);
+
+ if (!HttpUtil.isHttpResponseClassSuccess(result.getResultCode())) {
+ logger.error(DataRouterMsgs.FAIL_TO_CREATE_SEARCH_INDEX, index, result.getFailureCause());
+ } else {
+ logger.info(DataRouterMsgs.SEARCH_INDEX_CREATE_SUCCESS, index);
+ }
+
+ } catch (Exception e) {
+ logger.error(DataRouterMsgs.FAIL_TO_CREATE_SEARCH_INDEX, index, e.getLocalizedMessage());
+ }
+ }
+
+
+ /**
+ * Retrieves a document from the search service.
+ *
+ * @param index - The index to retrieve the document from.
+ * @param id - The unique identifier for the document.
+ *
+ * @return - The REST response returned from the Search Service.
+ */
+ public OperationResult getDocument(String index, String id) {
+
+ Map<String, List<String>> headers = new HashMap<>();
+ headers.put(Headers.FROM_APP_ID, Arrays.asList("Data Router"));
+ headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
+
+ String url = concatSubUri(searchUrl, index, documentEndpoint, id);
+ return searchClient.get(url, headers, MediaType.APPLICATION_JSON_TYPE);
+ }
+
+
+ /**
+ * Creates or updates a document in the Search Service.
+ *
+ * @param index - The index to create or update the document in.
+ * @param id - The identifier for the document.
+ * @param payload - The document contents.
+ * @param headers - HTTP headers.
+ */
+ public void putDocument(String index, String id, String payload, Map<String, List<String>> headers) {
+
+ // Try to post the document to the search service.
+ OperationResult result = doDocumentPut(index, id, payload, headers);
+
+ // A 404 response from the Search Service may indicate that the index we are writing
+ // to does not actually exist. We will try creating it now.
+ if(result.getResultCode() == Status.NOT_FOUND.getStatusCode()) {
+
+ // Lookup the location of the schema that we want to create.
+ String indexSchemaLocation = indexSchemaMapping.get(index);
+ if(indexSchemaLocation != null) {
+
+ // Try creating the index now...
+ logger.info(DataRouterMsgs.CREATE_MISSING_INDEX, index);
+ createIndex(index, indexSchemaLocation);
+
+ // ...and retry the document post.
+ result = doDocumentPut(index, id, payload, headers);
+ }
+ }
+
+ if(!resultSuccessful(result)) {
+ logger.error(DataRouterMsgs.FAIL_TO_CREATE_UPDATE_DOC, index, result.getFailureCause());
+ }
+ }
+
+
+ /**
+ * This method does the actual work of submitting a document PUT request to the Search Service.
+ *
+ * @param index - The index to create or update the document in.
+ * @param id - The identifier for the document.
+ * @param payload - The document contents.
+ * @param headers - HTTP headers.
+ *
+ * @return - The HTTP response returned by the Search Service.
+ */
+ private OperationResult doDocumentPut(String index, String id, String payload, Map<String, List<String>> headers) {
+
+ String url = concatSubUri(searchUrl, index, documentEndpoint, id);
+ return searchClient.put(url, payload, headers, MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
+ }
+
+
+ /**
+ * Creates a document in the Search Service.
+ *
+ * @param index - The index to create the document in.
+ * @param payload - The document contents.
+ * @param headers - HTTP headers.
+ */
+ public void postDocument(String index, String payload, Map<String, List<String>> headers) {
+
+ // Try to post the document to the search service.
+ OperationResult result = doDocumentPost(index, payload, headers);
+
+ // A 404 response from the Search Service may indicate that the index we are writing
+ // to does not actually exist. We will try creating it now.
+ if(result.getResultCode() == Status.NOT_FOUND.getStatusCode()) {
+
+ // Lookup the location of the schema that we want to create.
+ String indexSchemaLocation = indexSchemaMapping.get(index);
+ if(indexSchemaLocation != null) {
+
+ // Try creating the index now...
+ logger.info(DataRouterMsgs.CREATE_MISSING_INDEX, index);
+ createIndex(index, indexSchemaLocation);
+
+ // ...and retry the document post.
+ result = doDocumentPost(index, payload, headers);
+ }
+ }
+
+ if(!resultSuccessful(result)) {
+ logger.error(DataRouterMsgs.FAIL_TO_CREATE_UPDATE_DOC, index, result.getFailureCause());
+ }
+ }
+
+
+ /**
+ * This method does the actual work of submitting a document PUT request to the Search Service.
+ *
+ * @param index - The index to create or update the document in.
+ * @param payload - The document contents.
+ * @param headers - HTTP headers.
+ *
+ * @return - The HTTP response returned by the Search Service.
+ */
+ private OperationResult doDocumentPost(String index, String payload, Map<String, List<String>> headers) {
+
+ String url = concatSubUri(searchUrl, index, documentEndpoint);
+ return searchClient.post(url, payload, headers, MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
+ }
+
+
+ /**
+ * Removes a document from the Search Service.
+ *
+ * @param index - The index to create the document in.
+ * @param id - The identifier for the document.
+ * @param payload - The document contents.
+ * @param headers - HTTP headers.
+ */
+ public void deleteDocument(String index, String documentId, Map<String, List<String>> headers) {
+
+ String url = concatSubUri(searchUrl, index, documentEndpoint, documentId);
+ searchClient.delete(url, headers, null);
+ }
+
+
+ /**
+ * Convenience method to load up all the data from a file into a string
+ *
+ * @param filename the filename to read from disk
+ * @return the data contained within the file
+ * @throws Exception
+ */
+ protected String loadFileData(String filename) throws Exception {
+ StringBuilder data = new StringBuilder();
+ try {
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ EntityEventPolicy.class.getClassLoader().getResourceAsStream("/" + filename),
+ StandardCharsets.UTF_8));
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ data.append(line);
+ }
+ } catch (Exception e) {
+ throw new Exception("Failed to read from file = " + filename + ".", e);
+ }
+
+ return data.toString();
+ }
+
+
+ /**
+ * Helper utility to concatenate substrings of a URI together to form a proper URI.
+ *
+ * @param suburis the list of substrings to concatenate together
+ * @return the concatenated list of substrings
+ */
+ public 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;
+ }
+
+
+ /**
+ * Helper utility to check the response code of an HTTP response.
+ *
+ * @param aResult - The response that we want to check.
+ *
+ * @return - true if the response contains a success code,
+ * false otherwise.
+ */
+ private boolean resultSuccessful(OperationResult aResult) {
+
+ return (aResult.getResultCode() >= 200) && (aResult.getResultCode() < 300);
+ }
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/SearchSuggestionPermutation.java b/src/main/java/org/onap/aai/datarouter/util/SearchSuggestionPermutation.java
new file mode 100644
index 0000000..384122e
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/SearchSuggestionPermutation.java
@@ -0,0 +1,98 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchSuggestionPermutation {
+ /*
+ * Will return all the unique combinations of the suggestions provided.
+ * The order of the permutation is not taken into account when computing
+ * the uniqueness.
+ * e.g.: A list of A,B,C,D will return
+ * [[A], [A, B, C, D], [A, C, D], [A, D], [B], [B, C, D], [B, D], [C], [C, D], [D]]
+ *
+ * @param list The list of statuses to create permutations of
+ * @return A list which contains a array list of all possible combinations
+ */
+ public static ArrayList<ArrayList<String>> getUniqueListForSuggestions(
+ List<String> originalList) {
+ ArrayList<ArrayList<String>> lists = new ArrayList<>();
+ if (originalList.isEmpty()) {
+ lists.add(new ArrayList<String>());
+ return lists;
+ }
+ List<String> list = new ArrayList<>(originalList);
+ String head = list.get(0);
+ ArrayList<String> rest = new ArrayList<>(list.subList(1, list.size()));
+
+ for (ArrayList<String> activeList : getUniqueListForSuggestions(rest)) {
+ ArrayList<String> newList = new ArrayList<>();
+ newList.add(head);
+ newList.addAll(activeList);
+ lists.add(newList);
+ lists.add(activeList);
+ }
+ return lists;
+ }
+
+ public static ArrayList<ArrayList<String>> getNonEmptyUniqueLists(List<String> list) {
+ ArrayList<ArrayList<String>> lists = getUniqueListForSuggestions(list);
+ // remove empty list from the power set
+ for (ArrayList<String> emptyList : lists) {
+ if (emptyList.isEmpty()) {
+ lists.remove(emptyList);
+ break;
+ }
+ }
+ return lists;
+ }
+
+ public static List<List<String>> getListPermutations(List<String> list) {
+ List<String> inputList = new ArrayList<>();
+ inputList.addAll(list);
+ if (inputList.isEmpty()) {
+ List<List<String>> result = new ArrayList<>();
+ result.add(new ArrayList<String>());
+ return result;
+ }
+
+ List<List<String>> listOfLists = new ArrayList<>();
+
+ String firstElement = inputList.remove(0);
+
+ List<List<String>> recursiveReturn = getListPermutations(inputList);
+ for (List<String> li : recursiveReturn) {
+
+ for (int index = 0; index <= li.size(); index++) {
+ List<String> temp = new ArrayList<>(li);
+ temp.add(index, firstElement);
+ listOfLists.add(temp);
+ }
+
+ }
+ return listOfLists;
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/Version.java b/src/main/java/org/onap/aai/datarouter/util/Version.java
new file mode 100644
index 0000000..3362497
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/Version.java
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+public enum Version {
+ v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20;
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/aai/datarouter/util/VersionedOxmEntities.java b/src/main/java/org/onap/aai/datarouter/util/VersionedOxmEntities.java
new file mode 100644
index 0000000..24277c6
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/VersionedOxmEntities.java
@@ -0,0 +1,347 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util;
+
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.internal.helper.DatabaseField;
+import org.eclipse.persistence.internal.oxm.XPathFragment;
+import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.eclipse.persistence.mappings.DatabaseMapping;
+import org.eclipse.persistence.oxm.XMLField;
+import org.onap.aai.datarouter.entity.OxmEntityDescriptor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Builds up a representation of the versioned entities in a way that they can be cross referenced
+ * in a data-driven way
+ *
+ * @author DAVEA
+ */
+public class VersionedOxmEntities {
+
+ private static final String REST_ROOT_ENTITY = "inventory";
+
+ private HashMap<String, Boolean> crossEntityReferenceContainerLookup = new HashMap<>();
+ private HashMap<String, CrossEntityReference> crossEntityReferenceLookup = new HashMap<>();
+ private Map<String, DynamicType> entityTypeLookup = new LinkedHashMap<>();
+ private Map<String, OxmEntityDescriptor> searchableEntityDescriptors = new HashMap<>();
+ private Map<String, OxmEntityDescriptor> suggestableEntityDescriptors = new HashMap<>();
+ private Map<String, OxmEntityDescriptor> entityAliasDescriptors = new HashMap<>();
+
+
+ public void initialize(DynamicJAXBContext context) {
+ parseOxmContext(context);
+ buildCrossEntityReferenceCollections(REST_ROOT_ENTITY, new HashSet<String>());
+ populateSearchableDescriptors(context);
+ }
+
+ /**
+ * The big goal for these methods is to make the processing as generic and model driven as possible.
+ * There are only two exceptions to this rule, at the moment. I needed to hard-coded the top level REST data
+ * model entity type, which is "inventory" for now. And as this class is heavily focused and coupled towards
+ * building a version specific set of lookup structures for the "crossEntityReference" model attribute, it possesses
+ * knowledge of that attribute whether it exists or not in the DynamicJAXBContext we are currently analyzing.
+ * <p>
+ * This method will build two collections:
+ * <p>
+ * 1) A list of entity types that can have nested entities containing cross entity reference definitions.
+ * The purpose of this collection is a fail-fast test when processing UEB events so we can quickly determine if
+ * it is necessary to deeply parse the event looking for cross entity reference attributes which not exist.
+ * <p>
+ * For example, looking at a service-instance <=> inventory path:
+ * <p>
+ * inventory (true)
+ * -> business (true)
+ * -> customers (true)
+ * -> customer (true)
+ * -> service-subscriptions (true)
+ * -> service-subscription (CER defined here in the model) (true)
+ * -> service-instances (false)
+ * -> service-instance (false)
+ * <p>
+ * Because service-subscription contains a model definition of CER, in the first collection all the types in the
+ * tree will indicate that it possesses one or more contained entity types with a cross-entity-reference definition.
+ * <p>
+ * 2) A lookup for { entityType => CrossEntityReference } so we can quickly access the model definition of a CER
+ * for a specific entity type when we begin extracting parent attributes for transposition into nested child entity
+ * types.
+ *
+ * @param entityType
+ * @param checked
+ * @return
+ */
+ protected boolean buildCrossEntityReferenceCollections(String entityType, HashSet<String> checked) {
+
+ /*
+ * To short-circuit infinite loops, make sure this entityType hasn't
+ * already been checked
+ */
+
+ if (checked.contains(entityType)) {
+ return false;
+ } else {
+ checked.add(entityType);
+ }
+
+ DynamicType parentType = entityTypeLookup.get(entityType);
+ DynamicType childType;
+ boolean returnValue = false;
+
+ if (parentType == null) {
+ return returnValue;
+ }
+
+ /*
+ * Check if current descriptor contains the cross-entity-reference
+ * attribute. If it does not walk the entity model looking for nested
+ * entity types that may contain the reference.
+ */
+
+ Map<String, String> properties = parentType.getDescriptor().getProperties();
+ if (properties != null) {
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ if ("crossEntityReference".equalsIgnoreCase(entry.getKey())) {
+ returnValue = true;
+ CrossEntityReference cer = new CrossEntityReference();
+ cer.initialize(entry.getValue());
+ crossEntityReferenceLookup.put(entityType, cer);
+ //System.out.println("entityType = " + entityType + " contains a CER instance = " + returnValue);
+ // return true;
+ }
+ }
+ }
+
+ Vector<DatabaseField> fields = parentType.getDescriptor().getAllFields();
+
+ if (fields != null) {
+
+ XMLField xmlField;
+ for (DatabaseField f : fields) {
+
+ if (f instanceof XMLField) {
+ xmlField = (XMLField) f;
+ XPathFragment xpathFragment = xmlField.getXPathFragment();
+ String entityShortName = xpathFragment.getLocalName();
+
+ childType = entityTypeLookup.get(entityShortName);
+
+ if (childType != null) {
+
+ if (!checked.contains(entityShortName)) {
+
+ if (buildCrossEntityReferenceCollections(entityShortName, checked)) {
+ returnValue = true;
+ }
+
+ }
+
+ checked.add(entityShortName);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ crossEntityReferenceContainerLookup.put(entityType, Boolean.valueOf(returnValue));
+ return returnValue;
+ }
+
+ private void populateSearchableDescriptors(DynamicJAXBContext oxmContext) {
+ List<Descriptor> descriptorsList = oxmContext.getXMLContext().getDescriptors();
+ OxmEntityDescriptor newOxmEntity;
+
+ for (Descriptor desc : descriptorsList) {
+
+ DynamicType entity = (DynamicType) oxmContext.getDynamicType(desc.getAlias());
+
+ //LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>();
+ String primaryKeyAttributeNames = null;
+
+ //Not all fields have key attributes
+ if (desc.getPrimaryKeyFields() != null) {
+ primaryKeyAttributeNames = desc.getPrimaryKeyFields()
+ .toString().replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "");
+ }
+
+ String entityName = desc.getDefaultRootElement();
+
+ Map<String, String> properties = entity.getDescriptor().getProperties();
+ if (properties != null) {
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ if ("searchable".equalsIgnoreCase(entry.getKey())) {
+
+ /*
+ * we can do all the work here, we don't have a create additional collections for
+ * subsequent passes
+ */
+ newOxmEntity = new OxmEntityDescriptor();
+ newOxmEntity.setEntityName(entityName);
+ newOxmEntity
+ .setPrimaryKeyAttributeName(Arrays.asList(primaryKeyAttributeNames.split(",")));
+ newOxmEntity.setSearchableAttributes(Arrays.asList(entry.getValue().split(",")));
+ searchableEntityDescriptors.put(entityName, newOxmEntity);
+ } else if ("containsSuggestibleProps".equalsIgnoreCase(entry.getKey())) {
+ newOxmEntity = new OxmEntityDescriptor();
+ newOxmEntity.setEntityName(entityName);
+ newOxmEntity.setSuggestableEntity(true);
+ Vector<DatabaseMapping> descriptorMaps = entity.getDescriptor().getMappings();
+ List<String> listOfSuggestableAttributes = new ArrayList<>();
+
+ for (DatabaseMapping descMap : descriptorMaps) {
+ if (descMap.isAbstractDirectMapping()) {
+
+ if (descMap.getProperties().get("suggestibleOnSearch") != null) {
+ String suggestableOnSearchString = String.valueOf(
+ descMap.getProperties().get("suggestibleOnSearch"));
+
+ boolean isSuggestibleOnSearch = Boolean.valueOf(suggestableOnSearchString);
+
+ if (isSuggestibleOnSearch) {
+ /* Grab attribute types for suggestion */
+ String attributeName = descMap.getField().getName()
+ .replaceAll("/text\\(\\)", "");
+ listOfSuggestableAttributes.add(attributeName);
+ }
+ }
+ }
+ }
+ newOxmEntity.setSuggestableAttributes(listOfSuggestableAttributes);
+ suggestableEntityDescriptors.put(entityName, newOxmEntity);
+ } else if ("suggestionAliases".equalsIgnoreCase(entry.getKey())) {
+ newOxmEntity = new OxmEntityDescriptor();
+ newOxmEntity.setEntityName(entityName);
+ newOxmEntity.setAlias(Arrays.asList(entry.getValue().split(",")));
+ entityAliasDescriptors.put(entityName, newOxmEntity);
+ }
+ }
+ }
+
+ }
+
+ }
+
+ public Map<String, OxmEntityDescriptor> getSearchableEntityDescriptors() {
+ return searchableEntityDescriptors;
+ }
+
+ public OxmEntityDescriptor getSearchableEntityDescriptor(String entityType) {
+ return searchableEntityDescriptors.get(entityType);
+ }
+
+
+ public HashMap<String, Boolean> getCrossEntityReferenceContainers() {
+ return crossEntityReferenceContainerLookup;
+ }
+
+ public HashMap<String, CrossEntityReference> getCrossEntityReferences() {
+ return crossEntityReferenceLookup;
+ }
+
+
+ private void parseOxmContext(DynamicJAXBContext oxmContext) {
+ List<Descriptor> descriptorsList = oxmContext.getXMLContext().getDescriptors();
+
+ for (Descriptor desc : descriptorsList) {
+
+ DynamicType entity = (DynamicType) oxmContext.getDynamicType(desc.getAlias());
+
+ String entityName = desc.getDefaultRootElement();
+
+ entityTypeLookup.put(entityName, entity);
+
+ }
+
+ }
+
+ public boolean entityModelContainsCrossEntityReference(String containerEntityType) {
+ Boolean v = crossEntityReferenceContainerLookup.get(containerEntityType);
+
+ if (v == null) {
+ return false;
+ }
+
+ return v;
+ }
+
+ public boolean entityContainsCrossEntityReference(String entityType) {
+ return crossEntityReferenceLookup.get(entityType) != null;
+ }
+
+ public CrossEntityReference getCrossEntityReference(String entityType) {
+ return crossEntityReferenceLookup.get(entityType);
+ }
+
+ public Map<String, OxmEntityDescriptor> getSuggestableEntityDescriptors() {
+ return suggestableEntityDescriptors;
+ }
+
+ public void setSuggestableEntityDescriptors(
+ Map<String, OxmEntityDescriptor> suggestableEntityDescriptors) {
+ this.suggestableEntityDescriptors = suggestableEntityDescriptors;
+ }
+
+ public Map<String, OxmEntityDescriptor> getEntityAliasDescriptors() {
+ return entityAliasDescriptors;
+ }
+
+ public void setEntityAliasDescriptors(Map<String, OxmEntityDescriptor> entityAliasDescriptors) {
+ this.entityAliasDescriptors = entityAliasDescriptors;
+ }
+
+ public void extractEntities(String entityType, DynamicJAXBContext context, Collection<DynamicType> entities) {
+
+
+ }
+
+ public String dumpCrossEntityReferenceContainers() {
+
+ Set<String> keys = crossEntityReferenceContainerLookup.keySet();
+ StringBuilder sb = new StringBuilder(128);
+
+ for (String key : keys) {
+
+ if (crossEntityReferenceContainerLookup.get(key)) {
+ sb.append("\n").append("Entity-Type = '" + key + "' contains a Cross-Entity-Reference.");
+ }
+ }
+
+
+ return sb.toString();
+
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/client/NoAuthRestClient.java b/src/main/java/org/onap/aai/datarouter/util/client/NoAuthRestClient.java
new file mode 100644
index 0000000..91bd7d7
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/client/NoAuthRestClient.java
@@ -0,0 +1,222 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util.client;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+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.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.util.AaiUiSvcPolicyUtil;
+import org.onap.aai.datarouter.util.NodeUtils;
+import org.onap.aai.datarouter.util.RouterServiceUtil;
+import org.onap.aai.restclient.client.Headers;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.aai.restclient.enums.RestAuthenticationMode;
+import org.onap.aai.restclient.rest.HttpUtil;
+import org.slf4j.MDC;
+import org.springframework.http.HttpStatus;
+
+import javax.ws.rs.core.MediaType;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class NoAuthRestClient implements SvcRoutingRestClient {
+
+ private RestClient restClient;
+
+ private String host;
+ private String port;
+ private String originUrl;
+ private String targetUri;
+ private JsonNode targetPayload;
+ private Logger logger;
+ private Logger auditLogger;
+
+ public NoAuthRestClient(int connectTimeOut, int readTimeOut) {
+ LoggerFactory loggerFactoryInstance = LoggerFactory.getInstance();
+ logger = loggerFactoryInstance.getLogger(NoAuthRestClient.class.getName());
+ auditLogger = loggerFactoryInstance.getAuditLogger(NoAuthRestClient.class.getName());
+ restClient = new RestClient().authenticationMode(RestAuthenticationMode.HTTP_NOAUTH)
+ .connectTimeoutMs(connectTimeOut).readTimeoutMs(readTimeOut);
+ }
+
+
+ private OperationResult getResults(String url, JsonNode payload) {
+ Map<String, List<String>> headers = new HashMap<>();
+ headers.put(Headers.FROM_APP_ID, Arrays.asList("Synapse"));
+ headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
+ return this.getRestClient().post(url, payload.asText(),
+ headers, MediaType.APPLICATION_JSON_TYPE,
+ MediaType.APPLICATION_JSON_TYPE);
+ }
+
+ public final void handleRequest(String host, String port, Exchange exchange) throws Exception {
+ RouterServiceUtil.setMdcContext(exchange);
+ Message message = exchange.getIn();
+ String body = message.getBody(String.class);
+ OperationResult result = new OperationResult();
+
+ this.setHost(host);
+ this.setPort(port);
+
+ this.setOriginUrl(message.getHeader(Exchange.HTTP_URL).toString());
+ if (body != null && body.length() != 0) {
+ JsonNode node = NodeUtils.convertJsonStrToJsonNode(body);
+ this.setTargetPayload(AaiUiSvcPolicyUtil.getOriginPayload(node));
+ this.setTargetUri(AaiUiSvcPolicyUtil.getTargetUri(node));
+ }
+
+ if (this.getTargetPayload() == null || this.getTargetUri() == null) {
+ logger.error(DataRouterMsgs.INVALID_ORIGIN_PAYLOAD, body);
+ result.setResultCode(HttpStatus.BAD_REQUEST.value());
+ result.setFailureCause("Invalid payload");
+ }
+
+ String targetUrl = "http://" + host + ":" + port + "/" + this.targetUri;
+ auditLogger.info(DataRouterMsgs.ROUTING_FROM_TO, this.getOriginUrl(), targetUrl);
+ long startTimeInMs = System.currentTimeMillis();
+
+ result = this.getResults(targetUrl, targetPayload);
+
+ long targetMsOpTime = System.currentTimeMillis() - startTimeInMs;
+ auditLogger.info(DataRouterMsgs.OP_TIME, "Target service at " + targetUrl, String.valueOf(targetMsOpTime));
+
+ int rc = result.getResultCode();
+ String resultStr;
+ if (HttpUtil.isHttpResponseClassSuccess(rc)) {
+ resultStr = result.getResult();
+ } else {
+ resultStr = result.getFailureCause();
+ }
+
+ logger.debug(DataRouterMsgs.ROUTING_RESPONSE, targetUrl, result.toString());
+ exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, rc);
+ exchange.getOut().setBody(resultStr);
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#getHost()
+ */
+ @Override
+ public String getHost() {
+ return host;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#setHost(java.lang.String)
+ */
+ @Override
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#getPort()
+ */
+ @Override
+ public String getPort() {
+ return port;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#setPort(java.lang.String)
+ */
+ @Override
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#getTargetUri()
+ */
+ @Override
+ public String getTargetUri() {
+ return targetUri;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#setTargetUri(java.lang.String)
+ */
+ @Override
+ public void setTargetUri(String targetUri) {
+ this.targetUri = targetUri;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#getTargetPayload()
+ */
+ @Override
+ public JsonNode getTargetPayload() {
+ return targetPayload;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client
+ * .SvcRoutingRestClient#setTargetPayload(com.fasterxml.jackson.databind.JsonNode)
+ */
+ @Override
+ public void setTargetPayload(JsonNode targetPayload) {
+ this.targetPayload = targetPayload;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#getRestClient()
+ */
+ @Override
+ public RestClient getRestClient() {
+ return restClient;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aai.datarouter.util.client.SvcRoutingRestClient#setRestClient()
+ */
+ @Override
+ public void setRestClient(RestClient client) {
+ this.restClient = client;
+ }
+
+
+ public String getOriginUrl() {
+ return originUrl;
+ }
+
+
+ public void setOriginUrl(String originUrl) {
+ this.originUrl = originUrl;
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/datarouter/util/client/SvcRoutingRestClient.java b/src/main/java/org/onap/aai/datarouter/util/client/SvcRoutingRestClient.java
new file mode 100644
index 0000000..3d4bf8f
--- /dev/null
+++ b/src/main/java/org/onap/aai/datarouter/util/client/SvcRoutingRestClient.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.datarouter.util.client;
+
+import org.onap.aai.restclient.client.RestClient;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+
+public interface SvcRoutingRestClient {
+
+ String getHost();
+
+ void setHost(String host);
+
+ String getPort();
+
+ void setPort(String port);
+
+ String getTargetUri();
+
+ void setTargetUri(String targetUri);
+
+ JsonNode getTargetPayload();
+
+ void setTargetPayload(JsonNode targetPayload);
+
+ RestClient getRestClient();
+
+ void setRestClient(RestClient client);
+
+}