/*- * ============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.db.schema; import com.google.common.collect.Multimap; import com.thinkaurelius.titan.core.Cardinality; import com.thinkaurelius.titan.core.Multiplicity; import com.thinkaurelius.titan.core.schema.SchemaStatus; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Set; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.openecomp.aai.db.AAIProperties; import org.openecomp.aai.dbmodel.DbEdgeRules; import org.openecomp.aai.introspection.Introspector; import org.openecomp.aai.introspection.Loader; import org.openecomp.aai.introspection.LoaderFactory; import org.openecomp.aai.introspection.ModelType; import org.openecomp.aai.introspection.Version; import org.openecomp.aai.logging.LogLineBuilder; import org.openecomp.aai.util.AAIConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class AuditOXM extends Auditor { private static final Logger log = LoggerFactory.getLogger(AuditOXM.class); private Set allObjects; private final LogLineBuilder llBuilder = new LogLineBuilder(); /** * Instantiates a new audit OXM. * * @param version the version */ public AuditOXM(Version version) { Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, version, llBuilder); Set objectNames = getAllObjects(version); allObjects = new HashSet<>(); for (String key : objectNames) { Introspector temp = loader.introspectorFromName(key); allObjects.add(temp); this.createDBProperties(temp); } for (Introspector temp : allObjects) { this.createDBIndexes(temp); } createEdgeLabels(); } /** * Gets the all objects. * * @param version the version * @return the all objects */ private Set getAllObjects(Version version) { String fileName = AAIConstants.AAI_HOME_ETC_OXM + "aai_oxm_" + version.toString() + ".xml"; Set result = new HashSet<>(); DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); try { docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.parse(fileName); NodeList list = doc.getElementsByTagName("java-type"); for (int i = 0; i < list.getLength(); i++) { result.add(list.item(i).getAttributes().getNamedItem("name").getNodeValue()); } } catch (ParserConfigurationException | SAXException | IOException e) { // TODO Auto-generated catch block log.error(e.getLocalizedMessage(), e); } result.remove("EdgePropNames"); return result; } /** * Creates the DB properties. * * @param temp the temp */ private void createDBProperties(Introspector temp) { List objectProperties = temp.getProperties(); for (String prop : objectProperties) { if (!properties.containsKey(prop)) { DBProperty dbProperty = new DBProperty(); dbProperty.setName(prop); if (temp.isListType(prop)) { handleListTypePropertyForIntrospector(dbProperty, prop, temp); } else { handleNonListTypePropertyForIntrospector(dbProperty, prop, temp); } } } } private void handleListTypePropertyForIntrospector(DBProperty dbProperty, String prop, Introspector temp) { dbProperty.setCardinality(Cardinality.SET); if (temp.isSimpleGenericType(prop)) { Class clazz; try { clazz = Class.forName(temp.getGenericType(prop)); } catch (ClassNotFoundException e) { clazz = Object.class; } dbProperty.setTypeClass(clazz); properties.put(prop, dbProperty); } } private void handleNonListTypePropertyForIntrospector(DBProperty dbProperty, String prop, Introspector temp) { dbProperty.setCardinality(Cardinality.SINGLE); if (temp.isSimpleType(prop)) { Class clazz; try { clazz = Class.forName(temp.getType(prop)); } catch (ClassNotFoundException e) { clazz = Object.class; } dbProperty.setTypeClass(clazz); properties.put(prop, dbProperty); } } /** * Creates the DB indexes. * * @param temp the temp */ private void createDBIndexes(Introspector temp) { String uniqueProps = temp.getMetadata("uniqueProps"); String namespace = temp.getMetadata("namespace"); if (uniqueProps == null) { uniqueProps = ""; } if (namespace == null) { namespace = ""; } boolean isTopLevel = !Objects.equals(namespace, ""); List unique = Arrays.asList(uniqueProps.split(",")); List indexed = temp.getIndexedProperties(); List keys = temp.getKeys(); setDbIndexAttributes(indexed, unique); if (keys.size() > 1 || isTopLevel) { setDbIndexAttributes(isTopLevel, temp, unique, keys); } } private void setDbIndexAttributes(List indexed, List unique) { for (String prop : indexed) { DBIndex dbIndex = new DBIndex(); LinkedHashSet properties = new LinkedHashSet<>(); if (!this.indexes.containsKey(prop)) { dbIndex.setName(prop); dbIndex.setUnique(unique.contains(prop)); properties.add(this.properties.get(prop)); dbIndex.setProperties(properties); dbIndex.setStatus(SchemaStatus.ENABLED); this.indexes.put(prop, dbIndex); } } } private void setDbIndexAttributes(boolean isTopLevel, Introspector temp, List unique, List keys) { DBIndex dbIndex = new DBIndex(); LinkedHashSet properties = new LinkedHashSet<>(); dbIndex.setName("key-for-" + temp.getDbName()); if (!this.indexes.containsKey(dbIndex.getName())) { boolean isUnique = false; if (isTopLevel) { properties.add(this.properties.get(AAIProperties.NODE_TYPE)); } for (String key : keys) { properties.add(this.properties.get(key)); if (unique.contains(key) && !isUnique) { isUnique = true; } } dbIndex.setUnique(isUnique); dbIndex.setProperties(properties); dbIndex.setStatus(SchemaStatus.ENABLED); this.indexes.put(dbIndex.getName(), dbIndex); } } /** * Creates the edge labels. */ private void createEdgeLabels() { Multimap edgeRules = DbEdgeRules.EdgeRules; for (String key : edgeRules.keySet()) { Collection collection = edgeRules.get(key); EdgeProperty prop = new EdgeProperty(); //there is only ever one, they used the wrong type for EdgeRules String label = ""; for (String item : collection) { label = item.split(",")[0]; } prop.setName(label); prop.setMultiplicity(Multiplicity.MULTI); this.edgeLabels.put(label, prop); } } /** * Gets the all introspectors. * * @return the all introspectors */ public Set getAllIntrospectors() { return this.allObjects; } }