2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.util;
23 import java.util.HashMap;
24 import java.util.Iterator;
26 import java.util.Properties;
27 import java.util.UUID;
29 import org.apache.tinkerpop.gremlin.structure.Direction;
30 import org.apache.tinkerpop.gremlin.structure.Edge;
31 import org.apache.tinkerpop.gremlin.structure.Graph;
32 import org.apache.tinkerpop.gremlin.structure.Vertex;
33 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
34 import org.onap.aai.exceptions.AAIException;
37 import com.att.eelf.configuration.Configuration;
38 import com.att.eelf.configuration.EELFLogger;
39 import com.att.eelf.configuration.EELFManager;
40 import com.thinkaurelius.titan.core.TitanFactory;
41 import com.thinkaurelius.titan.core.TitanGraph;
45 public class UniquePropertyCheck {
48 private static final String FROMAPPID = "AAI-UTILS";
49 private static final String TRANSID = UUID.randomUUID().toString();
50 private static final String COMPONENT = "UniquePropertyCheck";
55 * @param args the arguments
57 public static void main(String[] args) {
60 Properties props = System.getProperties();
61 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "uniquePropertyCheck-logback.xml");
62 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
63 EELFLogger logger = EELFManager.getInstance().getLogger(UniquePropertyCheck.class.getSimpleName());
64 MDC.put("logFilenameAppender", UniquePropertyCheck.class.getSimpleName());
66 if( args == null || args.length != 1 ){
67 String msg = "usage: UniquePropertyCheck propertyName \n";
68 System.out.println(msg);
69 logAndPrint(logger, msg );
72 String propertyName = args[0];
77 System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n");
78 TitanGraph tGraph = TitanFactory.open(AAIConstants.REALTIME_DB_CONFIG);
80 if( tGraph == null ) {
81 logAndPrint(logger, " Error: Could not get TitanGraph ");
85 graph = tGraph.newTransaction();
87 logAndPrint(logger, "could not get graph object in UniquePropertyCheck() \n");
91 catch (AAIException e1) {
92 String msg = "Threw Exception: [" + e1.toString() + "]";
93 logAndPrint(logger, msg);
96 catch (Exception e2) {
97 String msg = "Threw Exception: [" + e2.toString() + "]";
98 logAndPrint(logger, msg);
102 runTheCheckForUniqueness( TRANSID, FROMAPPID, graph, propertyName, logger );
109 * Run the check for uniqueness.
111 * @param transId the trans id
112 * @param fromAppId the from app id
113 * @param graph the graph
114 * @param propertyName the property name
115 * @param logger the logger
116 * @return the boolean
118 public static Boolean runTheCheckForUniqueness( String transId, String fromAppId, Graph graph,
119 String propertyName, EELFLogger logger ){
121 // Note - property can be found in more than one nodetype
122 // our uniqueness constraints are always across the entire db - so this
123 // tool looks across all nodeTypes that the property is found in.
124 Boolean foundDupesFlag = false;
126 HashMap <String,String> valuesAndVidHash = new HashMap <String, String> ();
127 HashMap <String,String> dupeHash = new HashMap <String, String> ();
131 Iterator<Vertex> vertItor = graph.traversal().V().has(propertyName);
132 while( vertItor.hasNext() ){
134 Vertex v = vertItor.next();
135 String thisVid = v.id().toString();
136 Object val = (v.<Object>property(propertyName)).orElse(null);
137 if( valuesAndVidHash.containsKey(val) ){
138 // We've seen this one before- track it in our dupe hash
140 if( dupeHash.containsKey(val) ){
141 // This is not the first one being added to the dupe hash for this value
142 String updatedDupeList = dupeHash.get(val) + "|" + thisVid;
143 dupeHash.put(val.toString(), updatedDupeList);
146 // This is the first time we see this value repeating
147 String firstTwoVids = valuesAndVidHash.get(val) + "|" + thisVid;
148 dupeHash.put(val.toString(), firstTwoVids);
152 valuesAndVidHash.put(val.toString(), thisVid);
157 String info = "\n Found this property [" + propertyName + "] " + propCount + " times in our db.";
158 logAndPrint(logger, info);
159 info = " Found " + dupeCount + " cases of duplicate values for this property.\n\n";
160 logAndPrint(logger, info);
163 if( ! dupeHash.isEmpty() ){
164 Iterator <?> dupeItr = dupeHash.entrySet().iterator();
165 while( dupeItr.hasNext() ){
166 Map.Entry pair = (Map.Entry) dupeItr.next();
167 String dupeValue = pair.getKey().toString();;
168 String vidsStr = pair.getValue().toString();
169 String[] vidArr = vidsStr.split("\\|");
170 logAndPrint(logger, "\n\n -------------- Found " + vidArr.length
171 + " nodes with " + propertyName + " of this value: [" + dupeValue + "]. Node details: ");
173 for( int i = 0; i < vidArr.length; i++ ){
174 String vidString = vidArr[i];
175 Long idLong = Long.valueOf(vidString);
176 Vertex tvx = graph.traversal().V(idLong).next();
177 showPropertiesAndEdges( TRANSID, FROMAPPID, tvx, logger );
182 catch( Exception e2 ){
183 logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
187 graph.tx().rollback();
191 return foundDupesFlag;
193 }// end of runTheCheckForUniqueness()
197 * Show properties and edges.
199 * @param transId the trans id
200 * @param fromAppId the from app id
201 * @param tVert the t vert
202 * @param logger the logger
204 private static void showPropertiesAndEdges( String transId, String fromAppId, Vertex tVert,
208 logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
211 String nodeType = "";
212 Object ob = tVert.<String>property("aai-node-type").orElse(null);
217 nodeType = ob.toString();
220 logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]");
221 logAndPrint(logger, " Property Detail: ");
222 Iterator<VertexProperty<Object>> pI = tVert.properties();
223 while( pI.hasNext() ){
224 VertexProperty<Object> tp = pI.next();
225 Object val = tp.value();
226 logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] ");
229 Iterator <Edge> eI = tVert.edges(Direction.BOTH);
230 if( ! eI.hasNext() ){
231 logAndPrint(logger, "No edges were found for this vertex. ");
233 while( eI.hasNext() ){
235 String lab = ed.label();
237 if (tVert.equals(ed.inVertex())) {
238 vtx = ed.outVertex();
243 logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
246 String nType = vtx.<String>property("aai-node-type").orElse(null);
247 String vid = vtx.id().toString();
248 logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType + "] node with VtxId = " + vid);
252 } // End of showPropertiesAndEdges()
258 * @param logger the logger
261 protected static void logAndPrint(EELFLogger logger, String msg) {
262 System.out.println(msg);