X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fdatarouter%2Fpolicy%2FEntityEventPolicy.java;h=6660a79a7ce74c4b9e9e7feb980517b1586f5f86;hb=3a50e4c2dd8bdfca4b4c834316abee075448f27e;hp=b6b7fd860e9d54d37a752dace1a74d5fe72ef3df;hpb=e234ce76b9eee92b2a16450f773e4a99013d0178;p=aai%2Fdata-router.git diff --git a/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java index b6b7fd8..6660a79 100644 --- a/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java +++ b/src/main/java/org/onap/aai/datarouter/policy/EntityEventPolicy.java @@ -56,6 +56,7 @@ import org.onap.aai.util.CrossEntityReference; import org.onap.aai.util.EntityOxmReferenceHelper; import org.onap.aai.util.ExternalOxmModelProcessor; import org.onap.aai.schema.OxmModelLoader; +import org.onap.aai.setup.SchemaVersions; import org.onap.aai.util.Version; import org.onap.aai.util.VersionedOxmEntities; import org.onap.aai.cl.api.Logger; @@ -96,16 +97,16 @@ public class EntityEventPolicy implements Processor { /** 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; @@ -130,7 +131,7 @@ public class EntityEventPolicy implements Processor { topographicalSearchIndex = config.getSearchTopographySearchIndex(); aggregateGenericVnfIndex = config.getSearchAggregationVnfIndex(); autosuggestIndex = config.getSearchEntityAutoSuggestIndex(); - + // Instantiate the agent that we will use for interacting with the Search Service. searchAgent = new SearchServiceAgent(config.getSearchCertName(), config.getSearchKeystore(), @@ -143,7 +144,7 @@ public class EntityEventPolicy implements Processor { this.externalOxmModelProcessors = new ArrayList<>(); this.externalOxmModelProcessors.add(EntityOxmReferenceHelper.getInstance()); OxmModelLoader.registerExternalOxmModelProcessors(externalOxmModelProcessors); - OxmModelLoader.loadModels(); + OxmModelLoader.loadModels(config.getSchemaVersions(), config.getSchemaLocationsBean()); oxmVersionContextMap = OxmModelLoader.getVersionContextMap(); parseLatestOxmVersion(); } @@ -171,11 +172,11 @@ public class EntityEventPolicy implements Processor { } public void startup() { - + // Create the indexes in the search service if they do not already exist. searchAgent.createSearchIndex(entitySearchIndex, ENTITY_SEARCH_SCHEMA); searchAgent.createSearchIndex(topographicalSearchIndex, TOPOGRAPHICAL_SEARCH_SCHEMA); - + logger.info(EntityEventPolicyMsgs.ENTITY_EVENT_POLICY_REGISTERED); } @@ -207,7 +208,7 @@ public class EntityEventPolicy implements Processor { logger.debug(EntityEventPolicyMsgs.DISCARD_EVENT_VERBOSE, errorMsg, payload); setResponse(exchange, ResponseType.FAILURE, additionalInfo); } - + @Override public void process(Exchange exchange) throws Exception { @@ -215,7 +216,7 @@ public class EntityEventPolicy implements Processor { String uebPayload = exchange.getIn().getBody().toString(); - JsonNode uebAsJson =null; + JsonNode uebAsJson = null; ObjectMapper mapper = new ObjectMapper(); try{ uebAsJson = mapper.readTree(uebPayload); @@ -230,7 +231,7 @@ public class EntityEventPolicy implements Processor { 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); @@ -392,14 +393,14 @@ public class EntityEventPolicy implements Processor { * 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: + * 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 + 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 @@ -409,116 +410,122 @@ public class EntityEventPolicy implements Processor { JSONObject entityJsonObject = getUebEntity(uebPayload); - if (entityJsonObject != null) { - JsonNode entityJsonNode = convertToJsonNode(entityJsonObject.toString()); - - String parentEntityType = entityType; - - String targetEntityUrl = entityLink; + JsonNode entityJsonNode = convertToJsonNode(entityJsonObject.toString()); + + String parentEntityType = entityType; + + String targetEntityUrl = entityLink; - for (Map.Entry entry : crossEntityRefMap.entrySet()) { + for (Map.Entry 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 foundNodes = new ArrayList<>(); + /* + * if we know service-subscription is in the tree, then we can pull our all instances and + * process from there. + */ - RouterServiceUtil.extractObjectsByKey(entityJsonNode, key, foundNodes); + String key = entry.getKey(); + CrossEntityReference cerDescriptor = entry.getValue(); - if (!foundNodes.isEmpty()) { + ArrayList foundNodes = new ArrayList<>(); - 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/"; - } - } + RouterServiceUtil.extractObjectsByKey(entityJsonNode, key, foundNodes); - List extractedParentEntityAttributeValues = new ArrayList<>(); + if (!foundNodes.isEmpty()) { - RouterServiceUtil.extractFieldValuesFromObject(n, cerDescriptor.getAttributeNames(), - extractedParentEntityAttributeValues); + 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 nestedTargetEntityInstances = new ArrayList<>(); - RouterServiceUtil.extractObjectsByKey(n, cerDescriptor.getTargetEntityType(), - nestedTargetEntityInstances); + List extractedParentEntityAttributeValues = new ArrayList<>(); - 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 - */ + RouterServiceUtil.extractFieldValuesFromObject(n, cerDescriptor.getAttributeNames(), + extractedParentEntityAttributeValues); - // 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"); - } + List nestedTargetEntityInstances = new ArrayList<>(); + RouterServiceUtil.extractObjectsByKey(n, cerDescriptor.getTargetEntityType(), + nestedTargetEntityInstances); - OxmEntityDescriptor searchableDescriptor = oxmEntities.getSearchableEntityDescriptor(cerDescriptor.getTargetEntityType()); + 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 + */ - if (searchableDescriptor != null) { + // 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.getSearchableAttributes().isEmpty()) { + if (searchableDescriptor != null) { - AaiEventEntity entityToSync = null; + if (!searchableDescriptor.getSearchableAttributes().isEmpty()) { - try { + AaiEventEntity entityToSync = null; - entityToSync = getPopulatedEntity(targetEntityInstance, searchableDescriptor); + try { - /* - * Ready to do some ElasticSearch ops - */ + entityToSync = getPopulatedEntity(targetEntityInstance, searchableDescriptor); - for (String parentCrossEntityReferenceAttributeValue : extractedParentEntityAttributeValues) { - entityToSync.addCrossEntityReferenceValue(parentCrossEntityReferenceAttributeValue); - } + /* + * Ready to do some ElasticSearch ops + */ - entityToSync.setLink(targetEntityUrl); - entityToSync.deriveFields(); + for (String parentCrossEntityReferenceAttributeValue : extractedParentEntityAttributeValues) { + entityToSync + .addCrossEntityReferenceValue(parentCrossEntityReferenceAttributeValue); + } - updateCerInEntity(entityToSync); + entityToSync.setLink(targetEntityUrl); + entityToSync.deriveFields(); - } catch (NoSuchAlgorithmException e) { - logger.debug(e.getMessage()); - } - } - } else { - logger.debug(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC, - "failure to find searchable descriptor for type " - + cerDescriptor.getTargetEntityType()); - } - } + updateCerInEntity(entityToSync); + } catch (NoSuchAlgorithmException e) { + logger.debug(e.getMessage()); } - + } } else { - logger.debug(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC, - "failed to find 0 instances of cross-entity-reference with entity " + key); + logger.debug(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC, + "failure to find searchable descriptor for type " + + cerDescriptor.getTargetEntityType()); } + } } - } else { - logger.info(EntityEventPolicyMsgs.FAILED_TO_PARSE_UEB_PAYLOAD, "Unable to get UEB object"); + + } 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"); + logger.info(EntityEventPolicyMsgs.CROSS_ENTITY_REFERENCE_SYNC, "skipped due to OXM model for " + + topEntityType + " does not contain a cross-entity-reference entity"); } /* @@ -603,7 +610,7 @@ public class EntityEventPolicy implements Processor { } OxmEntityDescriptor desc = rootDescriptor.get(entityType); - + if (desc == null) { return Collections.emptyList(); } @@ -878,11 +885,11 @@ public class EntityEventPolicy implements Processor { if (HttpUtil.isHttpResponseClassSuccess(storedEntity.getResultCode())) { /* - * NOTES: aaiEventEntity (ie the nested entity) may contain a subset of properties of - * the pre-existing object, + * 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 etag = storedEntity.getHeaders().get(Headers.ETAG); if (etag != null && !etag.isEmpty()) { @@ -891,7 +898,7 @@ public class EntityEventPolicy implements Processor { logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE, entitySearchIndex, entityId); } - + ArrayList sourceObject = new ArrayList<>(); NodeUtils.extractObjectsByKey( NodeUtils.convertJsonStrToJsonNode(storedEntity.getResult()), @@ -899,7 +906,7 @@ public class EntityEventPolicy implements Processor { if (!sourceObject.isEmpty()) { JsonNode node = sourceObject.get(0); - final String sourceCer = NodeUtils.extractFieldValueFromObject(node, + final String sourceCer = NodeUtils.extractFieldValueFromObject(node, "crossEntityReferenceValues"); String newCer = aaiEventEntity.getCrossReferenceEntityValues(); boolean hasNewCer = true; @@ -910,7 +917,7 @@ public class EntityEventPolicy implements Processor { hasNewCer = false; } } - + if (hasNewCer){ // Do the PUT with new CER ((ObjectNode)node).put("crossEntityReferenceValues", newCer); @@ -937,13 +944,13 @@ public class EntityEventPolicy implements Processor { /** * 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, + protected void handleSearchServiceOperation(DocumentStoreDataEntity eventEntity, String action, String index) { try { @@ -977,7 +984,7 @@ public class EntityEventPolicy implements Processor { } 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); @@ -991,7 +998,7 @@ public class EntityEventPolicy implements Processor { logger.error(EntityEventPolicyMsgs.NO_ETAG_AVAILABLE_FAILURE, index, entityId); } - + /* * The Spring-Boot version of the search-data-service rejects the DELETE operation unless * we specify a Content-Type. @@ -1063,7 +1070,7 @@ public class EntityEventPolicy implements Processor { // 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 */