2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 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=========================================================
21 package org.openecomp.aai.util;
22 import java.util.HashMap;
23 import java.util.Iterator;
25 import java.util.Properties;
26 import java.util.UUID;
28 import org.apache.tinkerpop.gremlin.structure.Direction;
29 import org.apache.tinkerpop.gremlin.structure.Edge;
30 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
33 import org.openecomp.aai.exceptions.AAIException;
34 import com.att.eelf.configuration.Configuration;
35 import com.att.eelf.configuration.EELFLogger;
36 import com.att.eelf.configuration.EELFManager;
37 import com.thinkaurelius.titan.core.TitanEdge;
38 import com.thinkaurelius.titan.core.TitanFactory;
39 import com.thinkaurelius.titan.core.TitanGraph;
40 import com.thinkaurelius.titan.core.TitanTransaction;
41 import com.thinkaurelius.titan.core.TitanVertex;
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];
73 TitanTransaction graph = null;
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, TitanTransaction 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 Iterable <?> vertItr = graph.query().has(propertyName).vertices();
132 Iterator <?> vertItor = vertItr.iterator();
133 while( vertItor.hasNext() ){
135 TitanVertex v = (TitanVertex)vertItor.next();
136 String thisVid = v.id().toString();
137 Object val = (v.<Object>property(propertyName)).orElse(null);
138 if( valuesAndVidHash.containsKey(val) ){
139 // We've seen this one before- track it in our dupe hash
141 if( dupeHash.containsKey(val) ){
142 // This is not the first one being added to the dupe hash for this value
143 String updatedDupeList = dupeHash.get(val) + "|" + thisVid;
144 dupeHash.put(val.toString(), updatedDupeList);
147 // This is the first time we see this value repeating
148 String firstTwoVids = valuesAndVidHash.get(val) + "|" + thisVid;
149 dupeHash.put(val.toString(), firstTwoVids);
153 valuesAndVidHash.put(val.toString(), thisVid);
158 String info = "\n Found this property [" + propertyName + "] " + propCount + " times in our db.";
159 logAndPrint(logger, info);
160 info = " Found " + dupeCount + " cases of duplicate values for this property.\n\n";
161 logAndPrint(logger, info);
164 if( ! dupeHash.isEmpty() ){
165 Iterator <?> dupeItr = dupeHash.entrySet().iterator();
166 while( dupeItr.hasNext() ){
167 Map.Entry pair = (Map.Entry) dupeItr.next();
168 String dupeValue = pair.getKey().toString();;
169 String vidsStr = pair.getValue().toString();
170 String[] vidArr = vidsStr.split("\\|");
171 logAndPrint(logger, "\n\n -------------- Found " + vidArr.length
172 + " nodes with " + propertyName + " of this value: [" + dupeValue + "]. Node details: ");
174 for( int i = 0; i < vidArr.length; i++ ){
175 String vidString = vidArr[i];
176 Long idLong = Long.valueOf(vidString);
177 TitanVertex tvx = (TitanVertex)graph.getVertex(idLong);
178 showPropertiesAndEdges( TRANSID, FROMAPPID, tvx, logger );
183 catch( Exception e2 ){
184 logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
192 return foundDupesFlag;
194 }// end of runTheCheckForUniqueness()
198 * Show properties and edges.
200 * @param transId the trans id
201 * @param fromAppId the from app id
202 * @param tVert the t vert
203 * @param logger the logger
205 private static void showPropertiesAndEdges( String transId, String fromAppId, TitanVertex tVert,
209 logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
212 String nodeType = "";
213 Object ob = tVert.<String>property("aai-node-type").orElse(null);
218 nodeType = ob.toString();
221 logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]");
222 logAndPrint(logger, " Property Detail: ");
223 Iterator<VertexProperty<Object>> pI = tVert.properties();
224 while( pI.hasNext() ){
225 VertexProperty<Object> tp = pI.next();
226 Object val = tp.value();
227 logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] ");
230 Iterator <Edge> eI = tVert.edges(Direction.BOTH);
231 if( ! eI.hasNext() ){
232 logAndPrint(logger, "No edges were found for this vertex. ");
234 while( eI.hasNext() ){
235 TitanEdge ed = (TitanEdge) eI.next();
236 String lab = ed.label();
237 TitanVertex vtx = (TitanVertex) ed.otherVertex(tVert);
239 logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
242 String nType = vtx.<String>property("aai-node-type").orElse(null);
243 String vid = vtx.id().toString();
244 logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType + "] node with VtxId = " + vid);
248 } // End of showPropertiesAndEdges()
254 * @param logger the logger
257 protected static void logAndPrint(EELFLogger logger, String msg) {
258 System.out.println(msg);