diff options
Diffstat (limited to 'aai-traversal/src/main/java/org/openecomp/aai/util')
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); + } + +} |