diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-06 08:02:52 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-06 08:02:52 +0300 |
| commit | 1d99762c7965d351510cfb5e08eac25e48d96038 (patch) | |
| tree | f469493e911878ab9055ccf0494211bf9015922d /src/main/java/protocols | |
| parent | 4d35597bd92607c4d194686e20b125044506c79a (diff) | |
Modernize project structure, update Maven config, move sources, add logging config, update README and .gitignore
Diffstat (limited to 'src/main/java/protocols')
12 files changed, 1791 insertions, 0 deletions
diff --git a/src/main/java/protocols/VSAbstractProtocol.java b/src/main/java/protocols/VSAbstractProtocol.java new file mode 100644 index 0000000..70d7595 --- /dev/null +++ b/src/main/java/protocols/VSAbstractProtocol.java @@ -0,0 +1,450 @@ +package protocols; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; + +import core.VSInternalProcess; +import core.VSMessage; +import core.VSMessageStub; +import core.VSTask; +import events.VSAbstractEvent; +import events.internal.VSProtocolScheduleEvent; +import serialize.VSSerialize; +import simulator.VSSimulatorVisualization; + +/** + * The class VSAbstractProtocol, this class defined the basic framework of a + * protocol. + * + * @author Paul C. Buetow + */ +abstract public class VSAbstractProtocol extends VSAbstractEvent { + /** The protocol has an onServerStart method */ + protected static final boolean HAS_ON_SERVER_START = true; + + /** The protocol has an onClientStart method */ + protected static final boolean HAS_ON_CLIENT_START = false; + + /** True, if onServerStart is used, false if onClientStart is used */ + private boolean hasOnServerStart; + + /** The protocol object is a server. */ + private boolean isServer; + + /** The protocol object is a client. */ + private boolean isClient; + + /** The protocol object server is initialized. */ + private boolean isServerInitialized; + + /** The protocol object client is initialized. */ + private boolean isClientInitialized; + + /** The current protocol object's context is a server. */ + private boolean currentContextIsServer; + + /** The protocol's server schedules */ + private ArrayList<VSTask> serverSchedules = new ArrayList<VSTask>(); + + /** The protocol's client schedules */ + private ArrayList<VSTask> clientSchedules = new ArrayList<VSTask>(); + + /** + * A simple constructor. + * + * @param hasOnServerStart true, if the protocol uses an onServerStart + * method. false, if the protocol uses an onClientStart method instead. + */ + public VSAbstractProtocol(boolean hasOnServerStart) { + this.hasOnServerStart = hasOnServerStart; + } + + /** + * Sends a message. + * + * @param message the message to send + */ + public void sendMessage(VSMessage message) { + if (process == null) + return; + + process.increaseLamportTime(); + process.increaseVectorTime(); + + VSMessageStub stub = new VSMessageStub(message); + VSInternalProcess internalProcess = (VSInternalProcess) process; + + if (currentContextIsServer) + stub.init(internalProcess, getClassname(), + VSMessage.IS_SERVER_MESSAGE); + else + stub.init(internalProcess, getClassname(), + VSMessage.IS_CLIENT_MESSAGE); + + internalProcess.sendMessage(message); + } + + /** + * Checks if it's the incorrect protocol + * + * @param message the message to check against + * + * @return true, if is incorrect protocol + */ + private final boolean isIncorrectProtocol(VSMessage message) { + return !message.getProtocolClassname().equals(getClassname()); + } + + /* (non-Javadoc) + * @see events.VSAbstractEvent#onStart() + */ + public final void onStart() { + if (hasOnServerStart) { + if (isServer) { + currentContextIsServer(true); + if (!isServerInitialized) + onInit(); + onServerStart(); + } + } else { + if (isClient) { + currentContextIsServer(false); + if (!isClientInitialized) + onInit(); + onClientStart(); + } + } + } + + /* (non-Javadoc) + * @see events.VSAbstractEvent#onInit() + */ + public final void onInit() { + if (isClient) { + currentContextIsServer(false); + onClientInit(); + isClientInitialized = true; + } + + if (isServer) { + currentContextIsServer(true); + onServerInit(); + isServerInitialized = true; + } + } + + /** + * Runs a client schedule + */ + public final void onClientScheduleStart() { + if (isClient) { + currentContextIsServer(false); + onClientSchedule(); + } + } + + /** + * Runs a server schedule + */ + public final void onServerScheduleStart() { + if (isServer) { + currentContextIsServer(true); + onServerSchedule(); + } + } + + /** + * On message recv. + * + * @param message the message + */ + public final void onMessageRecvStart(VSMessage message) { + if (isIncorrectProtocol(message)) + return; + + if (isServer) { + currentContextIsServer(true); + if (!isServerInitialized) + onInit(); + onServerRecv(message); + } + + if (isClient) { + currentContextIsServer(false); + if (!isClientInitialized) + onInit(); + onClientRecv(message); + } + } + + /** + * Check's if its a relevant message. + * + * @param message the message to check + * + * @return true, if it's a relevant meessage. false if the protocol + * is wrong or if the server recv a server message/the client recv a + * client message. Clients should only recv server messages and servers + * should only recv client messages. + */ + public final boolean isRelevantMessage(VSMessage message) { + if (isIncorrectProtocol(message)) + return false; + + if (message.isServerMessage()) { + if (!isClient) + return false; + } else { + if (!isServer) + return false; + } + + return true; + } + + /** + * Sets if the current context is server. + * + * @param currentContextIsServer the context. + */ + public final void currentContextIsServer(boolean currentContextIsServer) { + this.currentContextIsServer = currentContextIsServer; + } + + /** + * Checks how the protocol will start + * + * @return true, if this protocol uses onServerStart instead of + * onClientStart + */ + public final boolean hasOnServerStart() { + return hasOnServerStart; + } + + /** + * Sets if is server. + * + * @param isServer the is server + */ + public final void isServer(boolean isServer) { + this.isServer = isServer; + } + + /** + * Checks if is server. + * + * @return true, if the protocol has activated the server part + */ + public final boolean isServer() { + return isServer; + } + + /** + * Sets if is client. + * + * @param isClient the is client + */ + public final void isClient(boolean isClient) { + this.isClient = isClient; + } + + /** + * Checks if is client. + * + * @return true, if the protocol has activated the client part + */ + public final boolean isClient() { + return isClient; + } + + /** + * Resets the protocol. + */ + public void reset() { + currentContextIsServer(true); + isServer = false; + onServerReset(); + serverSchedules.clear(); + + currentContextIsServer(false); + isClient = false; + onClientReset(); + clientSchedules.clear(); + } + + /** + * Reschedules the protocol for a new time and runs onClientSchedule or + * onServerSchedule + * + * @param time The process' local time to run the schedule at. + */ + public final void scheduleAt(long time) { + VSInternalProcess internalProcess = (VSInternalProcess) process; + VSAbstractEvent scheduleEvent = + new VSProtocolScheduleEvent(this, currentContextIsServer); + VSTask scheduleTask = + new VSTask(time, internalProcess, scheduleEvent, VSTask.LOCAL); + + if (currentContextIsServer) + serverSchedules.add(scheduleTask); + else + clientSchedules.add(scheduleTask); + + VSSimulatorVisualization canvas = internalProcess.getSimulatorCanvas(); + canvas.getTaskManager().addTask(scheduleTask); + } + + /** + * Removes all schedules of the protocol (server or client) + */ + public final void removeSchedules() { + VSInternalProcess internalProcess = (VSInternalProcess) process; + + if (currentContextIsServer) { + internalProcess.getSimulatorCanvas(). + getTaskManager().removeAllTasks(serverSchedules); + serverSchedules.clear(); + + } else { + internalProcess.getSimulatorCanvas(). + getTaskManager().removeAllTasks(clientSchedules); + clientSchedules.clear(); + } + } + + /** + * On client init. + */ + abstract public void onClientInit(); + + /** + * On client start. + */ + public void onClientStart() { }; + + /** + * On client reset. + */ + abstract public void onClientReset(); + + /** + * On client schedule. + */ + abstract public void onClientSchedule(); + + /** + * On client recv. + * + * @param message the message + */ + abstract public void onClientRecv(VSMessage message); + + /** + * On server init. + */ + abstract public void onServerInit(); + + /** + * On server start. + */ + public void onServerStart() { }; + + /** + * On server reset. + */ + abstract public void onServerReset(); + + /** + * On server recv. + * + * @param message the message + */ + abstract public void onServerRecv(VSMessage message); + + /** + * On server schedule. + */ + abstract public void onServerSchedule(); + + /** + * Gets the num processes. + * + * @return the num processes + */ + public final int getNumProcesses() { + if (process == null) + return 0; + + VSInternalProcess internalProcess = (VSInternalProcess) process; + return internalProcess.getSimulatorCanvas().getNumProcesses(); + } + + /* (non-Javadoc) + * @see events.VSAbstractEvent#createShortname()() + */ + protected String createShortname(String savedShortname) { + return savedShortname; + } + + /* (non-Javadoc) + * @see prefs.VSPrefs#toString() + */ + public String toString() { + if (process == null) + return ""; + + StringBuffer buffer = new StringBuffer(); + + buffer.append(prefs.getString("lang.protocol")); + buffer.append(": "); + buffer.append(getShortname()); + buffer.append(" "); + + if (currentContextIsServer) + buffer.append(prefs.getString("lang.server")); + else + buffer.append(prefs.getString("lang.client")); + + return buffer.toString(); + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#serialize(serialize.VSSerialize, + * java.io.ObjectOutputStream) + */ + public synchronized void serialize(VSSerialize serialize, + ObjectOutputStream objectOutputStream) + throws IOException { + super.serialize(serialize, objectOutputStream); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(Boolean.valueOf(false)); + + objectOutputStream.writeObject(Boolean.valueOf(hasOnServerStart)); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(Boolean.valueOf(false)); + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, + * java.io.ObjectInputStream) + */ + public synchronized void deserialize(VSSerialize serialize, + ObjectInputStream objectInputStream) + throws IOException, ClassNotFoundException { + super.deserialize(serialize, objectInputStream); + + if (VSSerialize.DEBUG) + System.out.println("Deserializing: VSAbstractProtocol"); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + + this.hasOnServerStart = ((Boolean) objectInputStream.readObject()).booleanValue(); + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + } +} diff --git a/src/main/java/protocols/implementations/README b/src/main/java/protocols/implementations/README new file mode 100644 index 0000000..fd8effa --- /dev/null +++ b/src/main/java/protocols/implementations/README @@ -0,0 +1,10 @@ +How to add a new protocol: + +1. Copy the file VSDummyProtocol.java into VSYourOwnNiceProtocol.java + +2. Edit VSYourOwnNiceProtocol.java and replace the classname! + +3. Edit the initialize method of events.RegisteredEvents.java and add the classname +of your protocol. E.g.: "protocols.implementations.VSYourOwnNiceProtocol" + + diff --git a/src/main/java/protocols/implementations/VSBasicMulticastProtocol.java b/src/main/java/protocols/implementations/VSBasicMulticastProtocol.java new file mode 100644 index 0000000..cfd5399 --- /dev/null +++ b/src/main/java/protocols/implementations/VSBasicMulticastProtocol.java @@ -0,0 +1,86 @@ +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSBasicMulticastProtocol, an implementation of the basic multicast + * protocol. + * + * @author Paul C. Buetow + */ +public class VSBasicMulticastProtocol extends VSAbstractProtocol { + /** + * Instantiates a new VSBasicMulticast object. + */ + public VSBasicMulticastProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + VSMessage message = new VSMessage(); + message.setBoolean("isMulticast", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (recvMessage.getBoolean("isMulticast")) + log("Multicast received"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSBerkelyTimeProtocol.java b/src/main/java/protocols/implementations/VSBerkelyTimeProtocol.java new file mode 100644 index 0000000..05d0eae --- /dev/null +++ b/src/main/java/protocols/implementations/VSBerkelyTimeProtocol.java @@ -0,0 +1,204 @@ +package protocols.implementations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Vector; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSBerkelyTimeProtocol, an implementation of the berkely time + * protocol. + * + * @author Paul C. Buetow + */ +public class VSBerkelyTimeProtocol extends VSAbstractProtocol { + /** + * Instantiates a new berkely time protocol. + */ + public VSBerkelyTimeProtocol() { + super(VSAbstractProtocol.HAS_ON_SERVER_START); + setClassname(getClass().toString()); + } + + /** Integer: Process ID, Long: Local time of the process */ + private HashMap<Integer,Long> processTimes = new HashMap<Integer,Long>(); + + /** Integer: Process ID, Long: Time of receiving the response from the + * process + */ + private HashMap<Integer,Long> recvTimes = new HashMap<Integer,Long>(); + + /** Integer: Process ID, Long: Calculated process times (using the RTT) */ + private HashMap<Integer,Long> realTimesRTT = new HashMap<Integer,Long>(); + + /** Contains all process IDs of processes which want to justify their + * time + */ + private ArrayList<Integer> peers = new ArrayList<Integer>(); + + /** Time the request/response has started */ + private long requestTime; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + Vector<Integer> vec = new Vector<Integer>(); + vec.add(1); + vec.add(3); + initVector("pids", vec, "PIDs of participating processes"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + //System.out.println("FOOBAR"); + processTimes.clear(); + recvTimes.clear(); + realTimesRTT.clear(); + peers.clear(); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerStart() + */ + public void onServerStart() { + //System.out.println("FOO"); + peers.addAll(getVector("pids")); + requestTime = process.getTime(); + VSMessage message = new VSMessage(); + message.setBoolean("isRequest", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + /* Ignore all protocol messages which are not a response message, + e.g. itself */ + if (!recvMessage.getBoolean("isResponse")) + return; + + Integer processID = recvMessage.getIntegerObj("processID"); + + if (peers.contains(processID)) + peers.remove(processID); + else + return; /* Process has been handled already or is not listed */ + + Long time = Long.valueOf(recvMessage.getLong("time")); + + processTimes.put(processID, time); + recvTimes.put(processID, Long.valueOf(process.getTime())); + + /* All peers have told their times */ + if (peers.size() == 0) { + long avgTime = calculateAverageTime(); + /* Set the local's process time to the new avg reference time */ + process.setTime(avgTime); + /* Tell all other processes what to do in order to justify their + times */ + sendJustifyRequests(avgTime); + /* Start "clean" next time */ + onServerReset(); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /** + * Calculate the new average time. + * + * @return the long + */ + private long calculateAverageTime() { + long sum = 0; + for (Integer processID : processTimes.keySet()) { + Long localTime = processTimes.get(processID); + Long recvTime = recvTimes.get(processID); + long rtt = recvTime.longValue() - requestTime; + long realProcessTime = localTime + (long) (rtt / 2); + realTimesRTT.put(processID, Long.valueOf(realProcessTime)); + sum += realProcessTime; + } + /* Include the time of the local process */ + sum += process.getTime(); + return (long) sum / (getVector("pids").size() + 1); + } + + /** + * Sends to all clients a value to justify their local clocks. + * + * @param avgTime the avg time + */ + private void sendJustifyRequests(long avgTime) { + for (Integer processID : processTimes.keySet()) { + long realProcessTime = realTimesRTT.get(processID).longValue(); + long diff = avgTime - realProcessTime; + VSMessage message = new VSMessage(); + message.setBoolean("isJustify", true); + message.setLong("timeDiff", diff); + message.setInteger("receiverProcessID", processID); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (recvMessage.getBoolean("isRequest")) { + VSMessage message = new VSMessage(); + message.setInteger("processID", process.getProcessID()); + message.setLong("time", process.getTime()); + message.setBoolean("isResponse", true); + sendMessage(message); + + } else if (recvMessage.getBoolean("isJustify")) { + /* Check if it's "my" justify message */ + if (recvMessage.getInteger("receiverProcessID") != + process.getProcessID()) + return; + + long timeDiff = recvMessage.getLong("timeDiff"); + //long recvTime = process.getTime(); + long newTime = process.getTime() + timeDiff; + log("New time: " + newTime); + + process.setTime(newTime); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSBroadcastProtocol.java b/src/main/java/protocols/implementations/VSBroadcastProtocol.java new file mode 100644 index 0000000..54fd3b5 --- /dev/null +++ b/src/main/java/protocols/implementations/VSBroadcastProtocol.java @@ -0,0 +1,103 @@ +package protocols.implementations; + +import java.util.ArrayList; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSBroadcastProtocol, an implementation of the broadcast + * sturm protocol. + * + * @author Paul C. Buetow + */ +public class VSBroadcastProtocol extends VSAbstractProtocol { + /** The sent messages. */ + private ArrayList<Integer> sentMessages; + + /** The broadcast count. */ + private static int broadcastCount; + + /** + * Instantiates a new broadcast sturm protocol. + */ + public VSBroadcastProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + sentMessages = new ArrayList<Integer>(); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + VSMessage message = new VSMessage(); + message.setInteger("Broadcast", broadcastCount++); + sentMessages.add(message.getIntegerObj("Broadcast")); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + onServerRecv(recvMessage); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + sentMessages.clear(); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (!sentMessages.contains(recvMessage.getIntegerObj("Broadcast"))) { + VSMessage message = new VSMessage(); + message.setInteger("Broadcast", + recvMessage.getInteger("Broadcast")); + sentMessages.add(message.getIntegerObj("Broadcast")); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSDummyProtocol.java b/src/main/java/protocols/implementations/VSDummyProtocol.java new file mode 100644 index 0000000..e9e6837 --- /dev/null +++ b/src/main/java/protocols/implementations/VSDummyProtocol.java @@ -0,0 +1,100 @@ +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSDummyProtocol, can be used as a template in order to create + * own protocols. + * + * @author Paul C. Buetow + */ +public class VSDummyProtocol extends VSAbstractProtocol { + /** + * Instantiates a new dummy protocol object. + */ + public VSDummyProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + log("onClientReset()"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + log("onClientStart()"); + + VSMessage message = new VSMessage(); + message.setString("Greeting", "Hello World!"); + message.setInteger("A number", 1); + message.setBoolean("A boolean", true); + message.setFloat("A float", 1.2f); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + log("onClientRecv("+recvMessage+")"); + + /* + String s = recvMessage.getString("Greeting"); + int n = recvMessage.getInteger("A number"); + boolean b = recvMessage.getBoolean("A boolean"); + float f = recvMessage.getFloat("A float"); + */ + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + log("onClientReset()"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + log("onServerRecv("+recvMessage+")"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString() + "; Dummy Test"; + } +} diff --git a/src/main/java/protocols/implementations/VSExternalTimeSyncProtocol.java b/src/main/java/protocols/implementations/VSExternalTimeSyncProtocol.java new file mode 100644 index 0000000..f044861 --- /dev/null +++ b/src/main/java/protocols/implementations/VSExternalTimeSyncProtocol.java @@ -0,0 +1,118 @@ +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSExternalTimeSyncProtocol, an implementation of the external + * time synchronisation protocol. + * + * @author Paul C. Buetow + */ +public class VSExternalTimeSyncProtocol extends VSAbstractProtocol { + /** The request time. */ + private long requestTime; + + /** The server is waiting for response, if true. */ + private boolean waitingForResponse; + + /** + * Instantiates a new external time sync protocol object. + */ + public VSExternalTimeSyncProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + requestTime = process.getTime(); + waitingForResponse = true; + + /* Multicast message to all processes */ + VSMessage message = new VSMessage(); + message.setBoolean("isClientRequest", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (!recvMessage.getBoolean("isServerResponse")) + return; + + if (waitingForResponse) + waitingForResponse = false; + else + return; + + long recvTime = process.getTime(); + long roundTripTime = recvTime - requestTime; + long serverTime = recvMessage.getLong("time"); + long newTime = serverTime + (long) (roundTripTime / 2); + + log("Server time: " + serverTime + "; RTT: " + roundTripTime + "; Old time: " + recvTime + "; New time: " + newTime + "; Offset: " + (newTime - recvTime)); + + process.setTime(newTime); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (!recvMessage.getBoolean("isClientRequest")) + return; + + /* Multicast message to all processes */ + VSMessage message = new VSMessage(); + message.setLong("time", process.getTime()); + message.setBoolean("isServerResponse", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSInternalTimeSyncProtocol.java b/src/main/java/protocols/implementations/VSInternalTimeSyncProtocol.java new file mode 100644 index 0000000..e3bd181 --- /dev/null +++ b/src/main/java/protocols/implementations/VSInternalTimeSyncProtocol.java @@ -0,0 +1,123 @@ +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSInternalTimeSyncProtocol, an implementation of the internal + * time synchronisation protocol. + * + * @author Paul C. Buetow + */ +public class VSInternalTimeSyncProtocol extends VSAbstractProtocol { + /** The waiting for response. */ + private boolean waitingForResponse; + + /** + * Instantiates a new internal time sync protocol. + */ + public VSInternalTimeSyncProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + initLong("t_min", 2000, "Max. transmission time", "ms"); + initLong("t_max", 500, "Min. transmission time", "ms"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + waitingForResponse = true; + + /* Multicast message to all processes */ + VSMessage message = new VSMessage(); + message.setBoolean("isClientRequest", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + /* Ignore all protocol messages which are not a response message, + e.g. itself */ + if (!recvMessage.getBoolean("isServerResponse")) + return; + + if (waitingForResponse) + waitingForResponse = false; + else + return; + + long tMax = getLong("t_max"); + long tMin = getLong("t_min"); + long serverTime = recvMessage.getLong("time"); + long newTime = serverTime + (long) ((tMax + tMin) / 2 ); + + log("Server time: " + serverTime + "; (t_min,t_max): (" + tMin + + "," + tMax + "); Old time: " + process.getTime() + + "; New time: " + newTime + "; Offset: " + + (process.getTime() - newTime)); + + process.setTime(newTime); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + /* Ignore all protocol messages which are not a request message, + e.g. itself */ + if (!recvMessage.getBoolean("isClientRequest")) + return; + + /* Multicast message to all processes */ + VSMessage message = new VSMessage(); + message.setLong("time", process.getTime()); + message.setBoolean("isServerResponse", true); + sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSOnePhaseCommitProtocol.java b/src/main/java/protocols/implementations/VSOnePhaseCommitProtocol.java new file mode 100644 index 0000000..4dcfe7e --- /dev/null +++ b/src/main/java/protocols/implementations/VSOnePhaseCommitProtocol.java @@ -0,0 +1,148 @@ +package protocols.implementations; + +import java.util.ArrayList; +import java.util.Vector; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSOnePhaseCommitProtocol, an implementation of the one phase + * commit protocol. + * + * @author Paul C. Buetow + */ +public class VSOnePhaseCommitProtocol extends VSAbstractProtocol { + /* Server variables */ + private boolean ackSent; + + /** + * Instantiates a one phase commit protocol. + */ + public VSOnePhaseCommitProtocol() { + super(VSAbstractProtocol.HAS_ON_SERVER_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + /* Can be changed via GUI variables editor of each process */ + Vector<Integer> vec = new Vector<Integer>(); + vec.add(1); + vec.add(3); + + // TODO: Translate + initVector("pids", vec, "PIDs beteiligter Prozesse"); + initLong("timeout", 2500, "Zeit bis erneute Anfrage", "ms"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + if (pids != null) { + pids.clear(); + pids.addAll(getVector("pids")); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerStart() + */ + public void onServerStart() { + if (pids == null) { + pids = new ArrayList<Integer>(); + pids.addAll(getVector("pids")); + } + + if (pids.size() != 0) { + long timeout = getLong("timeout") + process.getTime(); + /* Will run onServerSchedule() at the specified local time */ + scheduleAt(timeout); + + VSMessage message = new VSMessage(); + message.setBoolean("wantAck", true); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (pids.size() == 0) + return; + + if (recvMessage.getBoolean("isAck")) { + Integer pid = recvMessage.getIntegerObj("pid"); + if (pids.contains(pid)) + pids.remove(pid); + else + return; + + log("ACK from process " + pid + " received!"); + + if (pids.size() == 0) { + log("ACKs received from all participating processes! " + + "Committed!"); + + /* Remove the active schedule which has been created in the + onServerStart method */ + removeSchedules(); + } + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + onServerStart(); + } + + /* Client variables, coordinator */ + private ArrayList<Integer> pids; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + ackSent = false; + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (ackSent) + return; + + VSMessage message = new VSMessage(); + message.setBoolean("isAck", true); + message.setInteger("pid", process.getProcessID()); + sendMessage(message); + ackSent = true; + log("Committed"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString(); + } +} diff --git a/src/main/java/protocols/implementations/VSPingPongProtocol.java b/src/main/java/protocols/implementations/VSPingPongProtocol.java new file mode 100644 index 0000000..b1f3d20 --- /dev/null +++ b/src/main/java/protocols/implementations/VSPingPongProtocol.java @@ -0,0 +1,110 @@ +package protocols.implementations; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSPingPongProtocol, an implementation of the ping pong protocol. + * + * @author Paul C. Buetow + */ +public class VSPingPongProtocol extends VSAbstractProtocol { + /** The client counter. */ + private int clientCounter; + + /** The server counter. */ + private int serverCounter; + + /** + * Instantiates a new ping pong protocol. + */ + public VSPingPongProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + clientCounter = 0; + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + VSMessage message = new VSMessage(); + message.setBoolean("fromClient", true); + message.setInteger("counter", ++clientCounter); + super.sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (!recvMessage.getBoolean("fromServer")) + return; + + super.log("message: " + recvMessage.getInteger("counter")); + + VSMessage message = new VSMessage(); + message.setBoolean("fromClient", true); + message.setInteger("counter", ++clientCounter); + super.sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + serverCounter = 0; + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (!recvMessage.getBoolean("fromClient")) + return; + + super.log("message: " + recvMessage.getInteger("counter")); + + VSMessage message = new VSMessage(); + message.setBoolean("fromServer", true); + message.setInteger("counter", ++serverCounter); + super.sendMessage(message); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#toString() + */ + public String toString() { + return super.toString() + "; New message afterwards"; + } +} diff --git a/src/main/java/protocols/implementations/VSReliableMulticastProtocol.java b/src/main/java/protocols/implementations/VSReliableMulticastProtocol.java new file mode 100644 index 0000000..170533a --- /dev/null +++ b/src/main/java/protocols/implementations/VSReliableMulticastProtocol.java @@ -0,0 +1,143 @@ +package protocols.implementations; + +import java.util.ArrayList; +import java.util.Vector; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSReliableMulticastProtocol, an implementation of the reliable + * multicast protocol. + * + * @author Paul C. Buetow + */ +public class VSReliableMulticastProtocol extends VSAbstractProtocol { + /** + * Instantiates a two phase commit protocol object. + */ + public VSReliableMulticastProtocol() { + super(VSAbstractProtocol.HAS_ON_CLIENT_START); + setClassname(getClass().toString()); + } + + /** PIDs of all processes which still have to send an ACK */ + private ArrayList<Integer> pids; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + Vector<Integer> vec = new Vector<Integer>(); + vec.add(1); + vec.add(3); + + super.initVector("pids", vec, "PIDs beteiligter Prozesse"); + super.initLong("timeout", 2500, "Zeit bis erneute Anfrage", "ms"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + if (pids != null) { + pids.clear(); + pids.addAll(getVector("pids")); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientStart() + */ + public void onClientStart() { + if (pids == null) { + pids = new ArrayList<Integer>(); + pids.addAll(getVector("pids")); + } + + if (pids.size() != 0) { + long timeout = getLong("timeout") + process.getTime(); + /* Will run onClientSchedule() at the specified local time */ + scheduleAt(timeout); + + VSMessage message = new VSMessage(); + message.setBoolean("isMulticast", true); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (pids.size() != 0 && recvMessage.getBoolean("isAck")) { + Integer pid = recvMessage.getIntegerObj("pid"); + + if (pids.contains(pid)) + pids.remove(pid); + else + return; + + log("ACK from process " + pid + " received!"); + + + if (pids.size() == 0) { + log("ACKs from all involved processes received!"); + + /* Remove the active schedule which has been created in the + onClientStart method */ + removeSchedules(); + } + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + onClientStart(); + } + + /** True if ACK has been sent already */ + private boolean ackSent; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + ackSent = false; + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (recvMessage.getBoolean("isMulticast")) { + VSMessage message = new VSMessage(); + message.setBoolean("isAck", true); + message.setInteger("pid", process.getProcessID()); + sendMessage(message); + + if (ackSent) { + log("ACK sent again"); + + } else { + log("ACK sent"); + + ackSent = true; + } + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + } +} diff --git a/src/main/java/protocols/implementations/VSTwoPhaseCommitProtocol.java b/src/main/java/protocols/implementations/VSTwoPhaseCommitProtocol.java new file mode 100644 index 0000000..8f9e4a3 --- /dev/null +++ b/src/main/java/protocols/implementations/VSTwoPhaseCommitProtocol.java @@ -0,0 +1,196 @@ +package protocols.implementations; + +import java.util.ArrayList; +import java.util.Vector; + +import core.VSMessage; +import protocols.VSAbstractProtocol; + +/** + * The class VSTwoPhaseCommitProtocol, an implementation of the two phase + * commit protocol. + * + * @author Paul C. Buetow + */ +public class VSTwoPhaseCommitProtocol extends VSAbstractProtocol { + /** + * Instantiates a two phase commit protocol object. + */ + public VSTwoPhaseCommitProtocol() { + super(VSAbstractProtocol.HAS_ON_SERVER_START); + setClassname(getClass().toString()); + } + + /** PIDs of all processes which still have to vote */ + private ArrayList<Integer> votePids; + + /** PIDs of all processes which have to acknowledge that they recv the + * global vote result + */ + private ArrayList<Integer> ackPids; + + /** The gloal vote result */ + private boolean voteResult; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onServerInit() + */ + public void onServerInit() { + Vector<Integer> vec = new Vector<Integer>(); + vec.add(2); + vec.add(3); + + initVector("pids", vec, "PIDs beteiligter Prozesse"); + initLong("timeout", 2500, "Zeit bis erneute Anfrage", "ms"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerReset() + */ + public void onServerReset() { + if (votePids != null) { + voteResult = true; + votePids.clear(); + votePids.addAll(getVector("pids")); + ackPids.clear(); + ackPids.addAll(getVector("pids")); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerStart() + */ + public void onServerStart() { + if (votePids == null) { + voteResult = true; + votePids = new ArrayList<Integer>(); + votePids.addAll(getVector("pids")); + ackPids = new ArrayList<Integer>(); + ackPids.addAll(getVector("pids")); + } + + if (votePids.size() != 0) { + long timeout = getLong("timeout") + process.getTime(); + /* Will run onServerSchedule() at the specified local time */ + scheduleAt(timeout); + + VSMessage message = new VSMessage(); + message.setBoolean("wantVote", true); + sendMessage(message); + + } else if (ackPids.size() != 0) { + long timeout = getLong("timeout") + process.getTime(); + /* Will run onServerSchedule() at the specified local time */ + scheduleAt(timeout); + + VSMessage message = new VSMessage(); + message.setBoolean("isVoteResult", true); + message.setBoolean("voteResult", voteResult); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerRecv(core.VSMessage) + */ + public void onServerRecv(VSMessage recvMessage) { + if (votePids.size() != 0 && recvMessage.getBoolean("isVote")) { + Integer pid = recvMessage.getIntegerObj("pid"); + if (votePids.contains(pid)) + votePids.remove(pid); + else + return; + + boolean vote = recvMessage.getBoolean("vote"); + log("Vote from process " + pid + " received! Result: " + vote); + + if (!vote) + voteResult = false; + + if (votePids.size() == 0) { + log("Votes from all involved processes received! Global result: " + voteResult); + + /* Remove the active schedule which has been created in the + onServerStart method */ + removeSchedules(); + /* Create a new schedule and send the vote result */ + onServerStart(); + } + + } else if (ackPids.size() != 0 && recvMessage.getBoolean("isAck")) { + Integer pid = recvMessage.getIntegerObj("pid"); + if (ackPids.contains(pid)) + ackPids.remove(pid); + else + return; + + if (ackPids.size() == 0) { + /* Remove the active schedule which has been created in the + onServerStart method */ + removeSchedules(); + log("All participants have received the vote"); + } + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onServerSchedule() + */ + public void onServerSchedule() { + onServerStart(); + } + + /* Server variables */ + private boolean voteSent; + private boolean myVote; + + /* (non-Javadoc) + * @see events.VSAbstractProtocol#onClientInit() + */ + public void onClientInit() { + initInteger("ackProb", 50, "Festschreibw'keit", 0, 100, "%"); + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientReset() + */ + public void onClientReset() { + voteSent = false; + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientRecv(core.VSMessage) + */ + public void onClientRecv(VSMessage recvMessage) { + if (recvMessage.getBoolean("wantVote")) { + if (!voteSent) { + voteSent = true; + myVote = process.getRandomPercentage() <= getInteger("ackProb"); + } + + VSMessage message = new VSMessage(); + message.setBoolean("isVote", true); + message.setBoolean("vote", myVote); + message.setInteger("pid", process.getProcessID()); + sendMessage(message); + + log("Vote " + myVote + " sent"); + + + } else if (recvMessage.getBoolean("isVoteResult")) { + boolean voteResult = recvMessage.getBoolean("voteResult"); + log("Global voting result received. Result: " + voteResult); + + VSMessage message = new VSMessage(); + message.setBoolean("isAck", true); + message.setInteger("pid", process.getProcessID()); + sendMessage(message); + } + } + + /* (non-Javadoc) + * @see protocols.VSAbstractProtocol#onClientSchedule() + */ + public void onClientSchedule() { + } +} |
