diff options
66 files changed, 14634 insertions, 28 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01071bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +# Compiled class files +*.class + +# Log files +*.log +logs/ + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs +hs_err_pid* +replay_pid* + +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +# IntelliJ IDEA +.idea/ +*.iws +*.iml +*.ipr + +# Eclipse +.classpath +.project +.settings/ + +# VS Code +.vscode/ + +# Mac +.DS_Store + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini
\ No newline at end of file @@ -1,8 +1,73 @@ -ds-sim -====== +# DS-Sim -DS-Sim is an open source simulator programmed in Java for distributed systems. DS-Sim stands for "Verteilte Systeme Simulator," which is the German translation for "Distributed Systems Simulator." +DS-Sim is a modern, open-source simulator for distributed systems, written in Java. It provides a powerful environment for simulating and learning about distributed systems concepts. - +## Features -DS-Sim is a fork of VS-Sim: https://codeberg.org/snonux/vs-sim/ +- Protocol simulation +- Event handling +- Lamport and Vector time implementations +- Modern Java-based architecture +- Interactive GUI using JavaFX +- Comprehensive logging and monitoring +- JSON-based configuration + +## Requirements + +- Java 17 or higher +- Maven 3.8 or higher + +## Building + +```bash +# Clone the repository +git clone https://github.com/yourusername/ds-sim.git +cd ds-sim + +# Build the project +mvn clean package + +# Run the simulator +java -jar target/ds-sim-1.0-SNAPSHOT.jar +``` + +## Development + +```bash +# Run tests +mvn test + +# Generate documentation +mvn javadoc:javadoc +``` + +## Project Structure + +``` +ds-sim/ +├── src/ +│ ├── main/ +│ │ ├── java/ # Source code +│ │ └── resources/ # Configuration files +│ └── test/ +│ ├── java/ # Test code +│ └── resources/ # Test resources +├── docs/ # Documentation +└── pom.xml # Project configuration +``` + +## Contributing + +1. Fork the repository +2. Create your feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## License + +This project is licensed under the terms of the license included in the repository. + +## Acknowledgments + +- Original VS-Sim project: https://codeberg.org/snonux/vs-sim/ @@ -1,17 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>com.example</groupId> - <artifactId>verteilte-systeme</artifactId> + + <groupId>org.ds-sim</groupId> + <artifactId>ds-sim</artifactId> <version>1.0-SNAPSHOT</version> - <name>Verteilte Systeme</name> - <description>This is the distributed systems simulation/learning environment!</description> + <name>DS-Sim</name> + <description>Distributed Systems Simulator - A modern Java-based simulator for distributed systems</description> <properties> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> + <java.version>11</java.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <junit.version>5.9.2</junit.version> + <mockito.version>5.3.1</mockito.version> + <slf4j.version>2.0.7</slf4j.version> + <logback.version>1.4.7</logback.version> </properties> <build> @@ -21,14 +29,13 @@ </resource> </resources> <plugins> - <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.1</version> + <version>3.11.0</version> <configuration> - <source>${maven.compiler.source}</source> - <target>${maven.compiler.target}</target> + <source>${java.version}</source> + <target>${java.version}</target> <compilerArgs> <arg>-Xlint:deprecation,unchecked</arg> </compilerArgs> @@ -38,12 +45,11 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.2.0</version> + <version>3.3.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> - <classpathPrefix>lib/</classpathPrefix> <mainClass>simulator.VSMain</mainClass> </manifest> </archive> @@ -53,32 +59,92 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> - <version>3.2.0</version> + <version>3.5.0</version> <configuration> - <destDir>${project.basedir}/javadoc</destDir> + <doclint>none</doclint> + <source>${java.version}</source> </configuration> </plugin> <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>3.0.0</version> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.1.2</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.4.1</version> <executions> <execution> + <phase>package</phase> <goals> - <goal>java</goal> + <goal>shade</goal> </goals> + <configuration> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>simulator.VSMain</mainClass> + </transformer> + </transformers> + </configuration> </execution> </executions> - <configuration> - <mainClass>simulator.VSMain</mainClass> - </configuration> </plugin> - </plugins> </build> <dependencies> - <!-- Add your project dependencies here --> + <!-- Testing --> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>${mockito.version}</version> + <scope>test</scope> + </dependency> + + <!-- Logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>${logback.version}</version> + </dependency> + + <!-- JSON Processing --> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.15.2</version> + </dependency> + + <!-- GUI --> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-controls</artifactId> + <version>17.0.2</version> + </dependency> + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-fxml</artifactId> + <version>17.0.2</version> + </dependency> </dependencies> </project> diff --git a/src/main/java/core/VSAbstractProcess.java b/src/main/java/core/VSAbstractProcess.java new file mode 100644 index 0000000..78e7844 --- /dev/null +++ b/src/main/java/core/VSAbstractProcess.java @@ -0,0 +1,738 @@ +package core; + +import java.awt.Color; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; + +import core.time.VSLamportTime; +import core.time.VSTime; +import core.time.VSVectorTime; +import prefs.VSPrefs; +import prefs.VSSerializablePrefs; +import protocols.VSAbstractProtocol; +import serialize.VSSerialize; +import simulator.VSLogging; +import simulator.VSSimulatorVisualization; +import utils.VSPriorityQueue; +import utils.VSRandom; +import utils.VSTools; + +/** + * The class VSAbstractProcess, an object of this class represents a process + * of a simulator. + * + * @author Paul C. Buetow + */ +public abstract class VSAbstractProcess extends VSSerializablePrefs { + /** The data serialization id. */ + protected static final long serialVersionUID = 1L; + + /** The protocols to reset if the simulator is over or the reset + * button has been pressed. + */ + protected ArrayList<VSAbstractProtocol> protocolsToReset; + + /** The crash history. represents all crashes of the process using the + * global simulator time. + */ + protected ArrayList<Long> crashHistory; + + /** The lamport time history. */ + protected ArrayList<VSLamportTime> lamportTimeHistory; + + /** The vector time history. */ + protected ArrayList<VSVectorTime> vectorTimeHistory; + + /** The color used if the process has crashed. */ + protected Color crashedColor;; + + /** The process' current color. */ + protected Color currentColor; + + /** A temp. color. For internal usage. */ + protected Color tmpColor; + + /** The loging object. */ + protected VSLogging loging; + + /** The simulator's default prefs. */ + protected VSPrefs prefs; + + /** The random generator of the process. */ + protected VSRandom random; + + /** The simulator canvas. */ + protected VSSimulatorVisualization simulatorVisualization; + + /** The random crash task. May be null if there is no such random task. */ + protected VSTask randomCrashTask; + + /** The vector time. */ + protected VSVectorTime vectorTime; + + /** The tasks of the process. DO ONLY MANIPULATE THIS OBJECT WITHIN THE + * VSTaskManager CLASS! OTHERWISE THE SYNCHRONIZATION IS WRONG! Use the + * VSAbstractProcess.getTasks() method to get a reference to this object + * within the VSTaskManager! */ + protected VSPriorityQueue<VSTask> tasks; + + /** The process has crashed. But may be working again. */ + protected boolean hasCrashed; + + /** The process has started. But may be paused or crashed.. */ + protected boolean hasStarted; + + /** The process is crashed. */ + protected boolean isCrashed; + + /** The process is highlighted. */ + protected boolean isHighlighted; + + /** The process is paused. */ + protected boolean isPaused; + + /** The time has been modified in a task. Needed by the task manager to + * calculate correct offsets. + */ + protected boolean timeModified; + + /** The clock offset. Used by the task manager and also by the process' + * clock variance. + */ + protected double clockOffset; + + /** The clock variance. */ + protected float clockVariance; + + /** The process id. */ + protected int processID; + + /** The process num. It is different to the process id. It represents the + * array index of there the process is stored at. + */ + protected int processNum; + + /** The global time. */ + protected long globalTime; + + /** The lamport time. */ + protected long lamportTime; + + /** The local time. */ + protected long localTime; + + /** The Constant DEFAULT_INTEGER_VALUE_KEYS. + * This array contains all Integer prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_INTEGER_VALUE_KEYS[] = { + "process.prob.crash", + "message.prob.outage", + }; + + /** The Constant DEFAULT_LONG_VALUE_KEYS. + * This array contains all Long prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_LONG_VALUE_KEYS[] = { + "message.sendingtime.min", + "message.sendingtime.max", + }; + + /** The Constant DEFAULT_FLOAT_VALUE_KEYS. + * This array contains all Float prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_FLOAT_VALUE_KEYS[] = { + "process.clock.variance", + }; + + /** The Constant DEFAULT_COLOR_VALUE_KEYS. + * This array contains all Color prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_COLOR_VALUE_KEYS[] = { + "col.process.default", + "col.process.running", + "col.process.stopped", + "col.process.highlight", + "col.process.crashed", + }; + + /** The Constant DEFAULT_STRING_VALUE_KEYS. + * This array contains all String prefs of the process which should show + * up in the prefs menu! All keys which dont start with "sim." only show + * up in the extended prefs menu! + */ + protected static final String DEFAULT_STRING_VALUE_KEYS[] = { + }; + + /** + * Instantiates a new process. + * + * @param prefs the simulator's default prefs + * @param processNum the process num + * @param simulatorVisualization the simulator canvas + * @param loging the loging object + */ + public VSAbstractProcess(VSPrefs prefs, int processNum, + VSSimulatorVisualization simulatorVisualization, + VSLogging loging) { + init(prefs, processNum, simulatorVisualization, loging); + } + + /** + * Inits a the process. + * + * @param prefs the simulator's default prefs + * @param processNum the process num + * @param simulatorVisualization the simulator canvas + * @param loging the loging object + */ + protected void init(VSPrefs prefs, int processNum, + VSSimulatorVisualization simulatorVisualization, + VSLogging loging) { + /* May be not null if called from deserialization */ + if (this.protocolsToReset == null) + this.protocolsToReset = new ArrayList<VSAbstractProtocol>(); + + this.processNum = processNum; + this.prefs = prefs; + this.simulatorVisualization = simulatorVisualization; + this.loging = loging; + + processID = simulatorVisualization.processIDCount(); + random = new VSRandom(processID*processNum+processID+processNum); + tasks = new VSPriorityQueue<VSTask>(); + + initTimeFormats(); + + isPaused = true; |
