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);