diff --git a/src/main/kotlin/drills/drill03/exercise2/Agent.kt b/src/main/kotlin/drills/drill03/exercise2/Agent.kt new file mode 100644 index 0000000..4be7fe5 --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/Agent.kt @@ -0,0 +1,18 @@ +package drills.drill03.exercise2 + +import java.io.Serializable + +interface Agent : Serializable, Runnable { + fun start() + fun migrateTo(node: Node) +} + +abstract class AbstractAgent : Agent { + override fun start() { + Thread(this).start() + } + + override fun migrateTo(node: Node) { + node.migrate(this) + } +} diff --git a/src/main/kotlin/drills/drill03/exercise2/AgentContainer.kt b/src/main/kotlin/drills/drill03/exercise2/AgentContainer.kt new file mode 100644 index 0000000..fffcdae --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/AgentContainer.kt @@ -0,0 +1,16 @@ +package drills.drill03.exercise2 + +import java.rmi.Remote +import java.rmi.RemoteException +import java.rmi.server.UnicastRemoteObject + +interface AgentContainer : Remote { + @Throws(RemoteException::class) + fun migrate(agent: Agent) +} + +class AgentContainerImpl : AgentContainer, UnicastRemoteObject() { + override fun migrate(agent: Agent) { + agent.start() + } +} diff --git a/src/main/kotlin/drills/drill03/exercise2/ContainerServer.kt b/src/main/kotlin/drills/drill03/exercise2/ContainerServer.kt new file mode 100644 index 0000000..0f01c11 --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/ContainerServer.kt @@ -0,0 +1,26 @@ +package drills.drill03.exercise2 + +import java.net.MalformedURLException +import java.rmi.AccessException +import java.rmi.AlreadyBoundException +import java.rmi.Naming +import java.rmi.RemoteException +import java.rmi.registry.LocateRegistry + +fun main(args: Array) { + try { + if (args[0] == "0") + LocateRegistry.createRegistry(4242) + + val container: AgentContainer = AgentContainerImpl() + Naming.rebind("rmi://localhost:4242/container-${args[0]}", container) + } catch (e: AccessException) { + System.err.println("Bind operation not permitted $e") + } catch (e: RemoteException) { + System.err.println("Registry could not be contacted $e") + } catch (e: MalformedURLException) { + System.err.println("Wrong URL for binding $e") + } catch (e: AlreadyBoundException) { + System.err.println("Object alreay bound to the registry $e") + } +} diff --git a/src/main/kotlin/drills/drill03/exercise2/Node.kt b/src/main/kotlin/drills/drill03/exercise2/Node.kt new file mode 100644 index 0000000..a4bdd4b --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/Node.kt @@ -0,0 +1,36 @@ +package drills.drill03.exercise2 + +import java.io.Serializable +import java.net.MalformedURLException +import java.rmi.Naming +import java.rmi.NotBoundException +import java.rmi.RemoteException + +interface Node : Serializable { + fun migrate(agent: Agent) +} + +class NodeImpl(index: Int) : Node { + private val container = getContainer(index) + + override fun migrate(agent: Agent) { + container?.migrate(agent) + } + + private fun getContainer(index: Int): AgentContainer? { + try { + return Naming + .lookup("rmi://localhost:4242/container-$index") as AgentContainer + } catch (e: NotBoundException) { + System.err.println("Request obect not bound $e") + } catch (e: MalformedURLException) { + System.err.println("Wrong URL $e") + } catch (e: RemoteException) { + System.err.println("Network or Server Error $e") + } catch (e: Exception) { + System.err.println("Generic Error $e") + } + + return null + } +} diff --git a/src/main/kotlin/drills/drill03/exercise2/PrintAgent.kt b/src/main/kotlin/drills/drill03/exercise2/PrintAgent.kt new file mode 100644 index 0000000..e1da9bc --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/PrintAgent.kt @@ -0,0 +1,16 @@ +package drills.drill03.exercise2 + +class PrintAgent(private val nodes: Array): AbstractAgent(){ + private var index = 0 + private val names = mutableListOf() + + override fun run() { + if (index < nodes.size) { + println("Insert your name:") + val name = readLine() ?: "no name" + names.add(name) + migrateTo(nodes[index++]) + } else + println(names) + } +} diff --git a/src/main/kotlin/drills/drill03/exercise2/PrintApp.kt b/src/main/kotlin/drills/drill03/exercise2/PrintApp.kt new file mode 100644 index 0000000..4e0f096 --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise2/PrintApp.kt @@ -0,0 +1,7 @@ +package drills.drill03.exercise2 + +fun main() { + val nodes = Array(3) { NodeImpl(it) } + + PrintAgent(nodes).start() +} diff --git a/src/main/kotlin/drills/drill03/exercise3/AddTask.kt b/src/main/kotlin/drills/drill03/exercise3/AddTask.kt new file mode 100644 index 0000000..bed31ae --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/AddTask.kt @@ -0,0 +1,7 @@ +package drills.drill03.exercise3 + +import java.io.Serializable + +class AddTask(private val a: Int, private val b: Int) : Task { + override fun execute(): Serializable = a + b +} \ No newline at end of file diff --git a/src/main/kotlin/drills/drill03/exercise3/Client.kt b/src/main/kotlin/drills/drill03/exercise3/Client.kt new file mode 100644 index 0000000..3b55ebc --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/Client.kt @@ -0,0 +1,26 @@ +package drills.drill03.exercise3 + +import util.rmi.Client + +fun main() { + Client(clientHandler).start() +} + +val clientHandler = { + val rev = Client.lookup("rev") as Rev + + println("Enter two numbers:") + val a = readLine()?.toInt() ?: 0 + val b = readLine()?.toInt() ?: 0 + + val sum = rev.executeTask(AddTask(a, b)) + println("The sum of $a and $b is $sum") + + println("Enter the number of which you want to calculate the factorial:") + val n = readLine()?.toInt() ?: 0 + + val fact = rev.executeTask(FactTask(n)) + println("The factorial of $n is $fact") +} + +fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1) diff --git a/src/main/kotlin/drills/drill03/exercise3/FactTask.kt b/src/main/kotlin/drills/drill03/exercise3/FactTask.kt new file mode 100644 index 0000000..e881dfb --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/FactTask.kt @@ -0,0 +1,9 @@ +package drills.drill03.exercise3 + +import java.io.Serializable + +class FactTask(private val n: Int) : Task { + override fun execute(): Serializable = fact(n) + + private fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1) +} \ No newline at end of file diff --git a/src/main/kotlin/drills/drill03/exercise3/Rev.kt b/src/main/kotlin/drills/drill03/exercise3/Rev.kt new file mode 100644 index 0000000..a9d8b88 --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/Rev.kt @@ -0,0 +1,15 @@ +package drills.drill03.exercise3 + +import java.io.Serializable +import java.rmi.Remote +import java.rmi.RemoteException +import java.rmi.server.UnicastRemoteObject + +interface Rev : Remote { + @Throws(RemoteException::class) + fun executeTask(task: Task): Serializable +} + +class RevImpl : Rev, UnicastRemoteObject() { + override fun executeTask(task: Task): Serializable = task.execute() +} diff --git a/src/main/kotlin/drills/drill03/exercise3/Server.kt b/src/main/kotlin/drills/drill03/exercise3/Server.kt new file mode 100644 index 0000000..3622ccd --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/Server.kt @@ -0,0 +1,11 @@ +package drills.drill03.exercise3 + +import util.rmi.Server + +fun main() { + Server { + System.setSecurityManager(SecurityManager()) + val rev: Rev = RevImpl() + Server.bind(rev, "rev") + }.start() +} diff --git a/src/main/kotlin/drills/drill03/exercise3/Task.kt b/src/main/kotlin/drills/drill03/exercise3/Task.kt new file mode 100644 index 0000000..8a7e785 --- /dev/null +++ b/src/main/kotlin/drills/drill03/exercise3/Task.kt @@ -0,0 +1,7 @@ +package drills.drill03.exercise3 + +import java.io.Serializable + +interface Task : Serializable { + fun execute(): Serializable +} \ No newline at end of file