aboutsummaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main/java/org/openecomp/aai/util
diff options
context:
space:
mode:
Diffstat (limited to 'aai-traversal/src/main/java/org/openecomp/aai/util')
-rw-r--r--aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java104
-rw-r--r--aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java704
-rw-r--r--aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java358
3 files changed, 1166 insertions, 0 deletions
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java b/aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java
new file mode 100644
index 0000000..97b7edb
--- /dev/null
+++ b/aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.util;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.activemq.broker.BrokerService;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.ModelInjestor;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class AAIAppServletContextListener implements ServletContextListener {
+
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIAppServletContextListener.class.getName());
+
+ private BrokerService broker = new BrokerService();
+
+ /**
+ * Destroys Context
+ *
+ * @param arg0 the ServletContextEvent
+ */
+ public void contextDestroyed(ServletContextEvent arg0) {
+ LOGGER.info("AAIGraph shutting down");
+ AAIGraph.getInstance().graphShutdown();
+ LOGGER.info("AAIGraph shutdown");
+
+ try {
+ broker.stop();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Initializes Context
+ *
+ * @param arg0 the ServletContextEvent
+ */
+ public void contextInitialized(ServletContextEvent arg0) {
+ System.setProperty("org.openecomp.aai.serverStarted", "false");
+ LOGGER.info("***AAI Server initialization started...");
+
+ try {
+ LOGGER.info("Loading aaiconfig.properties");
+ AAIConfig.init();
+
+ LOGGER.info("Loading error.properties");
+ ErrorLogHelper.loadProperties();
+
+ LOGGER.info("Loading graph database");
+
+ AAIGraph.getInstance();
+ ModelInjestor.getInstance();
+
+ // Jsm internal broker for aai events
+ broker = new BrokerService();
+ broker.addConnector("tcp://localhost:61446");
+ broker.setPersistent(false);
+ broker.setUseJmx(false);
+ broker.setSchedulerSupport(false);
+ broker.start();
+
+ LOGGER.info("A&AI Server initialization succcessful.");
+ System.setProperty("org.openecomp.aai.serverStarted", "true");
+
+ } catch (AAIException e) {
+ ErrorLogHelper.logException(e);
+ throw new RuntimeException("AAIException caught while initializing A&AI server", e);
+ } catch (IOException e) {
+ ErrorLogHelper.logError("AAI_4000", e.getMessage());
+ throw new RuntimeException("IOException caught while initializing A&AI server", e);
+ } catch (Exception e) {
+ LOGGER.error("Unknown failure while initializing A&AI Server", e);
+ throw new RuntimeException("Unknown failure while initializing A&AI server", e);
+ }
+ }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java b/aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java
new file mode 100644
index 0000000..7c70929
--- /dev/null
+++ b/aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java
@@ -0,0 +1,704 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.springframework.web.util.UriUtils;
+
+import org.openecomp.aai.domain.model.AAIResource;
+import org.openecomp.aai.domain.model.AAIResourceKey;
+import org.openecomp.aai.domain.model.AAIResourceKeys;
+import org.openecomp.aai.domain.model.AAIResources;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import com.google.common.base.CaseFormat;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class RestURL {
+
+
+ /*
+ * method returns a REST URL for the given node based on its nodetype and key
+ * information
+ */
+
+ /**
+ * Gets the.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @param apiVersion the api version
+ * @param isLegacyVserverUEB the is legacy vserver UEB
+ * @param isCallbackurl the is callbackurl
+ * @return the string
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static String get(TitanTransaction graph, TitanVertex node, String apiVersion, Boolean isLegacyVserverUEB, Boolean isCallbackurl) throws AAIException, UnsupportedEncodingException
+ {
+ String nodeType = node.<String>property("aai-node-type").orElse(null);
+ String url = "";
+ String currentNodeType = nodeType;
+ Boolean noMoreDependentNodes = true;
+ TitanVertex currentNode = node;
+
+ // if the caller supplies an apiVersion we'll use it, otherwise we'll just
+ // reflect back from the called URI
+ if (apiVersion == null) {
+ apiVersion = AAIApiVersion.get();
+ }
+
+ String nodeURI = null;
+ if (Boolean.parseBoolean(AAIConfig.get("aai.use.unique.key", "false")))
+ nodeURI = node.<String>property("aai-unique-key").orElse(null);
+
+ if (nodeURI != null && !nodeURI.equals("")) {
+ if (isCallbackurl) {
+ url = AAIConfig.get(AAIConstants.AAI_GLOBAL_CALLBACK_URL) + apiVersion + "/" + nodeURI;
+ return url;
+ } else {
+ url = AAIApiServerURLBase.get() + apiVersion + "/" + nodeURI;
+ return url;
+ }
+ }
+
+ // TODO
+ DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+
+ // add the url component for the dependent on nodes for the node passed in
+ while (noMoreDependentNodes) {
+ Collection <String> depNodeTypeColl = dbMaps.NodeDependencies.get(currentNodeType);
+ Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+ if (!depNodeTypeListIterator.hasNext()) {
+ noMoreDependentNodes = false;
+ break;
+ }
+
+ // Look for IN edges for the current Node and find its Parent - and make it the current Node
+ boolean foundParent = false;
+ Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+ while( inEdges.hasNext() ){
+ TitanEdge inEdge = (TitanEdge) inEdges.next();
+ Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+ if( inEdgeIsParent != null && inEdgeIsParent ){
+ foundParent = true;
+ currentNode = (TitanVertex) inEdge.otherVertex(currentNode);
+ break;
+ }
+ }
+
+ if (foundParent == false) {
+ break;
+ }
+
+ // find the key(s) and add to the url
+ // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+ String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(depNodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ String nodeUrl = null;
+ String depNodeTypePlural = dbMaps.NodePlural.get(depNodeType);
+
+ if (depNodeTypePlural != null)
+ {
+ nodeUrl = depNodeTypePlural + "/" + depNodeType + "/";
+ }
+
+ while (keyPropI.hasNext()) {
+ Object nodeKey = currentNode.<Object>property(keyPropI.next()).orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+ }
+
+ currentNodeType = depNodeType;
+
+ url = nodeUrl + url;
+ }
+ // use the name space of the highest level of unique node since lots of children node types
+ // are common ex. l-interface is in the path for pserver and vpe
+ String urlNamespace = dbMaps.NodeNamespace.get(currentNodeType) + "/";
+ urlNamespace = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, urlNamespace);
+
+ // add the url component for the node passed in
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(nodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ String nodeUrl = null;
+ String nodeTypePlural = "";
+ nodeTypePlural = dbMaps.NodePlural.get(nodeType);
+
+
+ if (nodeTypePlural != null && !nodeTypePlural.equals("")){
+ nodeUrl = nodeTypePlural + "/" + nodeType + "/";
+ } else {
+ nodeUrl = nodeType + "/";
+ }
+
+ if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+ String nodeKey = node.<String>property("port-or-interface").orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey) + "/";
+ } else {
+ while (keyPropI.hasNext()) {
+ Object nodeKey = node.<Object>property(keyPropI.next()).orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+ }
+ }
+ if (isCallbackurl) {
+ url = AAIConfig.get(AAIConstants.AAI_GLOBAL_CALLBACK_URL) + apiVersion + "/" + urlNamespace + url + nodeUrl;
+ } else {
+ url = AAIApiServerURLBase.get() + apiVersion + "/" + urlNamespace + url + nodeUrl;
+ }
+ return url;
+ }
+
+ /**
+ * Gets the search url.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @param apiVersion the api version
+ * @return the search url
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static String getSearchUrl(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+ {
+ String nodeType = node.<String>property("aai-node-type").orElse(null);
+ String url = "";
+ String currentNodeType = nodeType;
+ Boolean noMoreDependentNodes = true;
+ TitanVertex currentNode = node;
+ Boolean hasCloudRegion = false;
+
+ // if the caller supplies an apiVersion we'll use it, otherwise we'll just
+ // reflect back from the called URI
+ if (apiVersion == null) {
+ apiVersion = AAIApiVersion.get();
+ }
+
+ DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+
+ // add the url component for the dependent on nodes for the node passed in
+ while (noMoreDependentNodes) {
+ Collection <String> depNodeTypeColl = dbMaps.NodeDependencies.get(currentNodeType);
+ Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+ if (!depNodeTypeListIterator.hasNext()) {
+ noMoreDependentNodes = false;
+ break;
+ }
+
+ // Look for IN edges for the current Node and find its Parent - and make it the current Node
+ boolean foundParent = false;
+ Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+ while( inEdges.hasNext() ){
+ TitanEdge inEdge = (TitanEdge) inEdges.next();
+ Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+ if( inEdgeIsParent != null && inEdgeIsParent ){
+ foundParent = true;
+ currentNode = inEdge.otherVertex(currentNode);
+ break;
+ }
+ }
+
+ if (foundParent == false) {
+ break;
+ }
+
+ // find the key(s) and add to the url
+ // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+ String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(depNodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ String nodeUrl = null;
+ String depNodeTypePlural = dbMaps.NodePlural.get(depNodeType);
+
+ if (depNodeTypePlural != null)
+ nodeUrl = depNodeTypePlural + "/" + depNodeType + "/";
+
+ while (keyPropI.hasNext()) {
+ Object nodeKey = currentNode.<Object>property(keyPropI.next()).orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+ }
+
+ currentNodeType = depNodeType;
+
+ url = nodeUrl + url;
+ }
+ // use the name space of the highest level of unique node since lots of children node types
+ // are common ex. l-interface is in the path for pserver and vpe
+ String urlNamespace = dbMaps.NodeNamespace.get(currentNodeType) + "/";
+ urlNamespace = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, urlNamespace);
+
+ // add the url component for the node passed in
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(nodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ String nodeUrl = null;
+ String nodeTypePlural = "";
+ nodeTypePlural = dbMaps.NodePlural.get(nodeType);
+
+ if (nodeTypePlural != null && !nodeTypePlural.equals(""))
+ nodeUrl = nodeTypePlural + "/" + nodeType + "/";
+ else
+ nodeUrl = nodeType + "/";
+
+ if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+ String nodeKey = node.<String>property("port-or-interface").orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey) + "/";
+ } else {
+ while (keyPropI.hasNext()) {
+ Object nodeKey = node.<Object>property(keyPropI.next()).orElse(null);
+ nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+ }
+ }
+
+ String nodeVersion = dbMaps.NodeVersionInfoMap.get(nodeType);
+ String urlVersion = null;
+ int nodeVerNum = Integer.parseInt(nodeVersion.substring(1));
+ int apiVerNum = Integer.parseInt(apiVersion.substring(1));
+
+ if (hasCloudRegion) {
+ if (apiVerNum < 7)
+ urlVersion = "v7"; // or set to the latest version?
+ else
+ urlVersion = apiVersion;
+ } else {
+ if (nodeVerNum == apiVerNum || nodeVerNum < apiVerNum)
+ urlVersion = apiVersion;
+ else
+ urlVersion = nodeVersion;
+ }
+ url = AAIApiServerURLBase.get() + urlVersion + "/" + urlNamespace + url + nodeUrl;
+ //remove the trailing "/"
+ url = url.substring(0, url.length()-1);
+ return url;
+ }
+
+ /**
+ * Gets the.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @return the string
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static String get(TitanTransaction graph, TitanVertex node) throws AAIException, UnsupportedEncodingException
+ {
+ return get(graph, node, null, false, false);
+ }
+
+ /**
+ * Gets the.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @param apiVersion the api version
+ * @return the string
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static String get(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+ {
+ return get(graph, node, apiVersion, false, false);
+ }
+
+ /**
+ * Gets the.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @param apiVersion the api version
+ * @param isLegacyVserverUEB the is legacy vserver UEB
+ * @return the string
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static String get(TitanTransaction graph, TitanVertex node, String apiVersion, Boolean isLegacyVserverUEB) throws AAIException, UnsupportedEncodingException
+ {
+ return get(graph, node, apiVersion, isLegacyVserverUEB, false);
+ }
+
+ /**
+ * Gets the key hashes.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @return the key hashes
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static LinkedHashMap<String, Object> getKeyHashes(TitanTransaction graph, TitanVertex node) throws AAIException, UnsupportedEncodingException
+ {
+ return getKeyHashes(graph, node, null);
+ }
+
+ /*
+ * method returns a Hash of Hashes for each parents keys for the given node based on its nodetype
+ * Special cases for REST URLs:
+ * - old URLS for vserver, ipaddress and volume node types for v2/v3
+ * - images, flavor, vnic and l-interface node types will return new url
+ * - nodetypes with multiple keys such as service capability
+ * - nodetypes with multiple keys such as ipaddress where we use one key in the URL
+ * - cvlan-tags and *list nodetypes - have special or no plurals - they get handled via the hash Map
+ */
+
+ /**
+ * Gets the key hashes.
+ *
+ * @param graph the graph
+ * @param node the node
+ * @param apiVersion the api version
+ * @return the key hashes
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static LinkedHashMap <String,Object> getKeyHashes(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+ {
+ String nodeType = node.<String>property("aai-node-type").orElse(null);
+ Boolean noMoreDependentNodes = true;
+ TitanVertex currentNode = node;
+
+ if (apiVersion == null || apiVersion.equals("")) {
+ apiVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+ }
+
+ DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(apiVersion);
+
+ // Hash of hashes of keys for each node and its ancestry
+ LinkedHashMap <String,Object> returnHash = new LinkedHashMap <String,Object> ();
+
+ // create the hash for the keys for the node passed in
+ HashMap <String,Object> thisNodeHash = new HashMap <String,Object> ();
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(nodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+ String nodeKeyValue = node.<String>property("port-or-interface").orElse(null);
+ thisNodeHash.put("port-or-interface", nodeKeyValue);
+ } else {
+ while (keyPropI.hasNext()) {
+ String nodeKeyName = keyPropI.next();
+ Object nodeKeyValue = node.<Object>property(nodeKeyName).orElse(null);
+ thisNodeHash.put(nodeKeyName, nodeKeyValue);
+ nodeKeyName = nodeType + "." + nodeKeyName;
+ }
+ }
+ returnHash.putAll(thisNodeHash);
+
+ // create and add the hashes for the dependent nodes for the node passed in
+ while (noMoreDependentNodes) {
+// Collection <String> depNodeTypeColl = DbRules.NodeDependencies.get(currentNodeType);
+// Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+ HashMap <String,Object> depNodeHash = new HashMap <String,Object> ();
+//
+// if (!depNodeTypeListIterator.hasNext()) {
+// noMoreDependentNodes = false;
+// break;
+// }
+
+ boolean foundParent = false;
+
+ // Look for IN edges for the current Node and find its Parent - and make it the current Node
+ Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+ while( inEdges.hasNext() ){
+ TitanEdge inEdge = (TitanEdge) inEdges.next();
+ Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+ if( inEdgeIsParent != null && inEdgeIsParent ){
+ currentNode = inEdge.otherVertex(currentNode);
+ foundParent = true;
+ break;
+ }
+ }
+ if (foundParent == false) {
+ break;
+ }
+
+ // find the key(s) and add to the url
+ // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+ String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+ keyProps = dbMaps.NodeKeyProps.get(depNodeType);
+ keyPropI = keyProps.iterator();
+
+ while (keyPropI.hasNext()) {
+ String nodeKeyName = keyPropI.next();
+ Object nodeKeyValue = currentNode.<Object>property(nodeKeyName).orElse(null);
+ nodeKeyName = depNodeType + "." + nodeKeyName;
+ // key name will be like tenant.tenant-id
+
+ depNodeHash.put(nodeKeyName, nodeKeyValue);
+ }
+ returnHash.putAll(depNodeHash);
+ }
+
+ return returnHash;
+ }
+
+ /*
+ * method returns a Hash of Hashes for each parents keys for the given node based on its nodeURI
+ * Special cases for REST URLs:
+ * - images, flavor, vnic and l-interface node types will return new url
+ * - nodetypes with multiple keys such as service capability
+ * - nodetypes with multiple keys such as ipaddress where we use one key in the URL
+ * - cvlan-tags and *list nodetypes - have special or no plurals - they get handled via the hash Map
+ */
+
+ /**
+ * Gets the key hashes.
+ *
+ * @param nodeURI the node URI
+ * @return the key hashes
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static LinkedHashMap <String,Object> getKeyHashes(String nodeURI) throws AAIException, UnsupportedEncodingException
+ {
+ return getKeyHashes(nodeURI, null);
+
+ }
+
+ /**
+ * Gets the key hashes.
+ *
+ * @param nodeURI the node URI
+ * @param apiVersion the api version
+ * @return the key hashes
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public static LinkedHashMap <String,Object> getKeyHashes(String nodeURI, String apiVersion) throws AAIException, UnsupportedEncodingException
+ {
+
+ if (apiVersion == null || apiVersion.equals(""))
+ apiVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+
+ DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(apiVersion);
+
+ // Hash of hashes of keys for each node and its ancestry
+ LinkedHashMap <String,Object> returnHash = new LinkedHashMap <String,Object> ();
+
+ String path = nodeURI.replaceFirst("^/", "");
+ Path p = Paths.get(path);
+ int index = p.getNameCount() - 2; // index of where we expect the node type to be
+
+ // if the node type has one key
+ String currentNodeType = p.getName(index).toString();
+ // if the node type has two keys - this assumes max 2 keys
+ if (!dbMaps.NodeKeyProps.containsKey(currentNodeType))
+ currentNodeType = p.getName(--index).toString();
+
+ // create the hash for the keys for the node passed in
+ LinkedHashMap <String,Object> thisNodeHash = new LinkedHashMap <String,Object> ();
+ Collection <String> keyProps = dbMaps.NodeKeyProps.get(currentNodeType);
+ Iterator <String> keyPropI = keyProps.iterator();
+
+ if (currentNodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+ String nodeKeyValue = p.getName(index + 1).toString();
+ thisNodeHash.put("port-or-interface", nodeKeyValue);
+ } else {
+ int j = 1;
+ while (keyPropI.hasNext()) {
+ String nodeKeyName = currentNodeType + "." + keyPropI.next();
+ String nodeKeyValue = p.getName(index + j++).toString();
+ thisNodeHash.put(nodeKeyName, nodeKeyValue);
+ }
+ }
+ returnHash.putAll(thisNodeHash);
+ if (!currentNodeType.contains("-list"))
+ index -= 3;
+ else
+ index -= 2; // no plural in this case
+
+
+ // create and add the hashes for the dependent nodes for the node passed in
+ LinkedHashMap <String,Object> depNodeHash = new LinkedHashMap <String,Object> ();
+ String depNodeType = null;
+ while (index >= 2) {
+ if (depNodeType == null) depNodeType = p.getName(index).toString();
+ //System.out.println("index=" + index);
+ // if the node type has one key
+ currentNodeType = p.getName(index).toString();
+ // if the node type has two keys - this assumes max 2 keys
+ if (!dbMaps.NodeKeyProps.containsKey(currentNodeType))
+ currentNodeType = p.getName(--index).toString();
+
+ keyProps = dbMaps.NodeKeyProps.get(currentNodeType);
+ keyPropI = keyProps.iterator();
+
+ if (currentNodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+ String nodeKeyValue = p.getName(index + 1).toString();
+ depNodeHash.put("port-or-interface", nodeKeyValue);
+ } else {
+ int j = 1;
+ while (keyPropI.hasNext()) {
+ String nodeKeyName = currentNodeType + "." + keyPropI.next();
+ String nodeKeyValue = p.getName(index + j++).toString();
+ depNodeHash.put(nodeKeyName, nodeKeyValue);
+ }
+ }
+
+ if (!currentNodeType.contains("-list"))
+ index -= 3;
+ else
+ index -= 2; // no plural in this case
+ }
+ if (depNodeType != null)
+ returnHash.putAll(depNodeHash);
+
+ return returnHash;
+ }
+
+ /**
+ * Parses the uri.
+ *
+ * @param allKeys the all keys
+ * @param keyList the key list
+ * @param uri the uri
+ * @param aaiExtMap the aai ext map
+ * @return the AAI resource
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws AAIException the AAI exception
+ */
+ public static AAIResource parseUri(HashMap<String, String> allKeys, LinkedHashMap<String,
+ LinkedHashMap<String,Object>> keyList, String uri,
+ AAIExtensionMap aaiExtMap) throws UnsupportedEncodingException, AAIException {
+
+ String[] ps = uri.split("/");
+
+ String apiVersion = ps[0];
+ aaiExtMap.setApiVersion(apiVersion);
+
+ AAIResources aaiResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer.get(apiVersion);
+
+ String namespace = ps[1];
+
+ aaiExtMap.setNamespace(namespace);
+
+ // /vces/vce/{vnf-id}/port-groups/port-group/{port-group-id}/cvlan-tag-entry/cvlan-tag/{cvlan-tag}
+
+ // FullName -> /Vces/Vce/PortGroups/PortGroup/CvlanTagEntry/CvlanTag <-
+
+ String fullResourceName = "/" + CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, namespace);
+ AAIResources theseResources = new AAIResources();
+
+ StringBuffer thisUri = new StringBuffer();
+
+ // the URI config option in the props file has a trailing slash
+ thisUri.append("/" + namespace);
+
+ boolean firstNode = true;
+
+ AAIResource lastResource = null;
+
+ for (int i = 2; i < ps.length; i++) {
+
+ AAIResource aaiRes;
+ StringBuffer tmpResourceName = new StringBuffer();
+
+ String p = ps[i];
+ String seg =ps[i];
+
+ thisUri.append("/" + seg);
+
+ tmpResourceName.append(fullResourceName);
+
+ if (seg.equals("cvlan-tag")) {
+ seg = "cvlan-tag-entry";
+ }
+ tmpResourceName.append("/" + CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, seg));
+
+ String tmpResource = tmpResourceName.toString();
+
+ if (aaiResources.getAaiResources().containsKey(tmpResource)) {
+ aaiRes = aaiResources.getAaiResources().get(tmpResource);
+ lastResource = aaiRes;
+ theseResources.getAaiResources().put(tmpResource, aaiRes);
+ fullResourceName = tmpResource;
+ if ("node".equals(aaiRes.getResourceType())) {
+
+ if (firstNode == true) {
+ aaiExtMap.setTopObjectFullResourceName(fullResourceName);
+ firstNode = false;
+ }
+
+ // get the keys, which will be in order and the next path segment(s)
+ AAIResourceKeys keys = aaiRes.getAaiResourceKeys();
+
+ LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+
+ // there might not be another path segment
+ if ( (i + 1) < ps.length) {
+
+ for (AAIResourceKey rk : keys.getAaiResourceKey()) {
+ String p1 = ps[++i];
+ String encodedKey = p1.toString();
+ thisUri.append("/" + encodedKey);
+ String decodedKey = UriUtils.decode(p1.toString(), "UTF-8");
+ subKeyList.put(rk.getKeyName(), decodedKey);
+ }
+ keyList.put(tmpResource, subKeyList);
+ // this is the key
+ allKeys.put(tmpResource, thisUri.toString());
+ }
+ } else { // examples sit directly under the container level, should probably be query params!!!
+ if ( (i + 1) < ps.length) {
+ String p1 = ps[i+1];
+ if (p1.toString().equals("example") || p1.toString().equals("singletonExample")) {
+ LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+ subKeyList.put("container|example", p1.toString());
+ keyList.put(tmpResource, subKeyList);
+ }
+ }
+ }
+ } else {
+ if (p.equals("relationship-list")) {
+ LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+ subKeyList.put("container|relationship", p.toString());
+ keyList.put(tmpResource, subKeyList);
+ } else if ( p.toString().length() > 0 && !p.toString().equals("example") && !p.toString().equals("singletonExample")
+ && !p.toString().equals("relationship") ) {
+ // this means the URL will break the model, so we bail
+ throw new AAIException("AAI_3001", "bad path");
+ }
+ }
+ }
+ aaiExtMap.setUri(AAIConfig.get("aai.global.callback.url") + apiVersion + thisUri.toString());
+ aaiExtMap.setNotificationUri(AAIConfig.get("aai.global.callback.url") + AAIConfig.get("aai.notification.current.version") + thisUri.toString());
+ aaiExtMap.setFullResourceName(fullResourceName);
+ return lastResource;
+ }
+
+}
+
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java b/aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
new file mode 100644
index 0000000..996abba
--- /dev/null
+++ b/aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
@@ -0,0 +1,358 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.util;
+
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.bind.Marshaller;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.openecomp.aai.dmaap.AAIDmaapEventJMSProducer;
+import org.openecomp.aai.domain.notificationEvent.NotificationEvent;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+
+public class StoreNotificationEvent {
+
+ private AAIDmaapEventJMSProducer messageProducer;
+ private String fromAppId = "";
+ private String transId = "";
+
+ /**
+ * Instantiates a new store notification event.
+ */
+ public StoreNotificationEvent() {
+ this.messageProducer = new AAIDmaapEventJMSProducer();
+ Message inMessage = PhaseInterceptorChain.getCurrentMessage().getExchange().getInMessage();
+ Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS));
+ if (headersList != null) {
+ List<String> xt = headersList.get("X-TransactionId");
+ if (xt != null) {
+ for (String transIdValue : xt) {
+ transId = transIdValue;
+ }
+ }
+ List<String> fa = headersList.get("X-FromAppId");
+ if (fa != null) {
+ for (String fromAppIdValue : fa) {
+
+ fromAppId = fromAppIdValue;
+ }
+ }
+ }
+ }
+
+ /**
+ * Store event.
+ *
+ * @param eh
+ * the eh
+ * @param obj
+ * the obj
+ * @throws AAIException
+ * the AAI exception
+ */
+ public void storeEvent(NotificationEvent.EventHeader eh, Object obj) throws AAIException {
+
+ if (obj == null) {
+ throw new AAIException("AAI_7350");
+ }
+
+ org.openecomp.aai.domain.notificationEvent.ObjectFactory factory = new org.openecomp.aai.domain.notificationEvent.ObjectFactory();
+
+ org.openecomp.aai.domain.notificationEvent.NotificationEvent ne = factory.createNotificationEvent();
+
+ if (eh.getId() == null) {
+ eh.setId(genDate2() + "-" + UUID.randomUUID().toString());
+ }
+ if (eh.getTimestamp() == null) {
+ eh.setTimestamp(genDate());
+ }
+
+ // there's no default, but i think we want to put this in hbase?
+
+ if (eh.getEntityLink() == null) {
+ eh.setEntityLink("UNK");
+ }
+
+ if (eh.getAction() == null) {
+ eh.setAction("UNK");
+ }
+
+ if (eh.getEventType() == null) {
+ eh.setEventType(AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+ }
+
+ if (eh.getDomain() == null) {
+ eh.setDomain(AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+ }
+
+ if (eh.getSourceName() == null) {
+ eh.setSourceName(AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+ }
+
+ if (eh.getSequenceNumber() == null) {
+ eh.setSequenceNumber(AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+ }
+
+ if (eh.getSeverity() == null) {
+ eh.setSeverity(AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+ }
+
+ if (eh.getVersion() == null) {
+ eh.setVersion(AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+ }
+
+ ne.setCambriaPartition(AAIConstants.UEB_PUB_PARTITION_AAI);
+ ne.setEventHeader(eh);
+ ne.setEntity(obj);
+
+ try {
+ PojoUtils pu = new PojoUtils();
+ String entityJson = pu.getJsonFromObject(ne);
+ sendToDmaapJmsQueue(entityJson);
+ } catch (Exception e) {
+ throw new AAIException("AAI_7350", e);
+ }
+ }
+
+ /**
+ * Store dynamic event.
+ *
+ * @param notificationJaxbContext
+ * the notification jaxb context
+ * @param notificationVersion
+ * the notification version
+ * @param eventHeader
+ * the event header
+ * @param obj
+ * the obj
+ * @throws AAIException
+ * the AAI exception
+ */
+ public void storeDynamicEvent(DynamicJAXBContext notificationJaxbContext, String notificationVersion, DynamicEntity eventHeader, DynamicEntity obj) throws AAIException {
+
+ if (obj == null) {
+ throw new AAIException("AAI_7350");
+ }
+
+ DynamicEntity notificationEvent = notificationJaxbContext.getDynamicType("inventory.aai.inventory.org." + notificationVersion + ".NotificationEvent").newDynamicEntity();
+
+ if (eventHeader.get("id") == null) {
+ eventHeader.set("id", genDate2() + "-" + UUID.randomUUID().toString());
+ }
+
+ if (eventHeader.get("timestamp") == null) {
+ eventHeader.set("timestamp", genDate());
+ }
+
+ if (eventHeader.get("entityLink") == null) {
+ eventHeader.set("entityLink", "UNK");
+ }
+
+ if (eventHeader.get("action") == null) {
+ eventHeader.set("action", "UNK");
+ }
+
+ if (eventHeader.get("eventType") == null) {
+ eventHeader.set("eventType", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+ }
+
+ if (eventHeader.get("domain") == null) {
+ eventHeader.set("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+ }
+
+ if (eventHeader.get("sourceName") == null) {
+ eventHeader.set("sourceName", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+ }
+
+ if (eventHeader.get("sequenceNumber") == null) {
+ eventHeader.set("sequenceNumber", AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+ }
+
+ if (eventHeader.get("severity") == null) {
+ eventHeader.set("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+ }
+
+ if (eventHeader.get("version") == null) {
+ eventHeader.set("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+ }
+
+ if (notificationEvent.get("cambriaPartition") == null) {
+ notificationEvent.set("cambriaPartition", AAIConstants.UEB_PUB_PARTITION_AAI);
+ }
+
+ notificationEvent.set("eventHeader", eventHeader);
+ notificationEvent.set("entity", obj);
+
+ try {
+ StringWriter result = new StringWriter();
+
+ Marshaller marshaller = notificationJaxbContext.createMarshaller();
+ marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.MEDIA_TYPE, "application/json");
+ marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_INCLUDE_ROOT, false);
+ marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, false);
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
+ marshaller.marshal(notificationEvent, result);
+
+ this.sendToDmaapJmsQueue(result.toString());
+
+ } catch (Exception e) {
+ throw new AAIException("AAI_7350", e);
+ }
+ }
+
+ public void storeEvent(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException {
+ if (obj == null) {
+ throw new AAIException("AAI_7350");
+ }
+
+ try {
+ final Introspector notificationEvent = loader.introspectorFromName("notification-event");
+
+ if (eventHeader.getValue("id") == null) {
+ eventHeader.setValue("id", genDate2() + "-" + UUID.randomUUID().toString());
+ }
+
+ if (eventHeader.getValue("timestamp") == null) {
+ eventHeader.setValue("timestamp", genDate());
+ }
+
+ if (eventHeader.getValue("entity-link") == null) {
+ eventHeader.setValue("entity-link", "UNK");
+ }
+
+ if (eventHeader.getValue("action") == null) {
+ eventHeader.setValue("action", "UNK");
+ }
+
+ if (eventHeader.getValue("event-type") == null) {
+ eventHeader.setValue("event-type", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+ }
+
+ if (eventHeader.getValue("domain") == null) {
+ eventHeader.setValue("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+ }
+
+ if (eventHeader.getValue("source-name") == null) {
+ eventHeader.setValue("source-name", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+ }
+
+ if (eventHeader.getValue("sequence-number") == null) {
+ eventHeader.setValue("sequence-number", AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+ }
+
+ if (eventHeader.getValue("severity") == null) {
+ eventHeader.setValue("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+ }
+
+ if (eventHeader.getValue("version") == null) {
+ eventHeader.setValue("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+ }
+
+ if (notificationEvent.getValue("cambria-partition") == null) {
+ notificationEvent.setValue("cambria-partition", AAIConstants.UEB_PUB_PARTITION_AAI);
+ }
+
+ notificationEvent.setValue("event-header", eventHeader.getUnderlyingObject());
+ notificationEvent.setValue("entity", obj.getUnderlyingObject());
+
+ String entityJson = notificationEvent.marshal(false);
+ sendToDmaapJmsQueue(entityJson);
+ } catch (JSONException e) {
+ throw new AAIException("AAI_7350", e);
+ } catch (AAIUnknownObjectException e) {
+ throw new AAIException("AAI_7350", e);
+ }
+ }
+
+ private void sendToDmaapJmsQueue(String entityString) throws JSONException {
+
+ JSONObject entityJsonObject = new JSONObject(entityString);
+
+ JSONObject entityJsonObjectUpdated = new JSONObject();
+ JSONObject finalJson = new JSONObject();
+
+ JSONObject entityHeader = entityJsonObject.getJSONObject("event-header");
+ String cambriaPartition = entityJsonObject.getString("cambria.partition");
+
+ entityJsonObject.remove("event-header");
+ entityJsonObject.remove("cambria.partition");
+
+ entityJsonObjectUpdated.put("event-header", entityHeader);
+ entityJsonObjectUpdated.put("cambria.partition", cambriaPartition);
+
+ Iterator<String> iter = entityJsonObject.keys();
+ JSONObject entity = new JSONObject();
+ if (iter.hasNext()) {
+ entity = entityJsonObject.getJSONObject(iter.next());
+ }
+
+ entityJsonObjectUpdated.put("entity", entity);
+
+ finalJson.put("event-topic", "AAI-EVENT");
+ finalJson.put("transId", transId);
+ finalJson.put("fromAppId", fromAppId);
+ finalJson.put("fullId", "");
+ finalJson.put("aaiEventPayload", entityJsonObjectUpdated);
+
+ messageProducer.sendMessageToDefaultDestination(finalJson);
+ }
+
+ /**
+ * Gen date.
+ *
+ * @return the string
+ */
+ public static String genDate() {
+ Date date = new Date();
+ DateFormat formatter = new SimpleDateFormat("YYYYMMdd-HH:mm:ss:SSS");
+ return formatter.format(date);
+ }
+
+ /**
+ * Gen date 2.
+ *
+ * @return the string
+ */
+ public static String genDate2() {
+ Date date = new Date();
+ DateFormat formatter = new SimpleDateFormat("YYYYMMddHHmmss");
+ return formatter.format(date);
+ }
+
+}