2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 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=========================================================
20 package org.onap.aai.util;
21 import java.util.HashMap;
22 import java.util.Iterator;
24 import java.util.Properties;
25 import java.util.UUID;
27 import org.apache.tinkerpop.gremlin.structure.Direction;
28 import org.apache.tinkerpop.gremlin.structure.Edge;
29 import org.apache.tinkerpop.gremlin.structure.Graph;
30 import org.apache.tinkerpop.gremlin.structure.Vertex;
31 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
32 import org.onap.aai.exceptions.AAIException;
33 import org.onap.aai.logging.LoggingContext;
34 import org.onap.aai.logging.LoggingContext.StatusCode;
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 import org.onap.aai.dbmap.AAIGraphConfig;
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());
64 LoggingContext.init();
65 LoggingContext.partnerName(FROMAPPID);
66 LoggingContext.serviceName(AAIConstants.AAI_RESOURCES_MS);
67 LoggingContext.component(COMPONENT);
68 LoggingContext.targetEntity(AAIConstants.AAI_RESOURCES_MS);
69 LoggingContext.targetServiceName("main");
70 LoggingContext.requestId(TRANSID);
71 LoggingContext.statusCode(StatusCode.COMPLETE);
72 LoggingContext.responseCode(LoggingContext.SUCCESS);
74 MDC.put("logFilenameAppender", UniquePropertyCheck.class.getSimpleName());
76 if( args == null || args.length != 1 ){
77 String msg = "usage: UniquePropertyCheck propertyName \n";
78 System.out.println(msg);
79 LoggingContext.statusCode(StatusCode.ERROR);
80 LoggingContext.responseCode(LoggingContext.BUSINESS_PROCESS_ERROR);
81 logAndPrint(logger, msg );
84 String propertyName = args[0];
89 System.out.println(" ---- NOTE --- about to open graph (takes a little while)--------\n");
90 TitanGraph tGraph = TitanFactory.open(new AAIGraphConfig.Builder(AAIConstants.REALTIME_DB_CONFIG).forService(UniquePropertyCheck.class.getSimpleName()).withGraphType("realtime").buildConfiguration());
92 if( tGraph == null ) {
93 LoggingContext.statusCode(StatusCode.ERROR);
94 LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR);
95 logAndPrint(logger, " Error: Could not get TitanGraph ");
99 graph = tGraph.newTransaction();
101 LoggingContext.statusCode(StatusCode.ERROR);
102 LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR);
103 logAndPrint(logger, "could not get graph object in UniquePropertyCheck() \n");
107 catch (AAIException e1) {
108 String msg = "Threw Exception: [" + e1.toString() + "]";
109 LoggingContext.statusCode(StatusCode.ERROR);
110 LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR);
111 logAndPrint(logger, msg);
114 catch (Exception e2) {
115 String msg = "Threw Exception: [" + e2.toString() + "]";
116 LoggingContext.statusCode(StatusCode.ERROR);
117 LoggingContext.responseCode(LoggingContext.UNKNOWN_ERROR);
118 logAndPrint(logger, msg);
122 runTheCheckForUniqueness( TRANSID, FROMAPPID, graph, propertyName, logger );
129 * Run the check for uniqueness.
131 * @param transId the trans id
132 * @param fromAppId the from app id
133 * @param graph the graph
134 * @param propertyName the property name
135 * @param logger the logger
136 * @return the boolean
138 public static Boolean runTheCheckForUniqueness( String transId, String fromAppId, Graph graph,
139 String propertyName, EELFLogger logger ){
141 // Note - property can be found in more than one nodetype
142 // our uniqueness constraints are always across the entire db - so this
143 // tool looks across all nodeTypes that the property is found in.
144 Boolean foundDupesFlag = false;
146 HashMap <String,String> valuesAndVidHash = new HashMap <String, String> ();
147 HashMap <String,String> dupeHash = new HashMap <String, String> ();
151 Iterator<Vertex> vertItor = graph.traversal().V().has(propertyName);
152 while( vertItor.hasNext() ){
154 Vertex v = vertItor.next();
155 String thisVid = v.id().toString();
156 Object val = (v.<Object>property(propertyName)).orElse(null);
157 if( valuesAndVidHash.containsKey(val) ){
158 // We've seen this one before- track it in our dupe hash
160 if( dupeHash.containsKey(val) ){
161 // This is not the first one being added to the dupe hash for this value
162 String updatedDupeList = dupeHash.get(val) + "|" + thisVid;
163 dupeHash.put(val.toString(), updatedDupeList);
166 // This is the first time we see this value repeating
167 String firstTwoVids = valuesAndVidHash.get(val) + "|" + thisVid;
168 dupeHash.put(val.toString(), firstTwoVids);
172 valuesAndVidHash.put(val.toString(), thisVid);
177 String info = "\n Found this property [" + propertyName + "] " + propCount + " times in our db.";
178 logAndPrint(logger, info);
179 info = " Found " + dupeCount + " cases of duplicate values for this property.\n\n";
180 logAndPrint(logger, info);
183 if( ! dupeHash.isEmpty() ){
184 Iterator <?> dupeItr = dupeHash.entrySet().iterator();
185 while( dupeItr.hasNext() ){
186 Map.Entry pair = (Map.Entry) dupeItr.next();
187 String dupeValue = pair.getKey().toString();;
188 String vidsStr = pair.getValue().toString();
189 String[] vidArr = vidsStr.split("\\|");
190 logAndPrint(logger, "\n\n -------------- Found " + vidArr.length
191 + " nodes with " + propertyName + " of this value: [" + dupeValue + "]. Node details: ");
193 for( int i = 0; i < vidArr.length; i++ ){
194 String vidString = vidArr[i];
195 Long idLong = Long.valueOf(vidString);
196 Vertex tvx = graph.traversal().V(idLong).next();
197 showPropertiesAndEdges( TRANSID, FROMAPPID, tvx, logger );
202 catch( Exception e2 ){
203 LoggingContext.statusCode(StatusCode.ERROR);
204 LoggingContext.responseCode(LoggingContext.DATA_ERROR);
205 logAndPrint(logger, "Threw Exception: [" + e2.toString() + "]");
209 graph.tx().rollback();
213 return foundDupesFlag;
215 }// end of runTheCheckForUniqueness()
219 * Show properties and edges.
221 * @param transId the trans id
222 * @param fromAppId the from app id
223 * @param tVert the t vert
224 * @param logger the logger
226 private static void showPropertiesAndEdges( String transId, String fromAppId, Vertex tVert,
230 logAndPrint(logger, "Null node passed to showPropertiesAndEdges.");
233 String nodeType = "";
234 Object ob = tVert.<String>property("aai-node-type").orElse(null);
239 nodeType = ob.toString();
242 logAndPrint(logger, " AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]");
243 logAndPrint(logger, " Property Detail: ");
244 Iterator<VertexProperty<Object>> pI = tVert.properties();
245 while( pI.hasNext() ){
246 VertexProperty<Object> tp = pI.next();
247 Object val = tp.value();
248 logAndPrint(logger, "Prop: [" + tp.key() + "], val = [" + val + "] ");
251 Iterator <Edge> eI = tVert.edges(Direction.BOTH);
252 if( ! eI.hasNext() ){
253 logAndPrint(logger, "No edges were found for this vertex. ");
255 while( eI.hasNext() ){
257 String lab = ed.label();
259 if (tVert.equals(ed.inVertex())) {
260 vtx = ed.outVertex();
265 logAndPrint(logger, " >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
268 String nType = vtx.<String>property("aai-node-type").orElse(null);
269 String vid = vtx.id().toString();
270 logAndPrint(logger, "Found an edge (" + lab + ") from this vertex to a [" + nType + "] node with VtxId = " + vid);
274 } // End of showPropertiesAndEdges()
280 * @param logger the logger
283 protected static void logAndPrint(EELFLogger logger, String msg) {
284 System.out.println(msg);