diff options
author | Steven Blimkie <Steven.Blimkie@amdocs.com> | 2017-10-12 15:08:25 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2017-10-12 15:08:25 +0000 |
commit | 7af00564f04e1b8f441536fce5bdf31d59fe722c (patch) | |
tree | c0f87c4746f420f6b0c9af72623074cd75dfe779 /src/main/java/org/onap | |
parent | 14326b84c4a78c17de6cedf50072cd4096d8a02d (diff) | |
parent | 2a5ff133471c5a69b0dfd760d2743f48112da9a0 (diff) |
Merge "Renaming openecomp to onap"
Diffstat (limited to 'src/main/java/org/onap')
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 a848bd2..ce83b15 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); + +} |