58eb41a4156b722ff72a19777eacfbbb5f611483
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / util / UniquePropertyCheck.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
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
10
11      http://www.apache.org/licenses/LICENSE-2.0
12
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=========================================================
19  */
20
21 package org.openecomp.aai.util;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Properties;
26 import java.util.UUID;
27
28 import org.apache.tinkerpop.gremlin.structure.Direction;
29 import org.apache.tinkerpop.gremlin.structure.Edge;
30 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
31 import org.slf4j.MDC;
32
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;
42
43
44
45 public class UniquePropertyCheck {
46
47
48         private static  final  String    FROMAPPID = "AAI-UTILS";
49         private static  final  String    TRANSID   = UUID.randomUUID().toString();
50         private static  final  String    COMPONENT = "UniquePropertyCheck";
51         
52         /**
53          * The main method.
54          *
55          * @param args the arguments
56          */
57         public static void main(String[] args) {
58                 
59                 
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());
65                 
66                 if( args == null || args.length != 1 ){
67                                 String msg = "usage:  UniquePropertyCheck propertyName \n";
68                                 System.out.println(msg);
69                                 logAndPrint(logger, msg );
70                                 System.exit(1);
71                 }
72                 String propertyName = args[0];
73                 TitanTransaction graph = null;
74                 
75                 try {   
76                 AAIConfig.init();
77                 System.out.println("    ---- NOTE --- about to open graph (takes a little while)--------\n");
78                 TitanGraph tGraph = TitanFactory.open(AAIConstants.REALTIME_DB_CONFIG);
79                 
80                 if( tGraph == null ) {
81                         logAndPrint(logger, " Error:  Could not get TitanGraph ");
82                         System.exit(1);
83                 }
84                 
85                 graph = tGraph.newTransaction();
86                 if( graph == null ){
87                         logAndPrint(logger, "could not get graph object in UniquePropertyCheck() \n");
88                         System.exit(0);
89                 }
90         }
91             catch (AAIException e1) {
92                         String msg =  "Threw Exception: [" + e1.toString() + "]";
93                         logAndPrint(logger, msg);
94                         System.exit(0);
95         }
96         catch (Exception e2) {
97                         String msg =  "Threw Exception: [" + e2.toString() + "]";
98                         logAndPrint(logger, msg);
99                         System.exit(0);
100         }
101                 
102                 runTheCheckForUniqueness( TRANSID, FROMAPPID, graph, propertyName, logger );
103                 System.exit(0);
104                 
105         }// End main()
106         
107         
108         /**
109          * Run the check for uniqueness.
110          *
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
117          */
118         public static Boolean runTheCheckForUniqueness( String transId, String fromAppId, TitanTransaction graph, 
119                         String propertyName, EELFLogger logger ){
120                 
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;
125                 
126                 HashMap <String,String> valuesAndVidHash = new HashMap <String, String> ();
127                 HashMap <String,String> dupeHash = new HashMap <String, String> ();
128         
129                 int propCount = 0;
130                 int dupeCount = 0;
131                 Iterable <?> vertItr = graph.query().has(propertyName).vertices();
132                 Iterator <?> vertItor = vertItr.iterator();
133         while( vertItor.hasNext() ){
134                 propCount++;
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
140                         dupeCount++;
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);
145                         }
146                         else {
147                                 // This is the first time we see this value repeating
148                                 String firstTwoVids =  valuesAndVidHash.get(val) + "|" + thisVid;
149                                 dupeHash.put(val.toString(), firstTwoVids);
150                         }
151                 }
152                 else {
153                         valuesAndVidHash.put(val.toString(), thisVid);
154                 }               
155         }
156                 
157         
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);
162
163         try {
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: ");
173                                 
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 );
179                                 }
180                         }
181                 }
182         }
183         catch( Exception e2 ){
184                         logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
185         } 
186         finally {
187                 if( graph != null ){
188                         graph.rollback();
189                 }
190         }
191         
192         return foundDupesFlag;
193         
194         }// end of runTheCheckForUniqueness()
195         
196         
197         /**
198          * Show properties and edges.
199          *
200          * @param transId the trans id
201          * @param fromAppId the from app id
202          * @param tVert the t vert
203          * @param logger the logger
204          */
205         private static void showPropertiesAndEdges( String transId, String fromAppId, TitanVertex tVert,
206                         EELFLogger logger ){ 
207
208                 if( tVert == null ){
209                         logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
210                 }
211                 else {
212                         String nodeType = "";
213                         Object ob = tVert.<String>property("aai-node-type").orElse(null);
214                         if( ob == null ){
215                                 nodeType = "null";
216                         }
217                         else{
218                                 nodeType = ob.toString();
219                         }
220                         
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 + "] ");          
228                         }
229                         
230                         Iterator <Edge> eI = tVert.edges(Direction.BOTH);
231                         if( ! eI.hasNext() ){
232                                 logAndPrint(logger, "No edges were found for this vertex. ");
233                         }
234                         while( eI.hasNext() ){
235                                 TitanEdge ed = (TitanEdge) eI.next();
236                                 String lab = ed.label();
237                                 TitanVertex vtx = (TitanVertex) ed.otherVertex(tVert);
238                                 if( vtx == null ){
239                                         logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
240                                 }
241                                 else {
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);
245                                 }
246                         }
247                 }
248         } // End of showPropertiesAndEdges()
249
250         
251         /**
252          * Log and print.
253          *
254          * @param logger the logger
255          * @param msg the msg
256          */
257         protected static void logAndPrint(EELFLogger logger, String msg) {
258                 System.out.println(msg);
259                 logger.info(msg);
260         }
261         
262 }
263
264