update junit to recheck for snapshot file
[aai/graphadmin.git] / src / main / java / org / onap / aai / datasnapshot / DataSnapshot4HistInit.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
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 package org.onap.aai.datasnapshot;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.SequenceInputStream;
28 import java.util.Map.Entry;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Properties;
35 import java.util.Set;
36 import java.util.Vector;
37 import java.util.concurrent.Callable;
38 import java.util.concurrent.ExecutionException;
39 import java.util.concurrent.ExecutorService;
40 import java.util.concurrent.Executors;
41 import java.util.concurrent.Future;
42 import java.util.concurrent.TimeUnit;
43 import org.onap.aai.restclient.PropertyPasswordConfiguration;
44 import org.apache.tinkerpop.gremlin.structure.Vertex;
45 import org.apache.commons.configuration.PropertiesConfiguration;
46 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
47 import org.janusgraph.core.JanusGraph;
48 import org.janusgraph.core.JanusGraphFactory;
49 import org.janusgraph.core.util.JanusGraphCleanup;
50 import org.onap.aai.dbmap.AAIGraph;
51 import org.onap.aai.dbmap.AAIGraphConfig;
52 import org.onap.aai.exceptions.AAIException;
53 import org.onap.aai.introspection.Introspector;
54 import org.onap.aai.introspection.Loader;
55
56
57 import org.onap.aai.introspection.LoaderFactory;
58 import org.onap.aai.introspection.LoaderUtil;
59 import org.onap.aai.logging.ErrorLogHelper;
60 import org.onap.aai.setup.SchemaVersions;
61 import org.onap.aai.util.AAIConfig;
62 import org.onap.aai.util.AAIConstants;
63 import org.onap.aai.util.GraphAdminConstants;
64 import org.onap.aai.util.AAISystemExitUtil;
65 import org.onap.aai.util.FormatDate;
66 import org.onap.aai.util.GraphAdminDBUtils;
67 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
68
69 import com.att.eelf.configuration.Configuration;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72 import com.beust.jcommander.JCommander;
73 import com.beust.jcommander.Parameter;
74 import com.beust.jcommander.ParameterException;
75
76 public class DataSnapshot4HistInit {
77
78         private static Logger LOGGER = LoggerFactory.getLogger(DataSnapshot4HistInit.class);
79
80         /* Using realtime d */
81         private static final String REALTIME_DB = "realtime";
82
83         private static final Set<String> SNAPSHOT_RELOAD_COMMANDS = new HashSet<>();
84
85         private static final String MIGRATION_PROCESS_NAME = "migration";
86         
87         private static boolean historyEnabled;
88         
89         private LoaderFactory loaderFactory;
90         private SchemaVersions schemaVersions;
91
92         static {
93                 SNAPSHOT_RELOAD_COMMANDS.add("RELOAD_DATA");
94                 SNAPSHOT_RELOAD_COMMANDS.add("RELOAD_DATA_MULTI");
95         }
96         
97         private CommandLineArgs cArgs;
98         
99         public DataSnapshot4HistInit(LoaderFactory loaderFactory, SchemaVersions schemaVersions){
100                 this.loaderFactory  = loaderFactory;
101                 this.schemaVersions = schemaVersions;
102         }
103         
104         /**
105          * The main method.
106          *
107          * @param args
108          *            the arguments
109          */
110         public static void main(String[] args) {
111                 
112                 // Set the logging file properties to be used by EELFManager
113                 System.setProperty("aai.service.name", DataSnapshot4HistInit.class.getSimpleName());
114                 Properties props = System.getProperties();
115                 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_NAME, AAIConstants.AAI_LOGBACK_PROPS);
116                 props.setProperty(Configuration.PROPERTY_LOGGING_FILE_PATH, AAIConstants.AAI_HOME_BUNDLECONFIG);
117
118                 
119                 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
120                 PropertyPasswordConfiguration initializer = new PropertyPasswordConfiguration();
121                 initializer.initialize(ctx);
122                 try {
123                         ctx.scan(
124                                         "org.onap.aai.config",
125                                         "org.onap.aai.setup"
126                         );
127                         ctx.refresh();
128                 } catch (Exception e) {
129                         AAIException ae = new AAIException("AAI_6128", e , "Error - Could not initialize context beans for DataSnapshot4HistInit.");
130                         ErrorLogHelper.logException(ae);
131                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
132                 }
133                 
134                 historyEnabled = Boolean.parseBoolean(ctx.getEnvironment().getProperty("history.enabled","false"));
135                 if( !historyEnabled ) {
136                         String emsg = "Error - DataSnapshot4HistInit may only be used when history.enabled=true. ";
137                         System.out.println(emsg);
138                         AAIException ae = new AAIException("AAI_6128", emsg);
139                         ErrorLogHelper.logException(ae);                        
140                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
141                 }
142                 
143                 LoaderFactory loaderFactory = ctx.getBean(LoaderFactory.class);
144                 SchemaVersions schemaVersions = (SchemaVersions) ctx.getBean("schemaVersions");
145                 DataSnapshot4HistInit dataSnapshotHI = new DataSnapshot4HistInit(loaderFactory, schemaVersions);
146                 
147                 boolean success = dataSnapshotHI.executeCommand(args);
148                 if(success){
149                         AAISystemExitUtil.systemExitCloseAAIGraph(0);
150                 } else {
151                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
152                 }
153
154         }// End of main()
155
156
157         public boolean executeCommand(String[] args) {
158                 
159                 Boolean dbClearFlag = false;
160                 JanusGraph graph = null;
161                 String command = "UNKNOWN"; 
162                 String oldSnapshotFileName = "";
163                 boolean success = true;
164                                 
165                 cArgs = new CommandLineArgs();          
166                 String itemName = "aai.datasnapshot.threads.for.create";
167                 try {
168                         String val = AAIConfig.get(itemName);
169                         if( val != null &&  !val.equals("") ){
170                                 cArgs.threadCount = Integer.parseInt(val);
171                         }
172                 }catch ( Exception e ){
173                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
174                 }
175                 int threadCount4Create = cArgs.threadCount;
176
177                 itemName = "aai.datasnapshot.max.nodes.per.file.for.create";
178                 try {
179                         String val = AAIConfig.get(itemName);
180                         if( val != null &&  !val.equals("") ){
181                                 cArgs.maxNodesPerFile = Long.parseLong(val);
182                         }
183                 }catch ( Exception e ){
184                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
185                 }
186                 long maxNodesPerFile4Create = cArgs.maxNodesPerFile;
187                                 
188                 cArgs.snapshotType = "graphson";
189                 Long vertAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_ADD_DELAY_MS;
190                 itemName = "aai.datasnapshot.vertex.add.delay.ms";
191                 try {
192                         String val = AAIConfig.get(itemName);
193                         if( val != null &&  !val.equals("") ){
194                                 cArgs.vertAddDelayMs = Long.parseLong(val);
195                         }
196                 }catch ( Exception e ){
197                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
198                 }
199                 
200                 Long edgeAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_EDGE_ADD_DELAY_MS;
201                 itemName = "aai.datasnapshot.edge.add.delay.ms";
202                 try {
203                         String val = AAIConfig.get(itemName);
204                         if( val != null &&  !val.equals("") ){
205                                 cArgs.edgeAddDelayMs = Long.parseLong(val);
206                         }
207                 }catch ( Exception e ){
208                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
209                 }
210                 
211                 Long failureDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_FAILURE_DELAY_MS;
212                 itemName = "aai.datasnapshot.failure.delay.ms";
213                 try {
214                         String val = AAIConfig.get(itemName);
215                         if( val != null &&  !val.equals("") ){
216                                 cArgs.failureDelayMs = Long.parseLong(val);
217                         }
218                 }catch ( Exception e ){
219                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
220                 }
221                 
222                 Long retryDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_RETRY_DELAY_MS;
223                 itemName = "aai.datasnapshot.retry.delay.ms";
224                 try {
225                         String val = AAIConfig.get(itemName);
226                         if( val != null &&  !val.equals("") ){
227                                 cArgs.retryDelayMs = Long.parseLong(val);
228                         }
229                 }catch ( Exception e ){
230                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
231                 }
232                 
233                 int maxErrorsPerThread = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_ERRORS_PER_THREAD;
234                 itemName = "aai.datasnapshot.max.errors.per.thread";
235                 try {
236                         String val = AAIConfig.get(itemName);
237                         if( val != null &&  !val.equals("") ){
238                                 cArgs.maxErrorsPerThread = Integer.parseInt(val);
239                         }
240                 }catch ( Exception e ){
241                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
242                 }
243                 
244                 Long vertToEdgeProcDelay = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_TO_EDGE_PROC_DELAY_MS;
245                 itemName = "aai.datasnapshot.vertex.to.edge.proc.delay.ms";
246                 try {
247                         String val = AAIConfig.get(itemName);
248                         if( val != null &&  !val.equals("") ){
249                                 cArgs.vertToEdgeProcDelay = Long.parseLong(val);
250                         }
251                 }catch ( Exception e ){
252                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
253                 }
254                 
255                 itemName = "aai.datasnapshot.stagger.thread.delay.ms";
256                 try {
257                         String val = AAIConfig.get(itemName);
258                         if( val != null &&  !val.equals("") ){
259                                 cArgs.staggerThreadDelay = Long.parseLong(val);
260                         }
261                 }catch ( Exception e ){
262                         LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
263                 }               
264         
265                 long debugAddDelayTime = 1;  // Default to 1 millisecond
266                 Boolean debug4Create = false;  // By default we do not use debugging for snapshot creation
267                 JCommander jCommander;
268                 try {
269                         jCommander = new JCommander(cArgs, args);
270                         jCommander.setProgramName(DataSnapshot4HistInit.class.getSimpleName());
271                 } catch (ParameterException e1) {
272                         AAIException ae = new AAIException("AAI_6128", e1 , "Error - invalid value passed to list of args - "+args);
273                         ErrorLogHelper.logException(ae);                        
274                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
275                 }
276                 
277                                 
278                 if (args.length >= 1) {
279                         command = cArgs.command;
280                 }
281                 
282                 String source = cArgs.caller;
283                 String snapshotType = "graphson";
284                 if( SNAPSHOT_RELOAD_COMMANDS.contains(cArgs.command)){
285                         if (args.length >= 2) {
286                                 // If re-loading, they need to also pass the snapshot file name to use.
287                                 // We expected the file to be found in our snapshot directory.
288                                 oldSnapshotFileName = cArgs.oldFileName;
289                                 snapshotType = cArgs.snapshotType;
290                         }
291                 }
292                 else if( command.equals("THREADED_SNAPSHOT") ){
293                         if (args.length >= 2) {
294                                 // If doing a "threaded" snapshot, they need to specify how many threads to use
295                                 try {
296                                         threadCount4Create = cArgs.threadCount;
297                                 }
298                                 catch ( NumberFormatException nfe ){
299                                         ErrorLogHelper.logError("AAI_6128", "Bad (non-integer) threadCount passed to DataSnapshot [" + cArgs.threadCount + "]");
300                                         LOGGER.debug("Bad (non-integer) threadCount passed to DataSnapshot [" + cArgs.threadCount + "]");
301                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
302                                 }
303                                 if( threadCount4Create < 1 || threadCount4Create > 100 ){
304                                         ErrorLogHelper.logError("AAI_6128", "Out of range (1-100) threadCount passed to DataSnapshot [" + cArgs.threadCount + "]");
305                                         LOGGER.debug("Out of range (1-100) threadCount passed to DataSnapshot [" + cArgs.threadCount + "]");
306                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
307                                 }
308                                 LOGGER.debug(" Will do Threaded Snapshot with threadCount = " + threadCount4Create );
309                                 
310                                 if( maxNodesPerFile4Create < 1000 || maxNodesPerFile4Create > 1000000 ){
311                                         ErrorLogHelper.logError("AAI_6128", "Out of range (1000-1000000) maxNodesPerFile passed to DataSnapshot [" + cArgs.maxNodesPerFile + "]");
312                                         LOGGER.debug("Out of range (1000-1000000) maxNodesPerFile passed to DataSnapshot [" + cArgs.maxNodesPerFile + "]");
313                                         LOGGER.debug("Out of range (1000-1000000) maxNodesPerFile >> Recommended value = 120000)");
314                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
315                                 }
316                                 LOGGER.debug(" Will do Threaded Snapshot with maxNodesPerFile = " + maxNodesPerFile4Create );
317                                 
318                                 // If doing a "threaded" snapshot, they need to specify how many threads to use
319                                 // They can also use debug mode if they pass the word "DEBUG" to do the nodes one at a time to see where it breaks.
320                                 if( cArgs.debugFlag.equals("DEBUG") ){
321                                         debug4Create = true;
322                                 }
323                                 LOGGER.debug(" Will do Threaded Snapshot with threadCount = " + threadCount4Create +
324                                                 ", and DEBUG-flag set to: " + debug4Create );
325                                 
326                                 if (debug4Create) {
327                                         // If doing a "threaded" snapshot, they need to specify how many threads to use (param 1)
328                                         // They can also use debug mode if they pass the word "DEBUG" to do the nodes one (param 2)
329                                         // They can also pass a delayTimer - how many milliseconds to put between each node's ADD (param 3)
330                                         try {
331                                                 debugAddDelayTime = cArgs.debugAddDelayTime;
332                                         } catch (NumberFormatException nfe) {
333                                                 ErrorLogHelper.logError("AAI_6128",     "Bad (non-integer) debugAddDelayTime passed to DataSnapshot ["
334                                                                                 + cArgs.debugAddDelayTime + "]");
335                                                 LOGGER.debug("Bad (non-integer) debugAddDelayTime passed to DataSnapshot ["+ cArgs.debugAddDelayTime + "]");
336                                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
337                                         }
338                                         LOGGER.debug(" Will do Threaded Snapshot with threadCount = "+ threadCount4Create + ", DEBUG-flag set to: "
339                                                         + debug4Create + ", and addDelayTimer = " + debugAddDelayTime + " mSec. ");
340                                 }
341                         }
342                         else {
343                                 ErrorLogHelper.logError("AAI_6128", "Wrong param count (should be 2,3 or 4) when using THREADED_SNAPSHOT.");
344                                 LOGGER.debug("Wrong param count (should be 2,3 or 4) when using THREADED_SNAPSHOT.");
345                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
346                         }
347                 }
348                 else if( command.equals("MULTITHREAD_RELOAD") ){
349                         // Note - this will use as many threads as the snapshot file is
350                         //   broken up into.  (up to a limit)
351                         if (args.length >= 2) {
352                                 // Since they are re-loading, they need to pass the snapshot file name to use.
353                                 // We expected the file to be found in our snapshot directory.  Note - if
354                                 // it is a multi-part snapshot, then this should be the root of the name.
355                                 // We will be using the default delay timers.
356                                 oldSnapshotFileName = cArgs.oldFileName;
357                                 vertAddDelayMs = cArgs.vertAddDelayMs;
358                                 edgeAddDelayMs = cArgs.edgeAddDelayMs;
359                                 failureDelayMs = cArgs.failureDelayMs;
360                                 retryDelayMs = cArgs.retryDelayMs;
361                                 try {
362                                         maxErrorsPerThread = cArgs.maxErrorsPerThread;
363                                 }
364                                 catch ( NumberFormatException nfe ){
365                                         ErrorLogHelper.logError("AAI_6128", "Bad (non-integer) maxErrorsPerThread passed to DataSnapshot [" + cArgs.maxErrorsPerThread + "]");
366                                         LOGGER.debug("Bad (non-integer) maxErrorsPerThread passed to DataSnapshot [" + cArgs.maxErrorsPerThread + "]");
367                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
368                                 }
369                                 if( maxErrorsPerThread < 1  ){
370                                         ErrorLogHelper.logError("AAI_6128", "Out of range (>0) maxErrorsPerThread passed to DataSnapshot [" + cArgs.maxErrorsPerThread + "]");
371                                         LOGGER.debug("Out of range (>0) maxErrorsPerThread passed to DataSnapshot [" + cArgs.maxErrorsPerThread + "]");
372                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
373                                 }
374                         }
375                         else {
376                                 ErrorLogHelper.logError("AAI_6128", "Wrong param count (should be either 2 or 7) when using MUTLITHREAD_RELOAD.");
377                                 LOGGER.debug("Wrong param count (should be 2 or 7) when using MUTLITHREAD_RELOAD.");
378                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
379                         }
380                 }
381                 else if (command.equals("CLEAR_ENTIRE_DATABASE")) {
382                         if (args.length >= 2) {
383                                 oldSnapshotFileName = cArgs.oldFileName;
384                         }
385                 }
386                 long scriptStartTime = System.currentTimeMillis();
387                 
388                 threadCount4Create = cArgs.threadCount; 
389                 
390                 //Print Defaults
391                 LOGGER.debug("DataSnapshot4HistInit command is [" + cArgs.command + "]");
392                 LOGGER.debug("File name to reload snapshot [" + cArgs.oldFileName + "]");
393                 LOGGER.debug("snapshotType is [" + cArgs.snapshotType + "]");
394                 LOGGER.debug("Thread count is [" + cArgs.threadCount + "]");
395                 LOGGER.debug("Debug Flag is [" + cArgs.debugFlag + "]");
396                 LOGGER.debug("DebugAddDelayTimer is [" + cArgs.debugAddDelayTime + "]");
397                 LOGGER.debug("VertAddDelayMs is [" + cArgs.vertAddDelayMs + "]");
398                 LOGGER.debug("FailureDelayMs is [" + cArgs.failureDelayMs + "]");
399                 LOGGER.debug("RetryDelayMs is [" + cArgs.retryDelayMs + "]");
400                 LOGGER.debug("MaxErrorsPerThread is [" + cArgs.maxErrorsPerThread + "]");
401                 LOGGER.debug("VertToEdgeProcDelay is [" + cArgs.vertToEdgeProcDelay + "]");
402                 LOGGER.debug("StaggerThreadDelay is [" + cArgs.staggerThreadDelay + "]");
403                 LOGGER.debug("Caller process is ["+ cArgs.caller + "]");
404                 
405                 //Print non-default values
406                 if (!AAIConfig.isEmpty(cArgs.fileName)){
407                         LOGGER.debug("Snapshot file name (if not default) to use  is [" + cArgs.fileName + "]");
408                 }
409                 if (!AAIConfig.isEmpty(cArgs.snapshotDir)){
410                         LOGGER.debug("Snapshot file Directory path (if not default) to use is [" + cArgs.snapshotDir + "]");
411                 }
412                 if (!AAIConfig.isEmpty(cArgs.oldFileDir)){
413                         LOGGER.debug("Directory path (if not default) to load the old snapshot file from is [" + cArgs.oldFileDir + "]");
414                 }
415                 
416                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
417                 try {
418                         AAIConfig.init();
419                         ErrorLogHelper.loadProperties();
420                         LOGGER.debug("Command = " + command + ", oldSnapshotFileName = [" + oldSnapshotFileName + "].");
421                         String targetDir = AAIConstants.AAI_HOME + AAIConstants.AAI_FILESEP + "logs" + AAIConstants.AAI_FILESEP + "data" + AAIConstants.AAI_FILESEP + "dataSnapshots";
422                         // Make sure the dataSnapshots directory is there
423                         new File(targetDir).mkdirs();
424
425                         LOGGER.debug("    ---- NOTE --- about to open graph (takes a little while) ");
426                         
427                         if ( (command.equals("THREADED_SNAPSHOT") || command.equals("JUST_TAKE_SNAPSHOT"))
428                                         && threadCount4Create == 1 ){
429                                 // -------------------------------------------------------------------------------
430                                 // They want to take a snapshot on a single thread and have it go in a single file
431                                 //   NOTE - they can't use the DEBUG option in this case.
432                                 // -------------------------------------------------------------------------------
433                                 LOGGER.debug(" Command = " + command );
434                                 verifyGraph(AAIGraph.getInstance().getGraph());
435                                 FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT");
436                                 String dteStr = fd.getDateTime();
437                                 graph = AAIGraph.getInstance().getGraph();
438                                 GraphAdminDBUtils.logConfigs(graph.configuration());
439                                 String newSnapshotOutFname = null;
440                                 long timeA = System.nanoTime();
441                                 newSnapshotOutFname = targetDir + AAIConstants.AAI_FILESEP + "dataSnapshot.graphSON." + dteStr;
442                                 graph.io(IoCore.graphson()).writeGraph(newSnapshotOutFname);
443                                 LOGGER.debug("Snapshot written to " + newSnapshotOutFname);
444                                 long timeB = System.nanoTime();
445                                 long diffTime =  timeB - timeA;
446                                 long minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
447                                 long secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
448                                 LOGGER.debug("    -- Single-Thread dataSnapshot took: " +
449                                                 minCount + " minutes, " + secCount + " seconds " );
450         
451                         }       
452                         else if ( (command.equals("THREADED_SNAPSHOT") || command.equals("JUST_TAKE_SNAPSHOT")) 
453                                         && threadCount4Create > 1 ){
454                                         // ------------------------------------------------------------
455                                         // They want the creation of the snapshot to be spread out via 
456                                         //    threads and go to multiple files
457                                         // ------------------------------------------------------------
458                                         LOGGER.debug(" Command = " + command );
459                                         String newSnapshotOutFname;
460                                         if (!AAIConfig.isEmpty(cArgs.fileName)){
461                                                 newSnapshotOutFname = cArgs.fileName;
462                                         } else {
463                                         FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT");
464                                         String dteStr = fd.getDateTime();
465                                         newSnapshotOutFname = targetDir + AAIConstants.AAI_FILESEP + "dataSnapshot.graphSON." + dteStr;
466                                         }
467                                         verifyGraph(AAIGraph.getInstance().getGraph());
468                                         graph = AAIGraph.getInstance().getGraph();
469                                         LOGGER.debug(" Successfully got the Graph instance. ");
470                                         GraphAdminDBUtils.logConfigs(graph.configuration());
471                                         long timeA = System.nanoTime();
472
473                                         LOGGER.debug("Count how many nodes are in the db. ");
474                                         long totalVertCount = graph.traversal().V().count().next();
475                                         LOGGER.debug(" Total Count of Nodes in DB = " + totalVertCount + ".");
476                                         long timeA2 = System.nanoTime();
477                                         long diffTime =  timeA2 - timeA;
478                                         long minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
479                                         long secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
480                                         LOGGER.debug("    -- To count all vertices in DB it took: " +
481                                                         minCount + " minutes, " + secCount + " seconds " );
482                                         
483                                         int fileCount4Create = figureOutFileCount( totalVertCount, threadCount4Create, 
484                                                         maxNodesPerFile4Create );
485                                         int threadPassesNeeded = (int) Math.ceil((double)fileCount4Create / (double)threadCount4Create);        
486                                         long nodesPerFile = (long) Math.ceil((double)totalVertCount / (double)fileCount4Create);  
487                                         
488                                         LOGGER.debug(" We will run this many simultaneous threads: " + threadCount4Create );
489                                         LOGGER.debug(" Required number of passes: " + threadPassesNeeded );
490                                         LOGGER.debug(" Max Nodes per file: " + maxNodesPerFile4Create );
491                                         LOGGER.debug(" We will generate this many files: " + fileCount4Create );
492                                         LOGGER.debug(" Each file will have (roughly): " + nodesPerFile + " nodes.");
493                                         LOGGER.debug(" Now, divide vertexIds across this many files: " + fileCount4Create );
494
495                                         HashMap <String,ArrayList<Long>> vertIdListHash = new HashMap <String,ArrayList<Long>> ();
496                                         for( int t = 0; t < fileCount4Create; t++ ){
497                                                 ArrayList <Long> vIdList = new ArrayList <Long> ();
498                                                 String tk = "" + t;
499                                                 vertIdListHash.put( tk, vIdList);
500                                         }
501                                                                 
502                                         int currentTNum = 0; 
503                                         String currentTKey = "0";
504                                         long thisThrIndex = 0;
505                                         Iterator <Vertex> vtxItr = graph.vertices();  // Getting ALL vertices!
506                                         while( vtxItr.hasNext() ){
507                                                 // Divide up ALL the vertices so we can process them on different threads
508                                                 thisThrIndex++;
509                                                 if( (thisThrIndex >= nodesPerFile) && (currentTNum < (fileCount4Create - 1)) ){
510                                                         // We will need to start adding to the Hash for the next file
511                                                         currentTNum++;
512                                                         currentTKey = "" + currentTNum;
513                                                         thisThrIndex = 0;
514                                                 }
515                                                 long vid = (long)(vtxItr.next()).id();
516                                                 (vertIdListHash.get(currentTKey)).add(vid);
517                                         }
518                                 
519                                         // close this graph instance thing here since we have all the ids
520                                         graph.tx().rollback();
521                                         graph.tx().close();
522                                         
523                                         long timeB = System.nanoTime();
524                                         diffTime =  timeB - timeA2;
525                                         minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
526                                         secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
527                                         LOGGER.debug("    -- To Loop over all vertices, and put them into sub-Arrays it took: " +
528                                                         minCount + " minutes, " + secCount + " seconds " );
529
530                                         // Need to print out each set of vertices using it's own thread
531                                         // NOTE - we may have more files to generate than number of threads - which
532                                         //    just means that ALL the files won't necessarily be generated in parallel.
533                                         
534                                         int fileNo = 0;
535                                         for( int passNo = 1; passNo <= threadPassesNeeded; passNo++ ){          
536                                                 ArrayList <Thread> threadArr = new ArrayList <Thread> ();
537                                                 // For each Pass, kick off all the threads and wait until they finish
538                                                 long timeP1 = System.nanoTime();
539                                                 for( int thNum = 0; thNum < threadCount4Create; thNum++ ){
540                                                         String fileNoStr = "" + fileNo;
541                                                         String subFName = newSnapshotOutFname + ".P" + fileNoStr;
542                                                         LOGGER.debug(" DEBUG >>> kick off pass # " + passNo + ", thread # " + thNum);
543                                                         Thread thr = new Thread(new PrintVertexDetails(graph, subFName, 
544                                                                         vertIdListHash.get(fileNoStr),
545                                                                         debug4Create, debugAddDelayTime, 
546                                                                         snapshotType, LOGGER) );
547                                                         thr.start();
548                                                         threadArr.add(thr);
549                                                         fileNo++;
550                                                 }                                       
551                                                 // Make sure all the threads finish before considering this Pass finished.
552                                                 for( int thNum = 0; thNum < threadCount4Create; thNum++ ){
553                                                         if( null != threadArr.get(thNum) ){
554                                                                 (threadArr.get(thNum)).join();
555                                                         }
556                                                 }
557                                                 long timeP2 = System.nanoTime();
558                                                 diffTime =  timeP2 - timeP1;
559                                                 minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
560                                                 secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
561                                                 LOGGER.debug(" Pass number " + passNo + " (out of " + threadPassesNeeded +
562                                                                 ") took " + minCount + " minutes, " + secCount + " seconds ");
563                                         }
564                                         
565                                         long timeC = System.nanoTime();
566                                         diffTime =  timeC - timeB;
567                                         minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
568                                         secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
569                                         LOGGER.debug("   -- To write all the data out to snapshot files, it took: " +
570                                                         minCount + " minutes, " + secCount + " seconds " );
571
572                                         
573                         } else if( command.equals("MULTITHREAD_RELOAD") ){
574                                 // ---------------------------------------------------------------------
575                                 // They want the RELOAD of the snapshot to be spread out via threads
576                                 // NOTE - it will only use as many threads as the number of files the
577                                 //    snapshot is  written to.  Ie. if you have a single-file snapshot,
578                                 //    then this will be single-threaded.
579                                 // If the number of files is greater than the 'threadCount' parameter,
580                                 //    then we will use more than one pass to keep the number of simultaneous 
581                                 //    threads below the threadCount param.
582                                 //
583                                 LOGGER.debug(" Command = " + command );
584                                 
585                                 if (cArgs.oldFileDir != null && cArgs.oldFileDir != ""){
586                                         targetDir = cArgs.oldFileDir;
587                                 }
588                                 ArrayList <File> snapFilesArr = getFilesToProcess(targetDir, oldSnapshotFileName, false);
589                                 int fCount = snapFilesArr.size();
590                                 int threadPassesNeeded = (int) Math.ceil((double)fCount / (double)threadCount4Create);
591                                 int filesPerPass = (int) Math.ceil((double)fCount / (double)threadPassesNeeded);
592                                 
593                                 JanusGraph graph1 = AAIGraph.getInstance().getGraph();
594                                 long timeStart = System.nanoTime();
595                                 GraphAdminDBUtils.logConfigs(graph1.configuration());
596                                 HashMap <String,String> old2NewVertIdMap = new HashMap <String,String>  ();
597                                 HashMap <String,ArrayList<String>> nodeKeyNames = new  HashMap <String,ArrayList<String>> ();                   
598                                 try {
599                                         LOGGER.debug("call getNodeKeyNames ()" );
600                                         nodeKeyNames = getNodeKeyNames();
601                                 } catch (Exception e) {
602                                         AAIException ae = new AAIException("AAI_6128", e , "Error - Could not get node Key names "+e.getMessage());
603                                         ErrorLogHelper.logException(ae);
604                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
605                                 }
606
607                                 ExecutorService executor = Executors.newFixedThreadPool(fCount);
608                                 int threadFailCount = 0;
609                                 
610                                 LOGGER.debug(" -- vertAddDelayMs = " + vertAddDelayMs
611                                                 + ", failureDelayMs = " + failureDelayMs + ", retryDelayMs = " + retryDelayMs
612                                                 + ", maxErrorsPerThread = " + maxErrorsPerThread );
613                                         
614                                 // --------------------------------------
615                                 // Step 1 -- Load empty vertices
616                                 // --------------------------------------
617                                 int fileNo = 0;
618                                 for( int passNo = 1; passNo <= threadPassesNeeded; passNo++ ){
619                                         List<Future<HashMap<String,String>>> listFutV = new ArrayList<Future<HashMap<String,String>>>();
620
621                                         int thisPassCount = 0;
622                                         while( (thisPassCount < filesPerPass) && (fileNo < fCount) ){
623                                                 File f = snapFilesArr.get(fileNo);
624                                                 String fname = f.getName();
625                                                 String fullSnapName = targetDir + AAIConstants.AAI_FILESEP + fname;
626                                                 Thread.sleep(cArgs.staggerThreadDelay);  // Stagger the threads a bit
627                                                 LOGGER.debug(" -- Read file: [" + fullSnapName + "]");
628                                                 Callable <HashMap<String,String>> vLoader = new PartialVertexLoader(graph1, fullSnapName,
629                                                                 vertAddDelayMs, failureDelayMs, retryDelayMs, maxErrorsPerThread, LOGGER);
630                                                 Future <HashMap<String,String>> future = (Future<HashMap<String, String>>) executor.submit(vLoader);
631
632                                                 // add future to the list, we can get return value later
633                                                 listFutV.add(future);
634                                                 LOGGER.debug(" --  Starting PartialDbLoad VERT_ONLY file # "+ fileNo
635                                                                 + "( passNo = " + passNo + ", passIndex = " + thisPassCount + ")");
636                                                 
637                                                 thisPassCount++;
638                                                 fileNo++;
639                                         }
640                                         
641                                         int threadCount4Reload = 0;
642                                         for(Future<HashMap<String,String>> fut : listFutV){
643                                                 threadCount4Reload++;
644                                                 try {
645                                                         old2NewVertIdMap.putAll(fut.get());
646                                                         LOGGER.debug(" -- back from PartialVertexLoader.  returned pass # " 
647                                                                         + passNo + ", thread # " 
648                                                                         + threadCount4Reload +
649                                                                         ", current size of old2NewVertMap is: " + old2NewVertIdMap.size() );
650                                                 }
651                                                 catch (InterruptedException e) {
652                                                         threadFailCount++;
653                                                         AAIException ae = new AAIException("AAI_6128", e , "InterruptedException");
654                                                         ErrorLogHelper.logException(ae);
655                                                 }
656                                                 catch (ExecutionException e) {
657                                                         threadFailCount++;
658                                                         AAIException ae = new AAIException("AAI_6128", e , "ExecutionException");
659                                                         ErrorLogHelper.logException(ae);
660                                                 }
661                                         }
662                                 } // end of passes for loading empty vertices
663                                         
664                                 executor.shutdown();
665                                 if( threadFailCount > 0 ) {
666                                         String emsg = " FAILURE >> " + threadFailCount + " Vertex-loader thread(s) failed to complete successfully.  ";
667                                         LOGGER.debug(emsg);
668                                         throw new Exception( emsg );
669                                 }
670
671                                 long timeX = System.nanoTime();
672                                 long diffTime =  timeX - timeStart;
673                                 long minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
674                                 long secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
675                                 LOGGER.debug("   -- To reload just the vertex ids from the snapshot files, it took: " +
676                                                 minCount + " minutes, " + secCount + " seconds " );
677
678                                 // Give the DB a little time to chew on all those new vertices
679                                 Thread.sleep(vertToEdgeProcDelay);
680
681                                         
682                                 // -------------------------------------------------------------
683                                 // Step 2 -- Load Edges and properties onto the empty vertices
684                                 // -------------------------------------------------------------
685                                 LOGGER.debug("\n\n\n  -- Now load the edges/properties ----------------------");
686                                 executor = Executors.newFixedThreadPool(fCount);
687
688                                 fileNo = 0;
689                                 for( int passNo = 1; passNo <= threadPassesNeeded; passNo++ ){
690                                         ArrayList<Future<ArrayList<String>>> listFutEdg = new ArrayList<Future<ArrayList<String>>>();
691
692                                         int thisPassCount = 0;
693                                         while( (thisPassCount < filesPerPass) && (fileNo < fCount) ){
694                                                 File f = snapFilesArr.get(fileNo);                                                              
695                                                 String fname = f.getName();
696                                                 String fullSnapName = targetDir + AAIConstants.AAI_FILESEP + fname;
697                                                 Thread.sleep(cArgs.staggerThreadDelay);  // Stagger the threads a bit
698                                                 LOGGER.debug(" -- Read file: [" + fullSnapName + "]");
699                                                 Callable eLoader = new PartialPropAndEdgeLoader4HistInit(graph1, fullSnapName,
700                                                                 edgeAddDelayMs, failureDelayMs, retryDelayMs,
701                                                                 old2NewVertIdMap, maxErrorsPerThread, LOGGER,
702                                                                 scriptStartTime, nodeKeyNames);
703                                                 
704                                                 Future <ArrayList<String>> future = (Future<ArrayList<String>>) executor.submit(eLoader);
705
706                                                 // add future to the list, we can wait for it below
707                                                 listFutEdg.add(future);
708                                                 LOGGER.debug(" --  Starting PartialPropAndEdgeLoader4HistInit file # "
709                                                                 + fileNo + " (pass # " + passNo + ", passIndex " 
710                                                                 + thisPassCount + ")" );
711                                                 
712                                                 thisPassCount++;
713                                                 fileNo++;
714                                         }
715
716                                         int threadCount4Reload = 0;
717                                         for( Future<ArrayList<String>> fut : listFutEdg ){
718                                                 threadCount4Reload++;
719                                                 try{
720                                                         fut.get();  
721                                                         LOGGER.debug(" -- back from PartialPropAndEdgeLoader4HistInit.  pass # "
722                                                                         + passNo + ", thread # " + threadCount4Reload  );
723                                                 }
724                                                 catch (InterruptedException e) {
725                                                         threadFailCount++;
726                                                         AAIException ae = new AAIException("AAI_6128", e , "InterruptedException");
727                                                         ErrorLogHelper.logException(ae);
728                                                 }
729                                                 catch (ExecutionException e) {
730                                                         threadFailCount++;
731                                                         AAIException ae = new AAIException("AAI_6128", e , "ExecutionException");
732                                                         ErrorLogHelper.logException(ae);
733                                                 }
734                                         }
735                                         
736                                 } // end of passes for reloading edges and properties 
737
738                                 executor.shutdown();
739
740                                 if( threadFailCount > 0 ) {
741                                         String emsg = " FAILURE >> " + threadFailCount + " Property/Edge-loader thread(s) failed to complete successfully.  ";
742                                         LOGGER.debug(emsg);
743                                         throw new Exception( emsg );
744                                 }
745
746                                 // This is needed so we can see the data committed by the called threads
747                                 graph1.tx().commit();
748
749                                 long timeEnd = System.nanoTime();
750                                 diffTime =  timeEnd - timeX;
751                                 minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
752                                 secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
753                                 LOGGER.debug("   -- To reload the edges and properties from snapshot files, it took: " +
754                                                 minCount + " minutes, " + secCount + " seconds " );
755
756                                 long totalDiffTime =  timeEnd - timeStart;
757                                 long totalMinCount = TimeUnit.NANOSECONDS.toMinutes(totalDiffTime);
758                                 long totalSecCount = TimeUnit.NANOSECONDS.toSeconds(totalDiffTime) - (60 * totalMinCount);
759                                 LOGGER.debug("   -- TOTAL multi-threaded reload time: " +
760                                                 totalMinCount + " minutes, " + totalSecCount + " seconds " );
761                         
762                         } else if (command.equals("CLEAR_ENTIRE_DATABASE")) {
763                                 // ------------------------------------------------------------------
764                                 // They are calling this to clear the db before re-loading it
765                                 // later
766                                 // ------------------------------------------------------------------
767                                 LOGGER.debug(" Command = " + command );
768                                 // First - make sure the backup file(s) they will be using can be
769                                 // found and has(have) data.
770                                 // getFilesToProcess makes sure the file(s) exist and have some data.
771                                 getFilesToProcess(targetDir, oldSnapshotFileName, true);
772                                 LOGGER.debug(" WARNING <<<< ");
773                                 LOGGER.debug(">>> All data and schema in this database will be removed at this point. <<<");
774                                 LOGGER.debug(">>> Processing will begin in 5 seconds. <<<");
775                                 LOGGER.debug(">>> WARNING <<<< ");
776
777                                 try {
778                                         // Give them a chance to back out of this
779                                         Thread.sleep(5000);
780                                 } catch (java.lang.InterruptedException ie) {
781                                         LOGGER.debug(" DB Clearing has been aborted. ");
782                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
783                                 }
784
785                                 LOGGER.debug(" Begin clearing out old data. ");
786                                 String rtConfig = AAIConstants.REALTIME_DB_CONFIG;
787                                 String serviceName = System.getProperty("aai.service.name", DataSnapshot4HistInit.class.getSimpleName());
788                                 LOGGER.debug("Getting new configs for clearig");
789                                 
790                                 PropertiesConfiguration propertiesConfiguration = new AAIGraphConfig.Builder(rtConfig).forService(serviceName).withGraphType(REALTIME_DB).buildConfiguration();
791                                 LOGGER.debug("Open New Janus Graph");
792                                 
793                                 JanusGraph janusGraph = JanusGraphFactory.open(propertiesConfiguration);
794                                 verifyGraph(janusGraph);
795                                 GraphAdminDBUtils.logConfigs(janusGraph.configuration());
796                                 janusGraph.close();
797                                 JanusGraphCleanup.clear(janusGraph);
798                                 LOGGER.debug(" Done clearing data. ");
799                                 LOGGER.debug(">>> IMPORTANT - NOTE >>> you need to run the SchemaGenerator (use GenTester) before ");
800                                 LOGGER.debug("     reloading data or the data will be put in without indexes. ");
801                                 dbClearFlag = true;
802                                 LOGGER.debug("All done clearing DB");
803                                 
804                         } else if (command.equals("RELOAD_DATA")) {
805                                 // ---------------------------------------------------------------------------
806                                 // They want to restore the database from either a single file, or a group
807                                 // of snapshot files.  Either way, this command will restore via single
808                                 // threaded processing.
809                                 // ---------------------------------------------------------------------------
810                                 LOGGER.debug(" Command = " + command );
811                                 verifyGraph(AAIGraph.getInstance().getGraph());
812                                 graph = AAIGraph.getInstance().getGraph();
813                                 GraphAdminDBUtils.logConfigs(graph.configuration());
814                                 if (oldSnapshotFileName.equals("")) {
815                                         String emsg = "No oldSnapshotFileName passed to DataSnapshot when RELOAD_DATA used.";
816                                         LOGGER.debug(emsg);
817                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
818                                 }
819                                 
820                                 long timeA = System.nanoTime();
821
822                                 ArrayList <File> snapFilesArr = new ArrayList <File> ();
823
824                                 // First, see if this is a single file (ie. no ".P#" suffix)
825                                 String onePieceSnapshotFname = targetDir + AAIConstants.AAI_FILESEP + oldSnapshotFileName;
826                                 File sf = new File(onePieceSnapshotFname);
827                                 if( sf.exists() ){
828                                         snapFilesArr.add(sf);
829                                 }
830                                 else {
831                                         // If it's a multi-part snapshot, then collect all the files for it
832                                         String thisSnapPrefix = oldSnapshotFileName + ".P";
833                                         File fDir = new File(targetDir); // Snapshot directory
834                                         File[] allFilesArr = fDir.listFiles();
835                                         for (File snapFile : allFilesArr) {
836                                                 String snapFName = snapFile.getName();
837                                                 if( snapFName.startsWith(thisSnapPrefix)){
838                                                         snapFilesArr.add(snapFile);
839                                                 }
840                                         }
841                                 }
842                                 
843                                 if( snapFilesArr.isEmpty() ){
844                                         String emsg = "oldSnapshotFile " + onePieceSnapshotFname + "(with or without .P0) could not be found.";
845                                         LOGGER.debug(emsg);
846                                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
847                                 }
848                                 
849                                 int fCount = snapFilesArr.size();
850                                 Vector<InputStream> inputStreamsV = new Vector<>();                  
851                                 for( int i = 0; i < fCount; i++ ){
852                                         File f = snapFilesArr.get(i);
853                                         String fname = f.getName();
854                                         if (!f.canRead()) {
855                                                 String emsg = "oldSnapshotFile " + fname + " could not be read.";
856                                                 LOGGER.debug(emsg);
857                                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
858                                         } else if (f.length() == 0) {
859                                                 String emsg = "oldSnapshotFile " + fname + " had no data.";
860                                                 LOGGER.debug(emsg);
861                                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
862                                         }
863                                         String fullFName = targetDir + AAIConstants.AAI_FILESEP + fname;
864                                         InputStream fis = new FileInputStream(fullFName);
865                                         inputStreamsV.add(fis);
866                                 }
867
868                                 // Now add inputStreams.elements() to the Vector,
869                             // inputStreams.elements() will return Enumerations
870                             InputStream sis = new SequenceInputStream(inputStreamsV.elements());
871                             LOGGER.debug("Begin loading data from " + fCount + " files  -----");
872                             if("gryo".equalsIgnoreCase(snapshotType)){
873                                         graph.io(IoCore.gryo()).reader().create().readGraph(sis, graph);
874                                 } else {
875                                         graph.io(IoCore.graphson()).reader().create().readGraph(sis, graph);
876                                 }
877                                 LOGGER.debug("Completed the inputGraph command, now try to commit()... ");
878                                 graph.tx().commit();
879                                 LOGGER.debug("Completed reloading data.");
880
881                                 long vCount = graph.traversal().V().count().next();
882                                 LOGGER.debug("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db.");
883                                 
884                                 long timeB = System.nanoTime();
885                                 long diffTime =  timeB - timeA;
886                                 long minCount = TimeUnit.NANOSECONDS.toMinutes(diffTime);
887                                 long secCount = TimeUnit.NANOSECONDS.toSeconds(diffTime) - (60 * minCount);
888                                 LOGGER.debug("    -- To Reload this snapshot, it took: " +
889                                                 minCount + " minutes, " + secCount + " seconds " );
890                                 
891                                 LOGGER.debug("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db.");
892
893                         } else {
894                                 String emsg = "Bad command passed to DataSnapshot: [" + command + "]";
895                                 LOGGER.debug(emsg);
896                                 AAISystemExitUtil.systemExitCloseAAIGraph(1);
897                         }
898
899                 } catch (AAIException e) {
900                         AAIException ae = new AAIException("AAI_6128", e , "Encountered an exception during the datasnapshot:"+e.getMessage());
901                         ErrorLogHelper.logException(ae);
902                         success = false;
903                 } catch (Exception ex) {
904                         AAIException ae = new AAIException("AAI_6128", ex , "Encountered an exception during the datasnapshot");
905                         ErrorLogHelper.logException(ae);
906                         success = false;
907                 } finally {
908                         if (!dbClearFlag && graph != null && !MIGRATION_PROCESS_NAME.equalsIgnoreCase(source)) {
909                                 // Any changes that worked correctly should have already done
910                                 // thier commits.
911                                 if(!"true".equals(System.getProperty("org.onap.aai.graphadmin.started"))) {
912                                         if (graph.isOpen()) {
913                                                 graph.tx().rollback();
914                                                 graph.close();
915                                         }
916                                 }
917                         }
918                         try {
919                                 baos.close();
920                         } catch (IOException iox) {
921                         }
922                 }
923
924                 return success;
925         }
926         
927     public static HashMap <String,ArrayList<String>> getNodeKeyNames()  {
928         
929         HashMap <String,ArrayList<String>> keyNameHash = new HashMap <String,ArrayList<String>> ();
930         Loader loader = LoaderUtil.getLatestVersion(); 
931                 Set<Entry<String, Introspector>> entrySet = loader.getAllObjects().entrySet();
932         // Get a collection of the names of the key properties for each nodeType
933                 for (Entry<String, Introspector> entry : entrySet) {
934                         String nType = entry.getKey();
935                         Set <String> keyPropsSet = entry.getValue().getKeys();
936                         ArrayList <String> keyProps = new ArrayList <String> ();
937                         keyProps.addAll(keyPropsSet);
938                         keyNameHash.put(nType, keyProps);       
939                 }
940                 return keyNameHash;
941     }
942     
943     
944         private static ArrayList <File> getFilesToProcess(String targetDir, String oldSnapshotFileName, boolean doingClearDb)
945                 throws Exception {
946
947                 if( oldSnapshotFileName == null || oldSnapshotFileName.equals("") ){
948                         String emsg = "No oldSnapshotFileName passed to DataSnapshot for Reload.  ";
949                         if( doingClearDb ) {
950                                 emsg = "No oldSnapshotFileName passed to DataSnapshot. Needed when Clearing the db in case we need a backup.  ";
951                         }
952                         LOGGER.debug(emsg);
953                         throw new Exception( emsg );
954                 }
955
956                 ArrayList <File> snapFilesArrList = new ArrayList <File> ();
957
958                 // First, we'll assume that this is a multi-file snapshot and
959                 //    look for names based on that.
960                 String thisSnapPrefix = oldSnapshotFileName + ".P";
961                 File fDir = new File(targetDir); // Snapshot directory
962                 File[] allFilesArr = fDir.listFiles();
963                 for (File snapFile : allFilesArr) {
964                         String snapFName = snapFile.getName();
965                         if( snapFName.startsWith(thisSnapPrefix)){
966                                 if (!snapFile.canRead()) {
967                                         String emsg = "oldSnapshotFile " + snapFName + " could not be read.";
968                                         LOGGER.debug(emsg);
969                                         throw new Exception (emsg);
970                                 } else if (snapFile.length() == 0) {
971                                         String emsg = "oldSnapshotFile " + snapFName + " had no data.";
972                                         LOGGER.debug(emsg);
973                                         throw new Exception (emsg);
974                                 }
975                                 snapFilesArrList.add(snapFile);
976                         }
977                 }
978
979                 if( snapFilesArrList.isEmpty() ){
980                         // Multi-file snapshot check did not find files, so this may
981                         //   be a single-file snapshot.
982                         String oldSnapshotFullFname = targetDir + AAIConstants.AAI_FILESEP + oldSnapshotFileName;
983                         File f = new File(oldSnapshotFullFname);
984                         if (!f.exists()) {
985                                 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " could not be found.";
986                                 LOGGER.debug(emsg);
987                                 throw new Exception (emsg);
988                         } else if (!f.canRead()) {
989                                 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " could not be read.";
990                                 LOGGER.debug(emsg);
991                                 throw new Exception (emsg);
992                         } else if (f.length() == 0) {
993                                 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " had no data.";
994                                 LOGGER.debug(emsg);
995                                 throw new Exception (emsg);
996                         }
997                         snapFilesArrList.add(f);
998                 }
999
1000                 if( snapFilesArrList.isEmpty() ){
1001                         // Still haven't found anything..  that was not a good file name.
1002                         String fullFName = targetDir + AAIConstants.AAI_FILESEP + thisSnapPrefix;
1003                         String emsg = "oldSnapshotFile " + fullFName + "* could not be found.";
1004                         LOGGER.debug(emsg);
1005                         throw new Exception(emsg);
1006                 }
1007
1008                 return snapFilesArrList;
1009         }
1010
1011
1012         public static void verifyGraph(JanusGraph graph) {
1013
1014                 if (graph == null) {
1015                         String emsg = "Not able to get a graph object in DataSnapshot.java\n";
1016                         LOGGER.debug(emsg);
1017                         AAISystemExitUtil.systemExitCloseAAIGraph(1);
1018                 }
1019
1020         }
1021
1022         
1023         public static int figureOutFileCount( long totalVertCount, int threadCount4Create, 
1024                         long maxNodesPerFile ) {
1025                 
1026                 // NOTE - we would always like to use all of our threads.  That is, if
1027                 //   we could process all the data with 16 threads, but our threadCount4Create is
1028                 //   only 15, we will do two passes and use all 15 threads each pass which will 
1029                 //   create a total of 30 files.  Each file will be a bit smaller so the overall
1030                 //   time for the two passes should be faster.
1031                 if( totalVertCount <= 0 || threadCount4Create <= 0 || maxNodesPerFile <= 0) {
1032                         return 1;
1033                 }
1034                 
1035                 long maxNodesPerPass = threadCount4Create * maxNodesPerFile;    
1036                 int numberOfPasses = (int) Math.ceil( (double)totalVertCount / (double)maxNodesPerPass);        
1037                 int fileCt = threadCount4Create * numberOfPasses;
1038                 
1039                 return fileCt;          
1040         }
1041         
1042
1043         class CommandLineArgs {
1044
1045                 @Parameter(names = "--help", help = true)
1046                 public boolean help;
1047
1048                 @Parameter(names = "-c", description = "command for taking data snapshot")
1049                 public String command = "JUST_TAKE_SNAPSHOT";
1050
1051                 @Parameter(names = "-f", description = "previous snapshot file to reload")
1052                 public String oldFileName = "";
1053
1054                 @Parameter(names = "-snapshotType", description = "snapshot type of gryo or graphson")
1055                 public String snapshotType = "graphson";
1056
1057                 @Parameter(names = "-threadCount", description = "thread count for create")
1058                 public int threadCount = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_THREADS_FOR_CREATE;
1059                                 
1060                 @Parameter(names = "-maxNodesPerFile", description = "Max nodes per file")
1061                 public long maxNodesPerFile = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_NODES_PER_FILE_FOR_CREATE;
1062
1063                 @Parameter(names = "-debugFlag", description = "DEBUG flag")
1064                 public String debugFlag = "";
1065
1066                 @Parameter(names = "-debugAddDelayTime", description = "delay in ms between each Add for debug mode")
1067                 public long debugAddDelayTime = 1L;
1068                 
1069                 @Parameter(names = "-vertAddDelayMs", description = "delay in ms while adding each vertex")
1070                 public long vertAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_ADD_DELAY_MS.longValue();
1071                 
1072                 @Parameter(names = "-edgeAddDelayMs", description = "delay in ms while adding each edge")
1073                 public long edgeAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_EDGE_ADD_DELAY_MS.longValue();
1074                 
1075                 @Parameter(names = "-failureDelayMs", description = "delay in ms when failure to load vertex or edge in snapshot")
1076                 public long failureDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_FAILURE_DELAY_MS.longValue();
1077
1078                 @Parameter(names = "-retryDelayMs", description = "time in ms after which load snapshot is retried")
1079                 public long retryDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_FAILURE_DELAY_MS.longValue();
1080
1081                 @Parameter(names = "-maxErrorsPerThread", description = "max errors allowed per thread")
1082                 public int maxErrorsPerThread = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_ERRORS_PER_THREAD;
1083                 
1084                 @Parameter(names = "-vertToEdgeProcDelay", description = "vertex to edge processing delay in ms")
1085                 public long vertToEdgeProcDelay = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_TO_EDGE_PROC_DELAY_MS.longValue();
1086                 
1087                 @Parameter(names = "-staggerThreadDelay", description = "thread delay stagger time in ms")
1088                 public long staggerThreadDelay = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_STAGGER_THREAD_DELAY_MS;
1089                 
1090                 @Parameter(names = "-fileName", description = "file name for generating snapshot ")
1091                 public String fileName = "";
1092                 
1093                 @Parameter(names = "-snapshotDir", description = "file path for generating snapshot ")
1094                 public String snapshotDir = "";
1095                 
1096                 @Parameter(names = "-oldFileDir", description = "directory containing the old snapshot file for reloading")
1097                 public String oldFileDir = "";
1098                 
1099                 @Parameter(names = "-caller", description = "process invoking the dataSnapshot")
1100                 public String caller = "";
1101                 
1102         }
1103         
1104 }