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.Graph;
31 import org.apache.tinkerpop.gremlin.structure.Vertex;
32 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
33 import org.openecomp.aai.exceptions.AAIException;
36 import com.att.eelf.configuration.Configuration;
37 import com.att.eelf.configuration.EELFLogger;
38 import com.att.eelf.configuration.EELFManager;
39 import com.thinkaurelius.titan.core.TitanFactory;
40 import com.thinkaurelius.titan.core.TitanGraph;
44 public class UniquePropertyCheck {
47 private static final String FROMAPPID = "AAI-UTILS";
48 private static final String TRANSID = UUID.randomUUID().toString();
49 private static final String COMPONENT = "UniquePropertyCheck";
54 * @param args the arguments
56 public static void main(String[] args) {
59 Properties props = System.getProperties();
60 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, "uniquePropertyCheck-logback.xml");
61 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
62 EELFLogger logger = EELFManager.getInstance().getLogger(UniquePropertyCheck.class.getSimpleName());
63 MDC.put("logFilenameAppender", UniquePropertyCheck.class.getSimpleName());
65 if( args == null || args.length != 1 ){
66 String msg = "usage: UniquePropertyCheck propertyName \n";
67 System.out.println(msg);
68 logAndPrint(logger, msg );
71 String propertyName = args[0];
76 System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n");
77 TitanGraph tGraph = TitanFactory.open(AAIConstants.REALTIME_DB_CONFIG);
79 if( tGraph == null ) {
80 logAndPrint(logger, " Error: Could not get TitanGraph ");
84 graph = tGraph.newTransaction();
86 logAndPrint(logger, "could not get graph object in UniquePropertyCheck() \n");
90 catch (AAIException e1) {
91 String msg = "Threw Exception: [" + e1.toString() + "]";
92 logAndPrint(logger, msg);
95 catch (Exception e2) {
96 String msg = "Threw Exception: [" + e2.toString() + "]";
97 logAndPrint(logger, msg);
101 runTheCheckForUniqueness( TRANSID, FROMAPPID, graph, propertyName, logger );
108 * Run the check for uniqueness.
110 * @param transId the trans id
111 * @param fromAppId the from app id
112 * @param graph the graph
113 * @param propertyName the property name
114 * @param logger the logger
115 * @return the boolean
117 public static Boolean runTheCheckForUniqueness( String transId, String fromAppId, Graph graph,
118 String propertyName, EELFLogger logger ){
120 // Note - property can be found in more than one nodetype
121 // our uniqueness constraints are always across the entire db - so this
122 // tool looks across all nodeTypes that the property is found in.
123 Boolean foundDupesFlag = false;
125 HashMap <String,String> valuesAndVidHash = new HashMap <String, String> ();
126 HashMap <String,String> dupeHash = new HashMap <String, String> ();
130 Iterator<Vertex> vertItor = graph.traversal().V().has(propertyName);
131 while( vertItor.hasNext() ){
133 Vertex v = vertItor.next();
134 String thisVid = v.id().toString();
135 Object val = (v.<Object>property(propertyName)).orElse(null);
136 if( valuesAndVidHash.containsKey(val) ){
137 // We've seen this one before- track it in our dupe hash
139 if( dupeHash.containsKey(val) ){
140 // This is not the first one being added to the dupe hash for this value
141 String updatedDupeList = dupeHash.get(val) + "|" + thisVid;
142 dupeHash.put(val.toString(), updatedDupeList);
145 // This is the first time we see this value repeating
146 String firstTwoVids = valuesAndVidHash.get(val) + "|" + thisVid;
147 dupeHash.put(val.toString(), firstTwoVids);
151 valuesAndVidHash.put(val.toString(), thisVid);
156 String info = "\n Found this property [" + propertyName + "] " + propCount + " times in our db.";
157 logAndPrint(logger, info);
158 info = " Found " + dupeCount + " cases of duplicate values for this property.\n\n";
159 logAndPrint(logger, info);
162 if( ! dupeHash.isEmpty() ){
163 Iterator <?> dupeItr = dupeHash.entrySet().iterator();
164 while( dupeItr.hasNext() ){
165 Map.Entry pair = (Map.Entry) dupeItr.next();
166 String dupeValue = pair.getKey().toString();;
167 String vidsStr = pair.getValue().toString();
168 String[] vidArr = vidsStr.split("\\|");
169 logAndPrint(logger, "\n\n -------------- Found " + vidArr.length
170 + " nodes with " + propertyName + " of this value: [" + dupeValue + "]. Node details: ");
172 for( int i = 0; i < vidArr.length; i++ ){
173 String vidString = vidArr[i];
174 Long idLong = Long.valueOf(vidString);
175 Vertex tvx = graph.traversal().V(idLong).next();
176 showPropertiesAndEdges( TRANSID, FROMAPPID, tvx, logger );
181 catch( Exception e2 ){
182 logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
186 graph.tx().rollback();
190 return foundDupesFlag;
192 }// end of runTheCheckForUniqueness()
196 * Show properties and edges.
198 * @param transId the trans id
199 * @param fromAppId the from app id
200 * @param tVert the t vert
201 * @param logger the logger
203 private static void showPropertiesAndEdges( String transId, String fromAppId, Vertex tVert,
207 logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
210 String nodeType = "";
211 Object ob = tVert.<String>property("aai-node-type").orElse(null);
216 nodeType = ob.toString();
219 logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]");
220 logAndPrint(logger, " Property Detail: ");
221 Iterator<VertexProperty<Object>> pI = tVert.properties();
222 while( pI.hasNext() ){
223 VertexProperty<Object> tp = pI.next();
224 Object val = tp.value();
225 logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] ");
228 Iterator <Edge> eI = tVert.edges(Direction.BOTH);
229 if( ! eI.hasNext() ){
230 logAndPrint(logger, "No edges were found for this vertex. ");
232 while( eI.hasNext() ){
234 String lab = ed.label();
236 if (tVert.equals(ed.inVertex())) {
237 vtx = ed.outVertex();
242 logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
245 String nType = vtx.<String>property("aai-node-type").orElse(null);
246 String vid = vtx.id().toString();
247 logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType + "] node with VtxId = " + vid);
251 } // End of showPropertiesAndEdges()
257 * @param logger the logger
260 protected static void logAndPrint(EELFLogger logger, String msg) {
261 System.out.println(msg);