Update license files, sonar plugin and fix tests
[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