Merge "Update shema for VFC"
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / util / UniquePropertyCheck.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  */
22 package org.onap.aai.util;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.UUID;
28
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;
35 import org.slf4j.MDC;
36
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;
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                 Graph 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, Graph 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                 Iterator<Vertex> vertItor = graph.traversal().V().has(propertyName);
132         while( vertItor.hasNext() ){
133                 propCount++;
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
139                         dupeCount++;
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);
144                         }
145                         else {
146                                 // This is the first time we see this value repeating
147                                 String firstTwoVids =  valuesAndVidHash.get(val) + "|" + thisVid;
148                                 dupeHash.put(val.toString(), firstTwoVids);
149                         }
150                 }
151                 else {
152                         valuesAndVidHash.put(val.toString(), thisVid);
153                 }               
154         }
155                 
156         
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);
161
162         try {
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: ");
172                                 
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 );
178                                 }
179                         }
180                 }
181         }
182         catch( Exception e2 ){
183                         logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
184         } 
185         finally {
186                 if( graph != null ){
187                         graph.tx().rollback();
188                 }
189         }
190         
191         return foundDupesFlag;
192         
193         }// end of runTheCheckForUniqueness()
194         
195         
196         /**
197          * Show properties and edges.
198          *
199          * @param transId the trans id
200          * @param fromAppId the from app id
201          * @param tVert the t vert
202          * @param logger the logger
203          */
204         private static void showPropertiesAndEdges( String transId, String fromAppId, Vertex tVert,
205                         EELFLogger logger ){ 
206
207                 if( tVert == null ){
208                         logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
209                 }
210                 else {
211                         String nodeType = "";
212                         Object ob = tVert.<String>property("aai-node-type").orElse(null);
213                         if( ob == null ){
214                                 nodeType = "null";
215                         }
216                         else{
217                                 nodeType = ob.toString();
218                         }
219                         
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 + "] ");          
227                         }
228                         
229                         Iterator <Edge> eI = tVert.edges(Direction.BOTH);
230                         if( ! eI.hasNext() ){
231                                 logAndPrint(logger, "No edges were found for this vertex. ");
232                         }
233                         while( eI.hasNext() ){
234                                 Edge ed = eI.next();
235                                 String lab = ed.label();
236                                 Vertex vtx;
237                                 if (tVert.equals(ed.inVertex())) {
238                                         vtx = ed.outVertex();
239                                 } else {
240                                         vtx = ed.inVertex();
241                                 }
242                                 if( vtx == null ){
243                                         logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
244                                 }
245                                 else {
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);
249                                 }
250                         }
251                 }
252         } // End of showPropertiesAndEdges()
253
254         
255         /**
256          * Log and print.
257          *
258          * @param logger the logger
259          * @param msg the msg
260          */
261         protected static void logAndPrint(EELFLogger logger, String msg) {
262                 System.out.println(msg);
263                 logger.info(msg);
264         }
265         
266 }
267
268