Skip to content
Snippets Groups Projects
Commit 9aaa4320 authored by leahhedgcorth's avatar leahhedgcorth
Browse files

Added code to run the Arrival Process class

parent 3ce4bc9d
No related branches found
No related tags found
No related merge requests found
/** /**
* Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. * Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved.
* This work is provided under a BSD open-source license, see project license.html and license.txt * This work is provided under a BSD open-source license, see project license.html and license.txt
* *
* This Program is a modified version of ExampleSimulationProgram in order to see the * This Program is a modified version of ExampleSimulationProgram in order to see the
* verbose plain text pdu log. This simulates a firewall identifying a malicious packet * verbose plain text pdu log. This simulates a firewall identifying a malicious packet
* and tracing its source before destroying it - updated September 12, 2021 to ensure * and tracing its source before destroying it - updated September 12, 2021 to ensure
* correct file pushed to Gitlab. * correct file pushed to Gitlab.
* *
* @author Bruce Chojnacki * @author Bruce Chojnacki
*/ */
package MV3500Cohort2023MarchJune.homework3.Chojnacki; package MV3500Cohort2023MarchJune.homework3.Chojnacki;
...@@ -20,19 +20,21 @@ import java.util.ArrayList; ...@@ -20,19 +20,21 @@ import java.util.ArrayList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** The purpose of this program is to provide an easily modifiable example simulation program /**
* that includes DIS-capable entities doing tasks and reporting them to the network. * The purpose of this program is to provide an easily modifiable example
* Default settings include PDU recording turned on by default. * simulation program that includes DIS-capable entities doing tasks and
* reporting them to the network. Default settings include PDU recording turned
* on by default.
*/ */
public class ExampleSimulationProgram public class ExampleSimulationProgram {
{
private boolean verboseComments = true; private boolean verboseComments = true;
static final String NETWORK_ADDRESS_DEFAULT = "239.1.2.3"; static final String NETWORK_ADDRESS_DEFAULT = "239.1.2.3";
static final int NETWORK_PORT_DEFAULT = 3000; static final int NETWORK_PORT_DEFAULT = 3000;
static String networkAddress = NETWORK_ADDRESS_DEFAULT; static String networkAddress = NETWORK_ADDRESS_DEFAULT;
static int networkPort = NETWORK_PORT_DEFAULT; static int networkPort = NETWORK_PORT_DEFAULT;
String DEFAULT_OUTPUT_DIRECTORY = "./pduLog"; String DEFAULT_OUTPUT_DIRECTORY = "./pduLog";
private EntityID createFriendFireWall() { private EntityID createFriendFireWall() {
EntityID FNFireWallID = new EntityID(); // 1.1.225.1.1.1 Platform,Cyber,USA,FireWall EntityID FNFireWallID = new EntityID(); // 1.1.225.1.1.1 Platform,Cyber,USA,FireWall
FNFireWallID.setSiteID(13); FNFireWallID.setSiteID(13);
...@@ -40,7 +42,7 @@ public class ExampleSimulationProgram ...@@ -40,7 +42,7 @@ public class ExampleSimulationProgram
FNFireWallID.setEntityID(103); FNFireWallID.setEntityID(103);
return FNFireWallID; return FNFireWallID;
} }
private EntityType createFriendFireWallType() { private EntityType createFriendFireWallType() {
EntityType FNFireWallType = new EntityType(); EntityType FNFireWallType = new EntityType();
FNFireWallType.setEntityKind(EntityKind.PLATFORM); FNFireWallType.setEntityKind(EntityKind.PLATFORM);
...@@ -51,15 +53,15 @@ public class ExampleSimulationProgram ...@@ -51,15 +53,15 @@ public class ExampleSimulationProgram
FNFireWallType.setSpecific(1); FNFireWallType.setSpecific(1);
return FNFireWallType; return FNFireWallType;
} }
private EntityID createMalPacket() { private EntityID createMalPacket() {
EntityID MalPacketID = new EntityID(); // 1.1.45.1.7.1 Platform,Cyber,China,MaliciousPacket EntityID MalPacketID = new EntityID(); // 1.1.45.1.7.1 Platform,Cyber,China,MaliciousPacket
MalPacketID.setSiteID(66); MalPacketID.setSiteID(66);
MalPacketID.setApplicationID(666); MalPacketID.setApplicationID(666);
MalPacketID.setEntityID(6666); MalPacketID.setEntityID(6666);
return MalPacketID; return MalPacketID;
} }
private EntityType createMalPacketType() { private EntityType createMalPacketType() {
EntityType MalPacketType = new EntityType(); EntityType MalPacketType = new EntityType();
MalPacketType.setEntityKind(EntityKind.PLATFORM); MalPacketType.setEntityKind(EntityKind.PLATFORM);
...@@ -70,7 +72,7 @@ public class ExampleSimulationProgram ...@@ -70,7 +72,7 @@ public class ExampleSimulationProgram
MalPacketType.setSpecific(1); MalPacketType.setSpecific(1);
return MalPacketType; return MalPacketType;
} }
private MunitionDescriptor createTraceroute() { private MunitionDescriptor createTraceroute() {
EntityType TracerouteType = new EntityType(); //2.2.225.2.13.1 EntityType TracerouteType = new EntityType(); //2.2.225.2.13.1
...@@ -87,319 +89,307 @@ public class ExampleSimulationProgram ...@@ -87,319 +89,307 @@ public class ExampleSimulationProgram
Traceroute.setRate(200); Traceroute.setRate(200);
return Traceroute; return Traceroute;
} }
/** /**
* This runSimulationLoops() method is for you, a * This runSimulationLoops() method is for you, a programmer-modifiable
* programmer-modifiable method for defining and running a new simulation of interest. * method for defining and running a new simulation of interest. Welcome!
* Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that * Other parts of this program handle bookkeeping and plumbing tasks so that
* you can focus on your model entities and activities. * you can focus on your model entities and activities. Expandable support
* Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for * includes DIS EntityStatePdu, FirePdu and CommentPdu all available for
* modification and sending in a simulation loop. * modification and sending in a simulation loop. Continuous improvement
* Continuous improvement efforts seek to make this program as easy and straightforward * efforts seek to make this program as easy and straightforward as possible
* as possible for DIS simulationists to use and adapt. * for DIS simulationists to use and adapt. All of the other methods are
* All of the other methods are setup, teardown and configuration that you may find * setup, teardown and configuration that you may find interesting, even
* interesting, even helpful, but don't really have to worry about. * helpful, but don't really have to worry about.
*/ */
@SuppressWarnings("SleepWhileInLoop") // yes we do that @SuppressWarnings("SleepWhileInLoop") // yes we do that
public void runSimulationLoops () public void runSimulationLoops() {
{ try {
try /**
{ * seconds for real-time execution (not simulation time, which may
/** seconds for real-time execution (not simulation time, which may or may not be the same) */ * or may not be the same)
final double SIMULATION_LOOP_DURATION_SECONDS = 1.0; */
final int SIMULATION_MAX_LOOP_COUNT = 15; // be deliberate out out there! also avoid infinite loops. final double SIMULATION_LOOP_DURATION_SECONDS = 1.0;
int simulationLoopCount = 0; // variable, initialized at 0 final int SIMULATION_MAX_LOOP_COUNT = 15; // be deliberate out out there! also avoid infinite loops.
boolean simulationComplete = false; // sentinel variable as termination condition,, are we done yet? int simulationLoopCount = 0; // variable, initialized at 0
boolean fireBool = false; boolean simulationComplete = false; // sentinel variable as termination condition,, are we done yet?
boolean destBool = false; boolean fireBool = false;
boolean destBool = false;
// TODO reset clock to zero each time for consistent outputs
// TODO reset clock to zero each time for consistent outputs
// Your model setup: define participants. who's who in this zoo? // Your model setup: define participants. who's who in this zoo?
// Assuming you keep track of entity objects... here is some support for for Entity 1. // Assuming you keep track of entity objects... here is some support for for Entity 1.
// create PDU object for US Firewall and set its values.
// create PDU object for US Firewall and set its values. //EntityID entityID_1 = new EntityID();
//EntityID entityID_1 = new EntityID(); //entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
//entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu();
entityStatePdu_1.setEntityID(createFriendFireWall());
EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu(); entityStatePdu_1.setEntityType(createFriendFireWallType());
entityStatePdu_1.setEntityID(createFriendFireWall()); entityStatePdu_1.getEntityLocation().setX(0);
entityStatePdu_1.setEntityType(createFriendFireWallType()); entityStatePdu_1.setForceId(ForceID.FRIENDLY);
entityStatePdu_1.getEntityLocation().setX(0);
entityStatePdu_1.setForceId(ForceID.FRIENDLY); // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute?
// create PDU object for Malware Packet and set its values.
// TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? //EntityID entityID_2 = new EntityID();
// create PDU object for Malware Packet and set its values. //entityID_2.setSiteID(4).setApplicationID(5).setEntityID(6);
//EntityID entityID_2 = new EntityID(); EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu();
//entityID_2.setSiteID(4).setApplicationID(5).setEntityID(6); entityStatePdu_2.setEntityID(createMalPacket());
entityStatePdu_2.setEntityType(createMalPacketType());
EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu(); entityStatePdu_2.getEntityLocation().setX(7);
entityStatePdu_2.setEntityID(createMalPacket()); entityStatePdu_2.setForceId(ForceID.OPPOSING);
entityStatePdu_2.setEntityType(createMalPacketType());
entityStatePdu_2.getEntityLocation().setX(7); int MalPacketPingsReceived = 0;
entityStatePdu_2.setForceId(ForceID.OPPOSING);
FirePdu firePdu = pduFactory.makeFirePdu(); // for entity 1 first weapon (possible traceroute)
int MalPacketPingsReceived = 0; // should we customize this munition? what is it for your simulation?
EntityID fireID = new EntityID();
FirePdu firePdu = pduFactory.makeFirePdu(); // for entity 1 first weapon (possible traceroute) fireID.setSiteID(13);
// should we customize this munition? what is it for your simulation? fireID.setApplicationID(43);
EntityID fireID = new EntityID(); fireID.setEntityID(103);
fireID.setSiteID(13); EntityID targetID = new EntityID();
fireID.setApplicationID(43); targetID.setSiteID(66);
fireID.setEntityID(103); targetID.setApplicationID(666);
EntityID targetID = new EntityID(); targetID.setEntityID(6666);
targetID.setSiteID(66);
targetID.setApplicationID(666); firePdu.setFiringEntityID(fireID);
targetID.setEntityID(6666); firePdu.setTargetEntityID(targetID);
firePdu.setFiringEntityID(fireID); firePdu.setDescriptor(createTraceroute()); // calling create Traceroute Method
firePdu.setTargetEntityID(targetID);
EntityID TracerouteID = new EntityID();
firePdu.setDescriptor(createTraceroute()); // calling create Traceroute Method TracerouteID.setEntityID(1);
firePdu.setMunitionExpendibleID(TracerouteID);
EntityID TracerouteID = new EntityID();
TracerouteID.setEntityID(1); CommentReliablePdu MalPacketDestroyedComment = pduFactory.makeCommentReliablePdu("Malware Packet DESTROYED BY Firewall");
firePdu.setMunitionExpendibleID(TracerouteID); CommentReliablePdu MalPacketDetectedComment = pduFactory.makeCommentReliablePdu("Firewall Detects Malware engage Traceroute");
CommentReliablePdu MalPacketDestroyedComment = pduFactory.makeCommentReliablePdu("Malware Packet DESTROYED BY Firewall"); // TODO simulation management PDUs for startup, planning to design special class support
CommentReliablePdu MalPacketDetectedComment = pduFactory.makeCommentReliablePdu("Firewall Detects Malware engage Traceroute"); //DetonationPdu detonationPdu = pduFactory.makeDetonationPdu();
//detonationPdu.setDescriptor(pDescriptor);
// TODO simulation management PDUs for startup, planning to design special class support // loop the simulation while allowed, programmer can set additional conditions to break out and finish
while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet?
//DetonationPdu detonationPdu = pduFactory.makeDetonationPdu(); {
//detonationPdu.setDescriptor(pDescriptor); simulationLoopCount++; // good practice: increment loop counter as first action in that loop
// loop the simulation while allowed, programmer can set additional conditions to break out and finish
while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet?
{
simulationLoopCount++; // good practice: increment loop counter as first action in that loop
// =============================================================================================
// * your own simulation code starts here! *
// =============================================================================================
// are there any other variables to modify at the beginning of your loop?
// compute a track, update an ESPDU, whatever it is that your model is doing...
// Where is my entity? Insert changes in position; this sample only changes X position.
entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX()); // stationary defensive posture
entityStatePdu_2.getEntityLocation().setX(entityStatePdu_2.getEntityLocation().getX() - 1.0); // 1m per timestep
// decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at!
Double range = entityStatePdu_2.getEntityLocation().getX();
System.out.println("range: " + range + " hops from our Network DMZ!");
if (range < 5) { // Range 5
if (!fireBool) {
sendSinglePdu(MalPacketDetectedComment);
}
fireBool = true;
System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "." + firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "." + firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "." + " at Entity#" + firePdu.getTargetEntityID().getEntityID());
if (firePdu.getTargetEntityID().getEntityID() == 6666) { // =============================================================================================
MalPacketPingsReceived += 1; // * your own simulation code starts here! *
if (MalPacketPingsReceived > 1) { // =============================================================================================
// The Firewall destroys the MalPacket // are there any other variables to modify at the beginning of your loop?
// compute a track, update an ESPDU, whatever it is that your model is doing...
// Where is my entity? Insert changes in position; this sample only changes X position.
entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX()); // stationary defensive posture
entityStatePdu_2.getEntityLocation().setX(entityStatePdu_2.getEntityLocation().getX() - 1.0); // 1m per timestep
System.out.println("Malware Packet DESTROYED BY Firewall after " + MalPacketPingsReceived + "pings from the traceroute."); // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at!
narrativeMessage4 = "Destroyed MalPacket"; Double range = entityStatePdu_2.getEntityLocation().getX();
destBool = true; System.out.println("range: " + range + " hops from our Network DMZ!");
simulationComplete = true;
if (range < 5) { // Range 5
if (!fireBool) {
sendSinglePdu(MalPacketDetectedComment);
}
fireBool = true;
System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "." + firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "." + firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "." + " at Entity#" + firePdu.getTargetEntityID().getEntityID());
if (firePdu.getTargetEntityID().getEntityID() == 6666) {
MalPacketPingsReceived += 1;
if (MalPacketPingsReceived > 1) {
// The Firewall destroys the MalPacket
System.out.println("Malware Packet DESTROYED BY Firewall after " + MalPacketPingsReceived + "pings from the traceroute.");
narrativeMessage4 = "Destroyed MalPacket";
destBool = true;
simulationComplete = true;
}
} }
} }
} // etc. etc. your code goes here for your simulation of interest
// etc. etc. your code goes here for your simulation of interest
// something happens between my simulation entities, la de da de da...
// something happens between my simulation entities, la de da de da... System.out.println("Phase complete. Next phase initiating...");
System.out.println ("Phase complete. Next phase initiating...");
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending)
narrativeMessage1 = "MV3500 Homework 3 - Simulation Program";
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) narrativeMessage2 = "runSimulation() loop " + simulationLoopCount;
narrativeMessage1 = "MV3500 Homework 3 - Simulation Program"; narrativeMessage3 = "Simulation Started!"; // intentionally blank for testing
narrativeMessage2 = "runSimulation() loop " + simulationLoopCount;
narrativeMessage3 = "Simulation Started!"; // intentionally blank for testing // your loop termination condition goes here
if (simulationLoopCount > 5) // for example
// your loop termination condition goes here {
if (simulationLoopCount > 5) // for example simulationComplete = true;
{ }
simulationComplete = true; // =============================================================================================
} // * your own simulation code is finished here! *
// ============================================================================================= // =============================================================================================
// * your own simulation code is finished here! *
// ============================================================================================= // staying synchronized with timestep: wait duration for elapsed time in this loop
// Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes
// staying synchronized with timestep: wait duration for elapsed time in this loop Thread.sleep((long) (SIMULATION_LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds
// Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes System.out.println("... [Pausing for " + SIMULATION_LOOP_DURATION_SECONDS + " seconds]");
Thread.sleep((long)(SIMULATION_LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds
System.out.println ("... [Pausing for " + SIMULATION_LOOP_DURATION_SECONDS + " seconds]"); // OK now send the status PDUs for this loop, and then continue
System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
// OK now send the status PDUs for this loop, and then continue sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
System.out.println ("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); sendSinglePdu(entityStatePdu_2); // me too i.e. 2!
sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); System.out.println("... [PDUs successfully sent for this loop]");
sendSinglePdu(entityStatePdu_2); // me too i.e. 2!
System.out.println ("... [PDUs successfully sent for this loop]"); // ===============================
// loop now finished, check whether to terminate if simulation complete, otherwise continue
// =============================== if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good
// loop now finished, check whether to terminate if simulation complete, otherwise continue {
if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good //sendSinglePdu(detonationPdu);
{ System.out.println("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount +
//sendSinglePdu(detonationPdu); break;
System.out.println ("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + }
break; } // end of simulation loop
}
} // end of simulation loop narrativeMessage2 = "runSimulation() completed successfully"; // all done
sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
narrativeMessage2 = "runSimulation() completed successfully"; // all done System.out.println("... [final CommentPdu successfully sent for simulation]");
sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); // TODO simulation management PDUs
System.out.println ("... [final CommentPdu successfully sent for simulation]"); } catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
// TODO simulation management PDUs {
} Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, iex);
catch (InterruptedException iex) // handle any exception that your code might choose to provoke! }
{
Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, iex);
}
} }
/* **************************** infrastructure code, modification is seldom needed ************************* */ /* **************************** infrastructure code, modification is seldom needed ************************* */
String narrativeMessage1 = new String(); String narrativeMessage1 = new String();
String narrativeMessage2 = new String(); String narrativeMessage2 = new String();
String narrativeMessage3 = new String(); String narrativeMessage3 = new String();
String narrativeMessage4 = new String(); String narrativeMessage4 = new String();
/* VariableRecordType enumerations have potential use with CommentPdu logs */ /* VariableRecordType enumerations have potential use with CommentPdu logs */
/* TODO contrast to EntityType */ /* TODO contrast to EntityType */
VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION; VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION;
VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT; VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT;
VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS; VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS;
VariableRecordType timeStepComment = VariableRecordType.APPLICATION_TIMESTEP; VariableRecordType timeStepComment = VariableRecordType.APPLICATION_TIMESTEP;
VariableRecordType otherComment = VariableRecordType.OTHER; VariableRecordType otherComment = VariableRecordType.OTHER;
/** /**
* Output prefix to identify this class, helps with logging * Output prefix to identify this class, helps with logging
*/ */
private final static String TRACE_PREFIX = "[" + ExampleSimulationProgram.class.getName() + "] "; private final static String TRACE_PREFIX = "[" + ExampleSimulationProgram.class.getName() + "] ";
// class variables // class variables
PduFactory pduFactory = new PduFactory(); PduFactory pduFactory = new PduFactory();
DisThreadedNetworkInterface disNetworkInterface; DisThreadedNetworkInterface disNetworkInterface;
DisThreadedNetworkInterface.PduListener pduListener; DisThreadedNetworkInterface.PduListener pduListener;
Pdu receivedPdu; Pdu receivedPdu;
PduRecorder pduRecorder; PduRecorder pduRecorder;
/** /**
* Constructor design goal: additional built-in initialization conveniences can go here * Constructor design goal: additional built-in initialization conveniences
* to keep student efforts focused on the runSimulation() method. * can go here to keep student efforts focused on the runSimulation()
* method.
*/ */
public ExampleSimulationProgram() public ExampleSimulationProgram() {
{
// Constructor is under consideration. Constructor is not currently needed. // Constructor is under consideration. Constructor is not currently needed.
} }
/** /**
* Utility Constructor that allows your example simulation program to override default network address and port * Utility Constructor that allows your example simulation program to
* override default network address and port
*
* @param address network address to use * @param address network address to use
* @param port corresponding network port to use * @param port corresponding network port to use
*/ */
public ExampleSimulationProgram(String address, int port) public ExampleSimulationProgram(String address, int port) {
{
setNetworkAddress(address); setNetworkAddress(address);
setNetworkPort(port); setNetworkPort(port);
} }
/** /**
* get networkAddress * get networkAddress
*
* @return the networkAddress * @return the networkAddress
*/ */
public String getNetworkAddress() public String getNetworkAddress() {
{
return networkAddress; return networkAddress;
} }
/** /**
* set networkAddress * set networkAddress
*
* @param newNetworkAddress the networkAddress to set * @param newNetworkAddress the networkAddress to set
*/ */
public final void setNetworkAddress(String newNetworkAddress) public final void setNetworkAddress(String newNetworkAddress) {
{
ExampleSimulationProgram.networkAddress = newNetworkAddress; ExampleSimulationProgram.networkAddress = newNetworkAddress;
} }
/** /**
* get networkPort * get networkPort
*
* @return the networkPort * @return the networkPort
*/ */
public int getNetworkPort() public int getNetworkPort() {
{
return networkPort; return networkPort;
} }
/** /**
* set networkPort * set networkPort
*
* @param newNetworkPort the networkPort to set * @param newNetworkPort the networkPort to set
*/ */
public final void setNetworkPort(int newNetworkPort) public final void setNetworkPort(int newNetworkPort) {
{
ExampleSimulationProgram.networkPort = newNetworkPort; ExampleSimulationProgram.networkPort = newNetworkPort;
} }
/** /**
* Initialize network interface, choosing best available network interface * Initialize network interface, choosing best available network interface
*/ */
public void setUpNetworkInterface() public void setUpNetworkInterface() {
{
disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort());
disNetworkInterface.setDescriptor ("ExampleSimulationProgramAllen_3 pdu looping"); disNetworkInterface.setDescriptor("ExampleSimulationProgramAllen_3 pdu looping");
System.out.println("Network confirmation:" + System.out.println("Network confirmation:"
" address=" + disNetworkInterface.getAddress()+ // disNetworkInterface.getMulticastGroup() + + " address=" + disNetworkInterface.getAddress()
" port=" + disNetworkInterface.getPort()); // + disNetworkInterface.getDisPort()); + // disNetworkInterface.getMulticastGroup() +
pduListener = new DisThreadedNetworkInterface.PduListener() " port=" + disNetworkInterface.getPort()); // + disNetworkInterface.getDisPort());
{ pduListener = new DisThreadedNetworkInterface.PduListener() {
/** Callback handler for listener */ /**
* Callback handler for listener
*/
@Override @Override
public void incomingPdu(Pdu newPdu) public void incomingPdu(Pdu newPdu) {
{
receivedPdu = newPdu; receivedPdu = newPdu;
} }
}; };
disNetworkInterface.addListener(pduListener); disNetworkInterface.addListener(pduListener);
String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; String outputDirectory = DEFAULT_OUTPUT_DIRECTORY;
System.out.println("Beginning pdu save to directory " + outputDirectory); System.out.println("Beginning pdu save to directory " + outputDirectory);
pduRecorder = new PduRecorder(outputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save pduRecorder = new PduRecorder(outputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save
pduRecorder.setDescriptor ("ExampleSimulationProgramAllen_3 pduRecorder"); pduRecorder.setDescriptor("ExampleSimulationProgramAllen_3 pduRecorder");
pduRecorder.start(); // begin running pduRecorder.start(); // begin running
} }
/** All done, release network resources */ /**
public void tearDownNetworkInterface() * All done, release network resources
{ */
public void tearDownNetworkInterface() {
pduRecorder.stop(); pduRecorder.stop();
disNetworkInterface.removeListener(pduListener); disNetworkInterface.removeListener(pduListener);
disNetworkInterface.close(); disNetworkInterface.close();
// disNetworkInterface.kill(); // renamed as close(), deprecated // disNetworkInterface.kill(); // renamed as close(), deprecated
// disNetworkInterface = null; // making sure no possibility of zombie process remaining... // disNetworkInterface = null; // making sure no possibility of zombie process remaining...
} }
/** /**
* Send a single Protocol Data Unit (PDU) of any type * Send a single Protocol Data Unit (PDU) of any type
*
* @param pdu the pdu to send * @param pdu the pdu to send
*/ */
private void sendSinglePdu(Pdu pdu) private void sendSinglePdu(Pdu pdu) {
{ try {
try
{
disNetworkInterface.send(pdu); disNetworkInterface.send(pdu);
Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally
} } catch (InterruptedException ex) {
catch (InterruptedException ex)
{
System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage());
System.exit(1); System.exit(1);
} }
...@@ -407,82 +397,91 @@ public class ExampleSimulationProgram ...@@ -407,82 +397,91 @@ public class ExampleSimulationProgram
/** /**
* Send Comment PDU * Send Comment PDU
* @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments *
* @param commentType enumeration value describing purpose of the narrative comment * @see
* @param comments String array of narrative comments * <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing
* Information to a Method or a Constructor</a> Arbitrary Number of
* Arguments
* @param commentType enumeration value describing purpose of the narrative
* comment
* @param comments String array of narrative comments
*/ */
public void sendCommentPdu(VariableRecordType commentType, public void sendCommentPdu(VariableRecordType commentType,
// vararg... variable-length set of String comments can optionally follow // vararg... variable-length set of String comments can optionally follow
String... comments) String... comments) {
{ sendAllPdusForLoopTimestep(null, null, commentType, comments);
sendAllPdusForLoopTimestep (null, null, commentType, comments);
} }
/** /**
* Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. * Send EntityState, Fire, Comment PDUs that got updated for this loop,
* @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments * reflecting state of current simulation timestep.
*
* @see
* <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing
* Information to a Method or a Constructor</a> Arbitrary Number of
* Arguments
* @param entityStatePdu the ESPDU to send, if any * @param entityStatePdu the ESPDU to send, if any
* @param firePdu the FirePDU to send, if any * @param firePdu the FirePDU to send, if any
* @param commentType enumeration value describing purpose of the narrative comment * @param commentType enumeration value describing purpose of the narrative
* @param comments String array of narrative comments * comment
* @param comments String array of narrative comments
*/ */
public void sendAllPdusForLoopTimestep(EntityStatePdu entityStatePdu, public void sendAllPdusForLoopTimestep(EntityStatePdu entityStatePdu,
FirePdu firePdu, FirePdu firePdu,
VariableRecordType commentType, VariableRecordType commentType,
// vararg... variable-length set of String comments can optionally follow // vararg... variable-length set of String comments can optionally follow
String... comments) String... comments) {
{ if (entityStatePdu != null) {
if (entityStatePdu != null)
sendSinglePdu(entityStatePdu); sendSinglePdu(entityStatePdu);
}
if (firePdu != null)
if (firePdu != null) {
sendSinglePdu(firePdu); // bang sendSinglePdu(firePdu); // bang
}
if ((comments != null) && (comments.length > 0)) if ((comments != null) && (comments.length > 0)) {
{
ArrayList<String> newCommentsList = new ArrayList<>(); ArrayList<String> newCommentsList = new ArrayList<>();
for (String comment : comments) for (String comment : comments) {
{ if (!comment.isEmpty()) {
if (!comment.isEmpty())
{
newCommentsList.add(comment); // OK found something to send newCommentsList.add(comment); // OK found something to send
} }
} }
if (!newCommentsList.isEmpty()) if (!newCommentsList.isEmpty()) {
{ if (commentType == null) {
if (commentType == null)
commentType = otherComment; // fallback value otherComment commentType = otherComment; // fallback value otherComment
// now build the commentPdu from these string inputs, thus constructing a narrative entry } // now build the commentPdu from these string inputs, thus constructing a narrative entry
CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments);
sendSinglePdu(commentPdu); sendSinglePdu(commentPdu);
if (isVerboseComments()) if (isVerboseComments()) {
System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString()); System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString());
}
} }
} }
} }
/** /**
* Main method is first executed when a program instance is loaded. * Main method is first executed when a program instance is loaded.
* @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> *
* @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation * @see
* <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java
* Tutorials: A Closer Look at the "Hello World!" Application</a>
* @param args command-line arguments are an array of optional String
* parameters that are passed from execution environment during invocation
*/ */
public static void main(String[] args) public static void main(String[] args) {
{
System.out.println(TRACE_PREFIX + "started..."); System.out.println(TRACE_PREFIX + "started...");
ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance
// initial execution: can handle args array of initialization arguments here // initial execution: can handle args array of initialization arguments here
if (args.length == 2) if (args.length == 2) {
{ if ((args[0] != null) && !args[0].isEmpty()) {
if ((args[0] != null) && !args[0].isEmpty())
thisProgram.setNetworkAddress(args[0]); thisProgram.setNetworkAddress(args[0]);
}
if ((args[1] != null) && !args[1].isEmpty())
if ((args[1] != null) && !args[1].isEmpty()) {
thisProgram.setNetworkPort(Integer.parseInt(args[1])); thisProgram.setNetworkPort(Integer.parseInt(args[1]));
} }
else if (args.length != 0) } else if (args.length != 0) {
{
System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]");
System.exit(-1); System.exit(-1);
} }
...@@ -490,15 +489,16 @@ public class ExampleSimulationProgram ...@@ -490,15 +489,16 @@ public class ExampleSimulationProgram
thisProgram.setUpNetworkInterface(); thisProgram.setUpNetworkInterface();
thisProgram.runSimulationLoops (); // ... your simulation execution code goes in there ... thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ...
thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering
System.out.println(TRACE_PREFIX + "complete."); // report successful completion System.out.println(TRACE_PREFIX + "complete."); // report successful completion
} }
/** /**
* get whether verbose comments are enabled * get whether verbose comments are enabled
*
* @return whether verboseComments mode is enabled * @return whether verboseComments mode is enabled
*/ */
public boolean isVerboseComments() { public boolean isVerboseComments() {
...@@ -507,6 +507,7 @@ public class ExampleSimulationProgram ...@@ -507,6 +507,7 @@ public class ExampleSimulationProgram
/** /**
* set whether verbose comments are enabled * set whether verbose comments are enabled
*
* @param newVerboseComments whether verboseComments mode is enabled * @param newVerboseComments whether verboseComments mode is enabled
*/ */
public void setVerboseComments(boolean newVerboseComments) { public void setVerboseComments(boolean newVerboseComments) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment