/* Copyright 2015 MITRE Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mitre.provenance.tools;
import org.mitre.provenance.PLUSException;
import org.mitre.provenance.client.LocalProvenanceClient;
import org.mitre.provenance.client.ProvenanceClientException;
import org.mitre.provenance.client.RESTProvenanceClient;
import org.mitre.provenance.simulate.SyntheticGraphProperties;
import org.mitre.provenance.simulate.motif.RandomMotifCollection;
import java.io.FileWriter;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Scanner;
/**
* A looper tool to upload synthetic motif graphs to a Provenance node of your choosing.
* A synthetic graph can be controlled by volume (node count) and density (connectivity)
* This was initially created to stress-test a Provenance node.
* @author Alexander Marr
*/
public class RemoteLoader {
/*
connectivity refers to the density of the graph while graphSize refers to its volume.
minTime is the minimum time a graph took to upload to the server while maxTime is the maximum.
testtime is a placeholder value to later find the average time it took for all graphs to upload.
*/
static int graphSize, numGraphs, actors, nodes, edges, npe;
static float connectivity;
static long testtime=0, count=1, minTime, maxTime, time;
static FileWriter writer;
public static void performTest(RESTProvenanceClient SynthLink, int graphSize, float connectivity, int numGraphs, String writeCSV) throws PLUSException, IOException {
/* Initializing the RESTProvenanceclient and the graph we're going to be working with, respectively.
Feel free to change "prov04.mitre.org" to another server and "8080" to the listening port on that server.*/
SyntheticGraphProperties Synth = new SyntheticGraphProperties().setComponents(graphSize).setConnectivity(connectivity);
//Initialize CSV file-writing stream and write the CSV file-header. Default file location in {HOME}/user/UploadCSV.txt
if (writeCSV.equals("y")){
try{
writer = new FileWriter(System.getProperty("user.home") + "\\RemoteUploadCSV.txt");
writer.append("Upload Number(1), Time to Upload in seconds(2), actors(3), nodes(4), edges(5), npes(6), connectivity(7)" + String.format("%n"));
}
catch (Exception e)
{
System.out.println("Error with CSVWRITER. Printing Stack Trace: ");
e.printStackTrace();
}
}
switch (numGraphs) {
//case for an infinite loop
case 0:
while (numGraphs == 0) {
System.out.printf("Generating Motif Graph number " + count + "........");
RandomMotifCollection RandomMotif = new RandomMotifCollection(Synth); //construct REST graph
System.out.printf( " done.%n");
Instant start = Instant.now(); //Start timer to record how long Uploading takes
System.out.println("Uploading graph number " + count + "......... ");
SynthLink.report(RandomMotif, "quiet"); //Uploading to prov04.mitre.org
Instant end = Instant.now(); //End timer
testtime = testtime + Duration.between(start,end).getSeconds(); //record total time
if (maxTime < Duration.between(start,end).getSeconds()) {maxTime = Duration.between(start,end).getSeconds();} //record maximum time
if (count == 1) {minTime = Duration.between(start,end).getSeconds();}
if (minTime > Duration.between(start,end).getSeconds()) { minTime = Duration.between(start,end).getSeconds();} //record minimum time
printTotalTimes("Completed run number " + count + " in " + Duration.between(start,end).getSeconds() + " seconds!");
//get actors, nodes, edges, npe (non-provenance edge), and time
actors = RandomMotif.countActors();
nodes = RandomMotif.countNodes();
edges = RandomMotif.countEdges();
npe = RandomMotif.countNPEs();
time = Duration.between(start,end).getSeconds();
//appending info to the CSV file
if (writeCSV.equals("y")) {
writer.append(count + "," + time + "," + actors + "," + nodes + "," + edges + "," + npe + "," + connectivity + String.format("%n"));
writer.flush();}
count++;
}
//case for finite loop
default:
for (int i=1; i<=numGraphs; i++) {
System.out.printf("Generating Motif Graph number " + i + "........");
RandomMotifCollection RandomMotif = new RandomMotifCollection(Synth);
System.out.printf(" done.%n");
Instant start = Instant.now();
System.out.printf("Uploading Graph number " + i + "......... ");
SynthLink.report(RandomMotif, "quiet");
Instant end = Instant.now();
System.out.println("done.");
testtime = testtime + Duration.between(start,end).getSeconds();
if (maxTime < Duration.between(start,end).getSeconds()) {maxTime = Duration.between(start,end).getSeconds();} //record maximum time
if (i == 1) {minTime = Duration.between(start,end).getSeconds();}
if (minTime > Duration.between(start,end).getSeconds()) { minTime = Duration.between(start,end).getSeconds();} //record minimum time
printTotalTimes("Completed run number " + i + " in " + Duration.between(start,end).getSeconds() + " seconds!");
actors = RandomMotif.countActors();
nodes = RandomMotif.countNodes();
edges = RandomMotif.countEdges();
npe = RandomMotif.countNPEs();
time = Duration.between(start,end).getSeconds();
if (writeCSV.equals("y")) {
writer.append(count + "," + time + "," + actors + "," + nodes + "," + edges + "," + npe + "," + connectivity + String.format("%n"));
writer.flush();}
count++;
}
}
}
public static void performTest(LocalProvenanceClient SynthLink, int graphSize, float connectivity, int numGraphs, String writeCSV) throws PLUSException, IOException {
/* Initializing the RESTProvenanceclient and the graph we're going to be working with, respectively.
Feel free to change "prov04.mitre.org" to another server and "8080" to the listening port on that server.*/
SyntheticGraphProperties Synth = new SyntheticGraphProperties().setComponents(graphSize).setConnectivity(connectivity);
//Initialize CSV file-writing stream and write the CSV file-header. Default file location in {HOME}/user/UploadCSV.txt
if (writeCSV.equals("y")){
try{
writer = new FileWriter(System.getProperty("user.home") + "\\LocalUploadCSV.txt");
writer.append("Upload Number(1), Time to Upload in seconds(2), actors(3), nodes(4), edges(5), npes(6), connectivity(7)" + String.format("%n"));
}
catch (Exception e)
{
System.out.println("Error with CSVWRITER. Printing Stack Trace: ");
e.printStackTrace();
}
}
switch (numGraphs) {
//case for an infinite loop
case 0:
while (numGraphs == 0) {
System.out.printf("Generating Motif Graph number " + count + "........");
RandomMotifCollection RandomMotif = new RandomMotifCollection(Synth); //construct REST graph
System.out.printf( " done.%n");
Instant start = Instant.now(); //Start timer to record how long Uploading takes
System.out.println("Uploading graph number " + count + "......... ");
SynthLink.report(RandomMotif); //Uploading to prov04.mitre.org
Instant end = Instant.now(); //End timer
testtime = testtime + Duration.between(start,end).getSeconds(); //record total time
if (maxTime < Duration.between(start,end).getSeconds()) {maxTime = Duration.between(start,end).getSeconds();} //record maximum time
if (count == 1) {minTime = Duration.between(start,end).getSeconds();}
if (minTime > Duration.between(start,end).getSeconds()) { minTime = Duration.between(start,end).getSeconds();} //record minimum time
printTotalTimes("Completed run number " + count + " in " + Duration.between(start,end).getSeconds() + " seconds!");
//get actors, nodes, edges, npe (non-provenance edge), and time
actors = RandomMotif.countActors();
nodes = RandomMotif.countNodes();
edges = RandomMotif.countEdges();
npe = RandomMotif.countNPEs();
time = Duration.between(start,end).getSeconds();
//appending info to the CSV file
if (writeCSV.equals("y")) {
writer.append(count + "," + time + "," + actors + "," + nodes + "," + edges + "," + npe + "," + connectivity + String.format("%n"));
writer.flush();}
count++;
}
//case for finite loop
default:
for (int i=1; i<=numGraphs; i++) {
System.out.printf("Generating Motif Graph number " + i + "........");
RandomMotifCollection RandomMotif = new RandomMotifCollection(Synth);
System.out.printf(" done.%n");
Instant start = Instant.now();
System.out.printf("Uploading Graph number " + i + "......... ");
SynthLink.report(RandomMotif);
Instant end = Instant.now();
System.out.println("done.");
testtime = testtime + Duration.between(start,end).getSeconds();
if (maxTime < Duration.between(start,end).getSeconds()) {maxTime = Duration.between(start,end).getSeconds();} //record maximum time
if (i == 1) {minTime = Duration.between(start,end).getSeconds();}
if (minTime > Duration.between(start,end).getSeconds()) { minTime = Duration.between(start,end).getSeconds();} //record minimum time
printTotalTimes("Completed run number " + i + " in " + Duration.between(start,end).getSeconds() + " seconds!");
actors = RandomMotif.countActors();
nodes = RandomMotif.countNodes();
edges = RandomMotif.countEdges();
npe = RandomMotif.countNPEs();
time = Duration.between(start,end).getSeconds();
if (writeCSV.equals("y")) {
writer.append(count + "," + time + "," + actors + "," + nodes + "," + edges + "," + npe + "," + connectivity + String.format("%n"));
writer.flush();}
count++;
}
}
}
public static void testRemote() throws ProvenanceClientException, PLUSException, IOException {
//Initialize input scanner
Scanner input = new Scanner(System.in);
//initializing the number of nodes we want in our generated graph
System.out.println("Enter Number of Nodes: ");
graphSize = input.nextInt();
//Initializing connectivity of our generated graph
System.out.println("Enter connectivity of nodes (0 < x < 1): ");
connectivity = input.nextFloat();
//How many times do we want to send unique graphs? Entering 0 loops infinitely.
System.out.println("Enter number of times to loop (enter 0 for infinite loop): ");
numGraphs = input.nextInt();
//Decide whether to write a csv file
System.out.println("Write to CSV file (y/n)?");
String writeCSV = input.next();
input.close();
performTest(new RESTProvenanceClient("prov04.mitre.org", "8080"), graphSize, connectivity, numGraphs, writeCSV);
}
public static void testLocal() throws PLUSException, IOException {
//Initialize input scanner
Scanner input = new Scanner(System.in);
//initializing the number of nodes we want in our generated graph
System.out.println("Enter Number of Nodes: ");
graphSize = input.nextInt();
//Initializing connectivity of our generated graph
System.out.println("Enter connectivity of nodes (0 < x < 1): ");
connectivity = input.nextFloat();
//How many times do we want to send unique graphs? Entering 0 loops infinitely.
System.out.println("Enter number of times to loop (enter 0 for infinite loop): ");
numGraphs = input.nextInt();
//Decide whether to write a csv file
System.out.println("Write to CSV file (y/n)?");
String writeCSV = input.next();
input.close();
performTest(new LocalProvenanceClient(), graphSize, connectivity, numGraphs, writeCSV);
}
public static void printTotalTimes(String s)
{
for(int i=0; i<=50; i++)
{
System.out.printf("-");
}
System.out.printf("%n");
System.out.println(s);
//Total Times recorded in seconds
System.out.println("\n......... TOTAL UPLOAD TIME = " + testtime);
System.out.println("......... AVERAGE UPLOAD TIME = " + (testtime/count));
System.out.println("......... MINIMUM UPLOAD TIME = " + minTime);
System.out.println("......... MAXIMUM UPLOAD TIME = " + maxTime);
for(int i=0; i<=50; i++)
{
System.out.printf("-");
}
System.out.printf("%n");
}
public static void main(String[] args) throws PLUSException, IOException {
Scanner main_input = new Scanner(System.in);
System.out.println("Test Local or Remote (local/remote)?");
String LocalorRemote = main_input.next();
if (LocalorRemote.equals("local")) { testLocal(); }
else {testRemote();}
main_input.close();
}
}