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.datasnapshot;
22 import java.io.ByteArrayOutputStream;
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;
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;
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;
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;
76 public class DataSnapshot4HistInit {
78 private static Logger LOGGER = LoggerFactory.getLogger(DataSnapshot4HistInit.class);
80 /* Using realtime d */
81 private static final String REALTIME_DB = "realtime";
83 private static final Set<String> SNAPSHOT_RELOAD_COMMANDS = new HashSet<>();
85 private static final String MIGRATION_PROCESS_NAME = "migration";
87 private static boolean historyEnabled;
89 private LoaderFactory loaderFactory;
90 private SchemaVersions schemaVersions;
93 SNAPSHOT_RELOAD_COMMANDS.add("RELOAD_DATA");
94 SNAPSHOT_RELOAD_COMMANDS.add("RELOAD_DATA_MULTI");
97 private CommandLineArgs cArgs;
99 public DataSnapshot4HistInit(LoaderFactory loaderFactory, SchemaVersions schemaVersions){
100 this.loaderFactory = loaderFactory;
101 this.schemaVersions = schemaVersions;
110 public static void main(String[] args) {
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);
119 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
120 PropertyPasswordConfiguration initializer = new PropertyPasswordConfiguration();
121 initializer.initialize(ctx);
124 "org.onap.aai.config",
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);
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);
143 LoaderFactory loaderFactory = ctx.getBean(LoaderFactory.class);
144 SchemaVersions schemaVersions = (SchemaVersions) ctx.getBean("schemaVersions");
145 DataSnapshot4HistInit dataSnapshotHI = new DataSnapshot4HistInit(loaderFactory, schemaVersions);
147 boolean success = dataSnapshotHI.executeCommand(args);
149 AAISystemExitUtil.systemExitCloseAAIGraph(0);
151 AAISystemExitUtil.systemExitCloseAAIGraph(1);
157 public boolean executeCommand(String[] args) {
159 Boolean dbClearFlag = false;
160 JanusGraph graph = null;
161 String command = "UNKNOWN";
162 String oldSnapshotFileName = "";
163 boolean success = true;
165 cArgs = new CommandLineArgs();
166 String itemName = "aai.datasnapshot.threads.for.create";
168 String val = AAIConfig.get(itemName);
169 if( val != null && !val.equals("") ){
170 cArgs.threadCount = Integer.parseInt(val);
172 }catch ( Exception e ){
173 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
175 int threadCount4Create = cArgs.threadCount;
177 itemName = "aai.datasnapshot.max.nodes.per.file.for.create";
179 String val = AAIConfig.get(itemName);
180 if( val != null && !val.equals("") ){
181 cArgs.maxNodesPerFile = Long.parseLong(val);
183 }catch ( Exception e ){
184 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
186 long maxNodesPerFile4Create = cArgs.maxNodesPerFile;
188 cArgs.snapshotType = "graphson";
189 Long vertAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_ADD_DELAY_MS;
190 itemName = "aai.datasnapshot.vertex.add.delay.ms";
192 String val = AAIConfig.get(itemName);
193 if( val != null && !val.equals("") ){
194 cArgs.vertAddDelayMs = Long.parseLong(val);
196 }catch ( Exception e ){
197 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
200 Long edgeAddDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_EDGE_ADD_DELAY_MS;
201 itemName = "aai.datasnapshot.edge.add.delay.ms";
203 String val = AAIConfig.get(itemName);
204 if( val != null && !val.equals("") ){
205 cArgs.edgeAddDelayMs = Long.parseLong(val);
207 }catch ( Exception e ){
208 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
211 Long failureDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_FAILURE_DELAY_MS;
212 itemName = "aai.datasnapshot.failure.delay.ms";
214 String val = AAIConfig.get(itemName);
215 if( val != null && !val.equals("") ){
216 cArgs.failureDelayMs = Long.parseLong(val);
218 }catch ( Exception e ){
219 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
222 Long retryDelayMs = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_RETRY_DELAY_MS;
223 itemName = "aai.datasnapshot.retry.delay.ms";
225 String val = AAIConfig.get(itemName);
226 if( val != null && !val.equals("") ){
227 cArgs.retryDelayMs = Long.parseLong(val);
229 }catch ( Exception e ){
230 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
233 int maxErrorsPerThread = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_ERRORS_PER_THREAD;
234 itemName = "aai.datasnapshot.max.errors.per.thread";
236 String val = AAIConfig.get(itemName);
237 if( val != null && !val.equals("") ){
238 cArgs.maxErrorsPerThread = Integer.parseInt(val);
240 }catch ( Exception e ){
241 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
244 Long vertToEdgeProcDelay = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_VERTEX_TO_EDGE_PROC_DELAY_MS;
245 itemName = "aai.datasnapshot.vertex.to.edge.proc.delay.ms";
247 String val = AAIConfig.get(itemName);
248 if( val != null && !val.equals("") ){
249 cArgs.vertToEdgeProcDelay = Long.parseLong(val);
251 }catch ( Exception e ){
252 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
255 itemName = "aai.datasnapshot.stagger.thread.delay.ms";
257 String val = AAIConfig.get(itemName);
258 if( val != null && !val.equals("") ){
259 cArgs.staggerThreadDelay = Long.parseLong(val);
261 }catch ( Exception e ){
262 LOGGER.warn("WARNING - could not get [" + itemName + "] value from aaiconfig.properties file. " + e.getMessage());
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;
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);
278 if (args.length >= 1) {
279 command = cArgs.command;
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;
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
296 threadCount4Create = cArgs.threadCount;
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);
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);
308 LOGGER.debug(" Will do Threaded Snapshot with threadCount = " + threadCount4Create );
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);
316 LOGGER.debug(" Will do Threaded Snapshot with maxNodesPerFile = " + maxNodesPerFile4Create );
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") ){
323 LOGGER.debug(" Will do Threaded Snapshot with threadCount = " + threadCount4Create +
324 ", and DEBUG-flag set to: " + 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)
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);
338 LOGGER.debug(" Will do Threaded Snapshot with threadCount = "+ threadCount4Create + ", DEBUG-flag set to: "
339 + debug4Create + ", and addDelayTimer = " + debugAddDelayTime + " mSec. ");
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);
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;
362 maxErrorsPerThread = cArgs.maxErrorsPerThread;
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);
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);
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);
381 else if (command.equals("CLEAR_ENTIRE_DATABASE")) {
382 if (args.length >= 2) {
383 oldSnapshotFileName = cArgs.oldFileName;
386 long scriptStartTime = System.currentTimeMillis();
388 threadCount4Create = cArgs.threadCount;
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 + "]");
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 + "]");
409 if (!AAIConfig.isEmpty(cArgs.snapshotDir)){
410 LOGGER.debug("Snapshot file Directory path (if not default) to use is [" + cArgs.snapshotDir + "]");
412 if (!AAIConfig.isEmpty(cArgs.oldFileDir)){
413 LOGGER.debug("Directory path (if not default) to load the old snapshot file from is [" + cArgs.oldFileDir + "]");
416 ByteArrayOutputStream baos = new ByteArrayOutputStream();
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();
425 LOGGER.debug(" ---- NOTE --- about to open graph (takes a little while) ");
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 " );
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;
463 FormatDate fd = new FormatDate("yyyyMMddHHmm", "GMT");
464 String dteStr = fd.getDateTime();
465 newSnapshotOutFname = targetDir + AAIConstants.AAI_FILESEP + "dataSnapshot.graphSON." + dteStr;
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();
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 " );
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);
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 );
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> ();
499 vertIdListHash.put( tk, vIdList);
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
509 if( (thisThrIndex >= nodesPerFile) && (currentTNum < (fileCount4Create - 1)) ){
510 // We will need to start adding to the Hash for the next file
512 currentTKey = "" + currentTNum;
515 long vid = (long)(vtxItr.next()).id();
516 (vertIdListHash.get(currentTKey)).add(vid);
519 // close this graph instance thing here since we have all the ids
520 graph.tx().rollback();
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 " );
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.
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) );
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();
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 ");
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 " );
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.
583 LOGGER.debug(" Command = " + command );
585 if (cArgs.oldFileDir != null && cArgs.oldFileDir != ""){
586 targetDir = cArgs.oldFileDir;
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);
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>> ();
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);
607 ExecutorService executor = Executors.newFixedThreadPool(fCount);
608 int threadFailCount = 0;
610 LOGGER.debug(" -- vertAddDelayMs = " + vertAddDelayMs
611 + ", failureDelayMs = " + failureDelayMs + ", retryDelayMs = " + retryDelayMs
612 + ", maxErrorsPerThread = " + maxErrorsPerThread );
614 // --------------------------------------
615 // Step 1 -- Load empty vertices
616 // --------------------------------------
618 for( int passNo = 1; passNo <= threadPassesNeeded; passNo++ ){
619 List<Future<HashMap<String,String>>> listFutV = new ArrayList<Future<HashMap<String,String>>>();
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);
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 + ")");
641 int threadCount4Reload = 0;
642 for(Future<HashMap<String,String>> fut : listFutV){
643 threadCount4Reload++;
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() );
651 catch (InterruptedException e) {
653 AAIException ae = new AAIException("AAI_6128", e , "InterruptedException");
654 ErrorLogHelper.logException(ae);
656 catch (ExecutionException e) {
658 AAIException ae = new AAIException("AAI_6128", e , "ExecutionException");
659 ErrorLogHelper.logException(ae);
662 } // end of passes for loading empty vertices
665 if( threadFailCount > 0 ) {
666 String emsg = " FAILURE >> " + threadFailCount + " Vertex-loader thread(s) failed to complete successfully. ";
668 throw new Exception( emsg );
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 " );
678 // Give the DB a little time to chew on all those new vertices
679 Thread.sleep(vertToEdgeProcDelay);
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);
689 for( int passNo = 1; passNo <= threadPassesNeeded; passNo++ ){
690 ArrayList<Future<ArrayList<String>>> listFutEdg = new ArrayList<Future<ArrayList<String>>>();
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);
704 Future <ArrayList<String>> future = (Future<ArrayList<String>>) executor.submit(eLoader);
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 + ")" );
716 int threadCount4Reload = 0;
717 for( Future<ArrayList<String>> fut : listFutEdg ){
718 threadCount4Reload++;
721 LOGGER.debug(" -- back from PartialPropAndEdgeLoader4HistInit. pass # "
722 + passNo + ", thread # " + threadCount4Reload );
724 catch (InterruptedException e) {
726 AAIException ae = new AAIException("AAI_6128", e , "InterruptedException");
727 ErrorLogHelper.logException(ae);
729 catch (ExecutionException e) {
731 AAIException ae = new AAIException("AAI_6128", e , "ExecutionException");
732 ErrorLogHelper.logException(ae);
736 } // end of passes for reloading edges and properties
740 if( threadFailCount > 0 ) {
741 String emsg = " FAILURE >> " + threadFailCount + " Property/Edge-loader thread(s) failed to complete successfully. ";
743 throw new Exception( emsg );
746 // This is needed so we can see the data committed by the called threads
747 graph1.tx().commit();
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 " );
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 " );
762 } else if (command.equals("CLEAR_ENTIRE_DATABASE")) {
763 // ------------------------------------------------------------------
764 // They are calling this to clear the db before re-loading it
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 <<<< ");
778 // Give them a chance to back out of this
780 } catch (java.lang.InterruptedException ie) {
781 LOGGER.debug(" DB Clearing has been aborted. ");
782 AAISystemExitUtil.systemExitCloseAAIGraph(1);
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");
790 PropertiesConfiguration propertiesConfiguration = new AAIGraphConfig.Builder(rtConfig).forService(serviceName).withGraphType(REALTIME_DB).buildConfiguration();
791 LOGGER.debug("Open New Janus Graph");
793 JanusGraph janusGraph = JanusGraphFactory.open(propertiesConfiguration);
794 verifyGraph(janusGraph);
795 GraphAdminDBUtils.logConfigs(janusGraph.configuration());
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. ");
802 LOGGER.debug("All done clearing DB");
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.";
817 AAISystemExitUtil.systemExitCloseAAIGraph(1);
820 long timeA = System.nanoTime();
822 ArrayList <File> snapFilesArr = new ArrayList <File> ();
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);
828 snapFilesArr.add(sf);
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);
843 if( snapFilesArr.isEmpty() ){
844 String emsg = "oldSnapshotFile " + onePieceSnapshotFname + "(with or without .P0) could not be found.";
846 AAISystemExitUtil.systemExitCloseAAIGraph(1);
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();
855 String emsg = "oldSnapshotFile " + fname + " could not be read.";
857 AAISystemExitUtil.systemExitCloseAAIGraph(1);
858 } else if (f.length() == 0) {
859 String emsg = "oldSnapshotFile " + fname + " had no data.";
861 AAISystemExitUtil.systemExitCloseAAIGraph(1);
863 String fullFName = targetDir + AAIConstants.AAI_FILESEP + fname;
864 InputStream fis = new FileInputStream(fullFName);
865 inputStreamsV.add(fis);
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);
875 graph.io(IoCore.graphson()).reader().create().readGraph(sis, graph);
877 LOGGER.debug("Completed the inputGraph command, now try to commit()... ");
879 LOGGER.debug("Completed reloading data.");
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.");
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 " );
891 LOGGER.debug("A little after repopulating from an old snapshot, we see: " + vCount + " vertices in the db.");
894 String emsg = "Bad command passed to DataSnapshot: [" + command + "]";
896 AAISystemExitUtil.systemExitCloseAAIGraph(1);
899 } catch (AAIException e) {
900 AAIException ae = new AAIException("AAI_6128", e , "Encountered an exception during the datasnapshot:"+e.getMessage());
901 ErrorLogHelper.logException(ae);
903 } catch (Exception ex) {
904 AAIException ae = new AAIException("AAI_6128", ex , "Encountered an exception during the datasnapshot");
905 ErrorLogHelper.logException(ae);
908 if (!dbClearFlag && graph != null && !MIGRATION_PROCESS_NAME.equalsIgnoreCase(source)) {
909 // Any changes that worked correctly should have already done
911 if(!"true".equals(System.getProperty("org.onap.aai.graphadmin.started"))) {
912 if (graph.isOpen()) {
913 graph.tx().rollback();
920 } catch (IOException iox) {
927 public static HashMap <String,ArrayList<String>> getNodeKeyNames() {
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);
944 private static ArrayList <File> getFilesToProcess(String targetDir, String oldSnapshotFileName, boolean doingClearDb)
947 if( oldSnapshotFileName == null || oldSnapshotFileName.equals("") ){
948 String emsg = "No oldSnapshotFileName passed to DataSnapshot for Reload. ";
950 emsg = "No oldSnapshotFileName passed to DataSnapshot. Needed when Clearing the db in case we need a backup. ";
953 throw new Exception( emsg );
956 ArrayList <File> snapFilesArrList = new ArrayList <File> ();
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.";
969 throw new Exception (emsg);
970 } else if (snapFile.length() == 0) {
971 String emsg = "oldSnapshotFile " + snapFName + " had no data.";
973 throw new Exception (emsg);
975 snapFilesArrList.add(snapFile);
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);
985 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " could not be found.";
987 throw new Exception (emsg);
988 } else if (!f.canRead()) {
989 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " could not be read.";
991 throw new Exception (emsg);
992 } else if (f.length() == 0) {
993 String emsg = "oldSnapshotFile " + oldSnapshotFullFname + " had no data.";
995 throw new Exception (emsg);
997 snapFilesArrList.add(f);
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.";
1005 throw new Exception(emsg);
1008 return snapFilesArrList;
1012 public static void verifyGraph(JanusGraph graph) {
1014 if (graph == null) {
1015 String emsg = "Not able to get a graph object in DataSnapshot.java\n";
1017 AAISystemExitUtil.systemExitCloseAAIGraph(1);
1023 public static int figureOutFileCount( long totalVertCount, int threadCount4Create,
1024 long maxNodesPerFile ) {
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) {
1035 long maxNodesPerPass = threadCount4Create * maxNodesPerFile;
1036 int numberOfPasses = (int) Math.ceil( (double)totalVertCount / (double)maxNodesPerPass);
1037 int fileCt = threadCount4Create * numberOfPasses;
1043 class CommandLineArgs {
1045 @Parameter(names = "--help", help = true)
1046 public boolean help;
1048 @Parameter(names = "-c", description = "command for taking data snapshot")
1049 public String command = "JUST_TAKE_SNAPSHOT";
1051 @Parameter(names = "-f", description = "previous snapshot file to reload")
1052 public String oldFileName = "";
1054 @Parameter(names = "-snapshotType", description = "snapshot type of gryo or graphson")
1055 public String snapshotType = "graphson";
1057 @Parameter(names = "-threadCount", description = "thread count for create")
1058 public int threadCount = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_THREADS_FOR_CREATE;
1060 @Parameter(names = "-maxNodesPerFile", description = "Max nodes per file")
1061 public long maxNodesPerFile = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_NODES_PER_FILE_FOR_CREATE;
1063 @Parameter(names = "-debugFlag", description = "DEBUG flag")
1064 public String debugFlag = "";
1066 @Parameter(names = "-debugAddDelayTime", description = "delay in ms between each Add for debug mode")
1067 public long debugAddDelayTime = 1L;
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();
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();
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();
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();
1081 @Parameter(names = "-maxErrorsPerThread", description = "max errors allowed per thread")
1082 public int maxErrorsPerThread = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_MAX_ERRORS_PER_THREAD;
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();
1087 @Parameter(names = "-staggerThreadDelay", description = "thread delay stagger time in ms")
1088 public long staggerThreadDelay = GraphAdminConstants.AAI_SNAPSHOT_DEFAULT_STAGGER_THREAD_DELAY_MS;
1090 @Parameter(names = "-fileName", description = "file name for generating snapshot ")
1091 public String fileName = "";
1093 @Parameter(names = "-snapshotDir", description = "file path for generating snapshot ")
1094 public String snapshotDir = "";
1096 @Parameter(names = "-oldFileDir", description = "directory containing the old snapshot file for reloading")
1097 public String oldFileDir = "";
1099 @Parameter(names = "-caller", description = "process invoking the dataSnapshot")
1100 public String caller = "";