diff --git a/src/main/java/com/example/AddressBook.java b/src/main/java/com/example/AddressBook.java index 30e5a75..aa69e19 100644 --- a/src/main/java/com/example/AddressBook.java +++ b/src/main/java/com/example/AddressBook.java @@ -8,14 +8,15 @@ import akka.actor.typed.javadsl.Behaviors; import akka.actor.typed.javadsl.Receive; import java.util.ArrayList; -import java.util.Collections; +import java.util.Random; public class AddressBook extends AbstractBehavior { - ArrayList> customers; + ArrayList> customers = new ArrayList<>(); public interface Message {} - public record CustomerMessage(ActorRef fragender, String nameFragender) implements Message{} + //Message, wenn ein Empfänger nach einer Adresse fragt + public record CustomerMessage(ActorRef fragender, String nameFragender,ActorRef truckReference) implements Message{} @Override public Receive createReceive() { @@ -24,21 +25,30 @@ public class AddressBook extends AbstractBehavior { .build(); } + //create Methode mit custo = der Liste der Empfänger public static Behavior create(ArrayList> custo){ return Behaviors.setup(context -> new AddressBook(context, custo)); } - private AddressBook(ActorContext context, ArrayList> actors){ + //Konstruktor von dem Adressbuch, in dem auch jedem Customer direkt eine Hello Nachricht geschickt wird, damit diese + //das Adressbuch auch kennen (um nach Empfängern fragen zu können). + private AddressBook(ActorContext context, ArrayList> custo){ super(context); - customers = actors; + if(!custo.isEmpty()){ + this.customers.addAll(custo); + for (ActorRef cst: this.customers) { + cst.tell(new Customer.AddressHello(getContext().getSelf())); + } + } } //Methode, um einen zufälligen Empfänger auszugeben public Behavior onCustomerMessage(CustomerMessage msg){ - Collections.shuffle(customers); - var addressOf = customers.get(0); + Random random = new Random(); + int index = random.nextInt(customers.size()); + var addressOf = customers.get(index); getContext().getLog().info("{} asked for an address",msg.nameFragender); - msg.fragender.tell(new Customer.AddressMessage(addressOf)); + msg.fragender.tell(new Customer.AddressMessage(addressOf, msg.truckReference)); return this; } } diff --git a/src/main/java/com/example/AkkaMainSystem.java b/src/main/java/com/example/AkkaMainSystem.java index e2e7289..55a086e 100644 --- a/src/main/java/com/example/AkkaMainSystem.java +++ b/src/main/java/com/example/AkkaMainSystem.java @@ -30,10 +30,11 @@ public class AkkaMainSystem extends AbstractBehavior { ActorRef a = this.getContext().spawn(Customer.create("Alice"), "alice"); ActorRef b = this.getContext().spawn(Customer.create("Bob"), "bob"); ActorRef c = this.getContext().spawn(Customer.create("Charlie"), "charlie"); + ActorRef d = this.getContext().spawn(Customer.create("Derik"), "derik"); ActorRef timerActor = this.getContext().spawn(ExampleTimerActor.create(), "timeractor"); //#create-actors - ArrayList> actors = new ArrayList<>(Arrays.asList(a,b,c)); - ActorRef adressBook = this.getContext().spawn(AddressBook.create(actors), "addressbook"); + ArrayList> actors = new ArrayList<>(Arrays.asList(a,b,c,d)); + ActorRef addressBook = this.getContext().spawn(AddressBook.create(actors), "addressbook"); return this; } } diff --git a/src/main/java/com/example/Customer.java b/src/main/java/com/example/Customer.java index 25d7679..cc391f4 100644 --- a/src/main/java/com/example/Customer.java +++ b/src/main/java/com/example/Customer.java @@ -7,19 +7,26 @@ import akka.actor.typed.javadsl.ActorContext; import akka.actor.typed.javadsl.Behaviors; import akka.actor.typed.javadsl.Receive; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Random; public class Customer extends AbstractBehavior { String name; - String[] gegenstaende = {"Spülmaschine","Altes CD-Regal", "Goldbarren","20kg Hanteln", "Holzkohlegrill","Blumenerde"}; + + ActorRef adrBook; + ArrayList gegenstaende = new ArrayList<>(Arrays.asList("Spülmaschine","Altes CD-Regal", "Goldbarren","20kg Hanteln", "Holzkohlegrill","Blumenerde")); public interface Message {} //Delivery Nachricht Typ public record DeliveryMessage(Paket paket) implements Message {} //Pickup Nachricht Typ - public record PickUpMessage(ActorRef truckReference, String someString) implements Message {} + public record PickUpMessage(ActorRef truckReference, String someString) implements Message {} + + public record AddressHello(ActorRef book) implements Message {} + public record AddressMessage(ActorRef addresse, ActorRef truckReference) implements Message {} private Customer(ActorContext context, String name){ super(context); @@ -35,26 +42,47 @@ public class Customer extends AbstractBehavior { public Receive createReceive() { return newReceiveBuilder() .onMessage(DeliveryMessage.class, this::onDeliveryMessage) + .onMessage(AddressHello.class, this::onAddressHello) .onMessage(PickUpMessage.class, this::onPickUpMessage) + .onMessage(AddressMessage.class, this::onAddressMessage) .build(); } + //Hier wird das Adressbuch gespeichert, nachdem es sich gemeldet hat + private Behavior onAddressHello(AddressHello msg){ + this.adrBook = msg.book; + return this; + } + //Verhalten, wenn Pickup Nachricht eingegangen ist + //Wenn 80% getroffen wurden, wird eine Anfrage an das Adressbuch geschickt und die Antwort + // an anderer Stelle (onAddressMessage) verarbeitet, um das Paket zu verschicken private Behavior onPickUpMessage(PickUpMessage msg){ Random random = new Random(); - int number = random.nextInt(100); + int number = random.nextInt(101); if(number <= 80){ - //TODO: Nachricht an AddressBook schicken - + //truck wird hier übergeben, damit man im nächsten Schritt wieder auf ihn zugreifen kann. + this.adrBook.tell(new AddressBook.CustomerMessage(getContext().getSelf(), this.name, msg.truckReference)); }else{ - //TODO: PickupResponse an Wagen schicken + msg.truckReference.tell(new DeliveryCar.PickupResponse(null)); } return this; } + //Adresse des Empfängers von dem Adressbuch empfangen und das Paket wird in den Truck geladen und verschickt + private Behavior onAddressMessage(AddressMessage adr){ + Random random = new Random(); + int index = random.nextInt(gegenstaende.size()); + String gegenstand = gegenstaende.get(index); + Paket paket = new Paket(gegenstand,this.name, adr.addresse); + getContext().getLog().info("Paket mit dem Inhalt {} wurde an {} verschickt", paket.inhalt, adr.addresse.path().name()); + adr.truckReference.tell(new DeliveryCar.PickupResponse(paket)); + return this; + } + //Verhalten, wenn Paket eingegangen ist private Behavior onDeliveryMessage(DeliveryMessage pkt){ - getContext().getLog().info("Ich habe ein Paket von {} erhalten mit dem Inhalt: {}",pkt.paket.inhalt, pkt.paket.absender); + getContext().getLog().info("Ich habe ein Paket von {} erhalten mit dem Inhalt: {}", pkt.paket.absender, pkt.paket.inhalt); return this; } } diff --git a/src/main/java/com/example/DeliveryCar.java b/src/main/java/com/example/DeliveryCar.java index 1bd1f11..1b2f8d1 100644 --- a/src/main/java/com/example/DeliveryCar.java +++ b/src/main/java/com/example/DeliveryCar.java @@ -1,12 +1,19 @@ package com.example; import akka.actor.typed.ActorRef; +import akka.actor.typed.Behavior; import akka.actor.typed.javadsl.AbstractBehavior; import akka.actor.typed.javadsl.ActorContext; import akka.actor.typed.javadsl.Receive; + import java.util.ArrayList; +//TODO: Timer Aktivitäten müssen hinzugefügt werden +//TODO: Delivery Nachricht für den Fall, dass der Truck ein Paket für den Customer hat, bei dem der Truck gerade ist +//Gedanke: Eventuell mit Overseer wie in Blatt 1 arbeiten für das Einhalten der Routen +//TODO: Pickup Nachricht an den Customer, wenn der Truck noch freie Plätze hat +//TODO: Arrive Nachricht public class DeliveryCar extends AbstractBehavior { ArrayList pakete; @@ -15,9 +22,12 @@ public class DeliveryCar extends AbstractBehavior { public record LoadMessage(ArrayList pakete) implements Message{} public interface Message {} + public record PickupResponse(Paket paket) implements Message{} @Override public Receive createReceive() { - return newReceiveBuilder().build(); + return newReceiveBuilder() + .onMessage(PickupResponse.class, this::onPickupResponse) + .build(); } private DeliveryCar(ActorContext context,ArrayList> route){ @@ -26,4 +36,27 @@ public class DeliveryCar extends AbstractBehavior { } + //Pakete aus dem Verteilzentrum einladen + //TODO: Eventuell das losfahren und handlen, zu welchem Empfänger er fahren muss, mit einem Overseer Actor implementieren + public Behavior onLoadMessage(LoadMessage msg){ + if(!msg.pakete.isEmpty()){ + this.pakete.addAll(msg.pakete); + } + //vielleicht sowas wie in Blatt 1 Lösung mit einem Overseer Actor und dann einem overseer Attribut im Konstruktor + //this.overseer.tell(new Overseer.LoadedMessage() + return this; + } + + //Customer gibt PickupResponse entweder mit einem Paket oder ohne eins + //Die Methode kann nur ausgeführt werden, wenn zuvor eine Pickup Nachricht an den Empfänger gesendet wurde und das + //impliziert, dass der Truck noch Platz für weitere Pakete hat + public Behavior onPickupResponse(PickupResponse rsp){ + if(rsp.paket != null){ + pakete.add(rsp.paket); + getContext().getLog().info("Aktuelle Anzahl der Pakete im Truck: {}",pakete.size()); + } + //TODO: Fall behandeln, dass kein Paket übergeben wurde (wahrscheinlich einfach Timer setzen) + return this; + } + } diff --git a/src/main/java/com/example/DistributionCenter.java b/src/main/java/com/example/DistributionCenter.java new file mode 100644 index 0000000..26f4f41 --- /dev/null +++ b/src/main/java/com/example/DistributionCenter.java @@ -0,0 +1,21 @@ +package com.example; + +import akka.actor.typed.javadsl.AbstractBehavior; +import akka.actor.typed.javadsl.ActorContext; +import akka.actor.typed.javadsl.Receive; + + //TODO: Implementierung dieser Klasse +public class DistributionCenter extends AbstractBehavior { + + public DistributionCenter(ActorContext context) { + super(context); + } + + interface Message{} + + + @Override + public Receive createReceive() { + return newReceiveBuilder().build(); + } +} diff --git a/src/main/java/com/example/Paket.java b/src/main/java/com/example/Paket.java index ea79a28..e4754e8 100644 --- a/src/main/java/com/example/Paket.java +++ b/src/main/java/com/example/Paket.java @@ -1,13 +1,15 @@ package com.example; +import akka.actor.typed.ActorRef; + public class Paket { String inhalt; String absender; - Customer empfaenger; + ActorRef empfaenger; - Paket(String i, String a, Customer e){ - this.inhalt = i; - this.absender = a; - this.empfaenger = e; + Paket(String inhalt, String absender, ActorRef empfaenger){ + this.inhalt = inhalt; + this.absender = absender; + this.empfaenger = empfaenger; } }