From db65b24cdb83e1494ec68bd92a031f11e83a4588 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Wed, 16 Apr 2025 22:42:26 -0300 Subject: [PATCH 1/7] :sparkles: generating and registering voting with random code at DF Co-authored-by: dartmol203 --- .../java/simple_voting_structure/App.java | 2 -- .../simple_voting_structure/BaseAgent.java | 20 +++++++++--- .../{Formatter.java => LogFormatter.java} | 6 +--- .../simple_voting_structure/Mediator.java | 32 ++++++++++++++++--- 4 files changed, 45 insertions(+), 15 deletions(-) rename src/main/java/simple_voting_structure/{Formatter.java => LogFormatter.java} (64%) diff --git a/src/main/java/simple_voting_structure/App.java b/src/main/java/simple_voting_structure/App.java index fe16054..c59076b 100644 --- a/src/main/java/simple_voting_structure/App.java +++ b/src/main/java/simple_voting_structure/App.java @@ -39,8 +39,6 @@ protected void setup() { votersQuorum = Integer.parseInt(args[0].toString()); } - Random rand = new Random(); - int votingStarter = rand.nextInt(votersQuorum); logger.log(Level.INFO, "Agent number " + votingStarter + " will request to the mediator!"); diff --git a/src/main/java/simple_voting_structure/BaseAgent.java b/src/main/java/simple_voting_structure/BaseAgent.java index 2d1f506..feeec30 100644 --- a/src/main/java/simple_voting_structure/BaseAgent.java +++ b/src/main/java/simple_voting_structure/BaseAgent.java @@ -8,6 +8,7 @@ import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.lang.acl.ACLMessage; import java.util.logging.Logger; +import java.util.Random; import java.util.logging.ConsoleHandler; import java.util.logging.Level; @@ -32,6 +33,9 @@ public abstract class BaseAgent extends Agent { public static final String ANSI_CYAN = "\u001B[36m"; public static final String ANSI_WHITE = "\u001B[37m"; + protected static final Random rand = new Random(); + + protected static final Logger logger = Logger.getLogger(BaseAgent.class.getName()); @Override @@ -42,13 +46,23 @@ protected void registerDF(Agent regAgent, String sdName, String sdType) { DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(getAID()); + ServiceDescription sd = new ServiceDescription(); sd.setType(sdType); sd.setName(sdName); + + DFAgentDescription [] found = DFService.search(this, dfd); + dfd.addServices(sd); - DFService.register(regAgent, dfd); + if ( found.length == 0 ) { + DFService.register(regAgent, dfd); + } else { + found[0].addServices(sd); + DFService.modify(regAgent, found[0]); + } + logger.log(Level.INFO, getLocalName()+" REGISTERED WITH THE DF" ); } catch (FIPAException e) { e.printStackTrace(); @@ -92,10 +106,8 @@ protected void takeDown() { protected void loggerSetup() { ConsoleHandler handler = new ConsoleHandler(); - handler.setFormatter(new Formatter()); + handler.setFormatter(new LogFormatter()); logger.setUseParentHandlers(false); logger.addHandler(handler); } - - } diff --git a/src/main/java/simple_voting_structure/Formatter.java b/src/main/java/simple_voting_structure/LogFormatter.java similarity index 64% rename from src/main/java/simple_voting_structure/Formatter.java rename to src/main/java/simple_voting_structure/LogFormatter.java index 8b8ecad..08bb5e8 100644 --- a/src/main/java/simple_voting_structure/Formatter.java +++ b/src/main/java/simple_voting_structure/LogFormatter.java @@ -2,11 +2,7 @@ import java.util.logging.LogRecord; -public class Formatter extends java.util.logging.Formatter { - - public Formatter() { - // TODO Auto-generated constructor stub - } +public class LogFormatter extends java.util.logging.Formatter { @Override public String format(LogRecord record) { diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index 7e38b8c..b92d123 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -5,16 +5,19 @@ import jade.core.AID; import jade.core.behaviours.CyclicBehaviour; +import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; public class Mediator extends BaseAgent { private static final long serialVersionUID = 1L; - + private static final int MAX_VOTING_CODE = 9999; + private static final int MIN_VOTING_VALUE = 1; + private static final int MAX_VOTING_VALUE = 100; + private int answersCnt = 0; - - private int inpA, inpB; + private int inpA, inpB, voting_code; @Override protected void setup() { @@ -66,6 +69,13 @@ public void action() { } } else if (START.equalsIgnoreCase(msg.getContent())) { // send them a message requesting for a number; + + voting_code = votingCodeGenerator(); + + registerDF(myAgent, Integer.toString(voting_code), Integer.toString(voting_code)); + + logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), voting_code)); + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); msg2.setContent(REQUEST); @@ -73,7 +83,7 @@ public void action() { msg2.addReceiver(new AID(votersName.get(1), AID.ISLOCALNAME)); send(msg2); - logger.log(Level.INFO, getLocalName() + " SENT REQUEST MESSAGE TO " + votersName.get(0) + " AND " + votersName.get(1)); + logger.log(Level.INFO, getLocalName() + " SENT REQUEST MESSAGE TO " + votersName.get(0) + " AND " + votersName.get(1)); } else { logger.log(Level.INFO, myAgent.getLocalName() + " Unexpected message received from " + msg.getSender().getLocalName()); @@ -85,4 +95,18 @@ public void action() { } }); } + + private int votingCodeGenerator () { + int proposedCode; + DFAgentDescription [] foundAgents; + + do { + proposedCode = rand.nextInt(MAX_VOTING_CODE); + + foundAgents = searchAgentByType(Integer.toString(proposedCode)); + System.out.println(String.format("I have found %d agents!\n", foundAgents.length)); + } while ( foundAgents.length > 0 ); + + return proposedCode; + } } From 1d5f0be5f212a448ad2df70aafb94d8874496f87 Mon Sep 17 00:00:00 2001 From: Andre Correa Date: Thu, 17 Apr 2025 00:08:12 -0300 Subject: [PATCH 2/7] add code for generating right answer Co-authored-by: gabrielm2q --- .../java/simple_voting_structure/App.java | 1 - .../simple_voting_structure/Mediator.java | 29 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/simple_voting_structure/App.java b/src/main/java/simple_voting_structure/App.java index c59076b..eba90d4 100644 --- a/src/main/java/simple_voting_structure/App.java +++ b/src/main/java/simple_voting_structure/App.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.logging.Level; -import java.util.Random; /** diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index b92d123..421ba02 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.logging.Level; +import FIPA.stringsHelper; import jade.core.AID; import jade.core.behaviours.CyclicBehaviour; import jade.domain.FIPAAgentManagement.DFAgentDescription; @@ -16,8 +17,11 @@ public class Mediator extends BaseAgent { private static final int MIN_VOTING_VALUE = 1; private static final int MAX_VOTING_VALUE = 100; + private int ans; private int answersCnt = 0; - private int inpA, inpB, voting_code; + private int inpA; + private int inpB; + private int votingCode; @Override protected void setup() { @@ -70,20 +74,21 @@ public void action() { } else if (START.equalsIgnoreCase(msg.getContent())) { // send them a message requesting for a number; - voting_code = votingCodeGenerator(); + votingCode = votingCodeGenerator(); - registerDF(myAgent, Integer.toString(voting_code), Integer.toString(voting_code)); + setAns(); - logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), voting_code)); + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), votingCode)); - ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); - msg2.setContent(REQUEST); + ACLMessage msg2 = msg.createReply(); - msg2.addReceiver(new AID(votersName.get(0), AID.ISLOCALNAME)); - msg2.addReceiver(new AID(votersName.get(1), AID.ISLOCALNAME)); + msg2.setContent("VOTEID " + votingCode + " MAXVALUE " + MAX_VOTING_VALUE + " MINVALUE " + MIN_VOTING_VALUE); send(msg2); - logger.log(Level.INFO, getLocalName() + " SENT REQUEST MESSAGE TO " + votersName.get(0) + " AND " + votersName.get(1)); + logger.log(Level.INFO, getLocalName() + " SENT VOTING CODE TO " + msg2.getAllReceiver().next()); + } else { logger.log(Level.INFO, myAgent.getLocalName() + " Unexpected message received from " + msg.getSender().getLocalName()); @@ -104,9 +109,13 @@ private int votingCodeGenerator () { proposedCode = rand.nextInt(MAX_VOTING_CODE); foundAgents = searchAgentByType(Integer.toString(proposedCode)); - System.out.println(String.format("I have found %d agents!\n", foundAgents.length)); } while ( foundAgents.length > 0 ); return proposedCode; } + + private void setAns(){ + ans = rand.nextInt(MIN_VOTING_VALUE, MAX_VOTING_VALUE); + + } } From 0aa708c61e4ddf29d0ea33560ffd7ecd19f9b785 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Thu, 17 Apr 2025 19:30:11 -0300 Subject: [PATCH 3/7] :sparkles: adds voting invitation functionality Co-authored-by: dartmol203 --- .../simple_voting_structure/BaseAgent.java | 3 ++ .../simple_voting_structure/Mediator.java | 6 ++-- .../java/simple_voting_structure/Voter.java | 32 ++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/simple_voting_structure/BaseAgent.java b/src/main/java/simple_voting_structure/BaseAgent.java index feeec30..c7ec1aa 100644 --- a/src/main/java/simple_voting_structure/BaseAgent.java +++ b/src/main/java/simple_voting_structure/BaseAgent.java @@ -22,6 +22,8 @@ public abstract class BaseAgent extends Agent { public static final String ANSWER = "ANSWER"; public static final String THANKS = "THANKS"; public static final String START = "START"; + public static final String VOTEID = "VOTEID"; + public static final String INVITE = "INVITE"; public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLUE = "\u001B[34m"; @@ -35,6 +37,7 @@ public abstract class BaseAgent extends Agent { protected static final Random rand = new Random(); + protected int votingCode; protected static final Logger logger = Logger.getLogger(BaseAgent.class.getName()); diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index 421ba02..adad657 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -21,7 +21,6 @@ public class Mediator extends BaseAgent { private int answersCnt = 0; private int inpA; private int inpB; - private int votingCode; @Override protected void setup() { @@ -84,10 +83,10 @@ public void action() { ACLMessage msg2 = msg.createReply(); - msg2.setContent("VOTEID " + votingCode + " MAXVALUE " + MAX_VOTING_VALUE + " MINVALUE " + MIN_VOTING_VALUE); + msg2.setContent(String.format("VOTEID %d MINVALUE %d MAXVALUE %d", votingCode, MIN_VOTING_VALUE, MAX_VOTING_VALUE)); send(msg2); - logger.log(Level.INFO, getLocalName() + " SENT VOTING CODE TO " + msg2.getAllReceiver().next()); + logger.log(Level.INFO, getLocalName() + " SENT VOTING CODE TO " + msg.getSender().getLocalName()); } else { logger.log(Level.INFO, @@ -116,6 +115,5 @@ private int votingCodeGenerator () { private void setAns(){ ans = rand.nextInt(MIN_VOTING_VALUE, MAX_VOTING_VALUE); - } } diff --git a/src/main/java/simple_voting_structure/Voter.java b/src/main/java/simple_voting_structure/Voter.java index cab792f..2a75345 100644 --- a/src/main/java/simple_voting_structure/Voter.java +++ b/src/main/java/simple_voting_structure/Voter.java @@ -1,5 +1,7 @@ package simple_voting_structure; +import java.util.ArrayList; +import java.util.Arrays; import java.util.logging.Level; import jade.core.AID; @@ -11,6 +13,9 @@ public class Voter extends BaseAgent { private static final long serialVersionUID = 1L; + + private int minVotingValue; + private int maxVotingValue; @Override protected void setup() { @@ -47,7 +52,7 @@ public void action() { msg2.addReceiver(foundMediator); send(msg2); - logger.log(Level.INFO, getLocalName() + " SENT START MESSAGE TO " + foundMediator.getLocalName()); + logger.log(Level.INFO, String.format("%s SENT START MESSAGE TO %s", getLocalName(), foundMediator.getLocalName())); } } catch ( Exception any ) { logger.log(Level.SEVERE, ANSI_RED + "ERROR WHILE SENDING MESSAGE" + ANSI_RESET); @@ -59,6 +64,31 @@ public void action() { || EVEN.equalsIgnoreCase(msg.getContent().split(" ")[0])) { logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED RESULTS MESSAGE FROM " + msg.getSender().getLocalName()); logger.log(Level.INFO, myAgent.getLocalName() + " " + msg.getContent()); + } else if (msg.getContent().startsWith(VOTEID)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); + + votingCode = Integer.parseInt(splittedMsg[1]); + minVotingValue = Integer.parseInt(splittedMsg[3]); + maxVotingValue = Integer.parseInt(splittedMsg[5]); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + ArrayList foundAgents = new ArrayList(Arrays.asList(searchAgentByType("voter"))); + + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); + msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); + + foundAgents.forEach(ag -> { + if ( !ag.getName().equals(myAgent.getAID()) ) { + msg2.addReceiver(ag.getName()); + } + }); + + send(msg2); + logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); } else { logger.log(Level.INFO, myAgent.getLocalName() + " Unexpected message received from " + msg.getSender().getLocalName()); From 7096e8c4b292e58c1c4987009d37028b4e5aa3b2 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Thu, 17 Apr 2025 19:42:37 -0300 Subject: [PATCH 4/7] :sparkles: parsing invitations sent to voters Co-authored-by: dartmol203 --- src/main/java/simple_voting_structure/Voter.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/simple_voting_structure/Voter.java b/src/main/java/simple_voting_structure/Voter.java index 2a75345..4e3b746 100644 --- a/src/main/java/simple_voting_structure/Voter.java +++ b/src/main/java/simple_voting_structure/Voter.java @@ -89,9 +89,21 @@ public void action() { send(msg2); logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); + } else if (msg.getContent().startsWith(INVITE)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); + + votingCode = Integer.parseInt(splittedMsg[2]); + minVotingValue = Integer.parseInt(splittedMsg[4]); + maxVotingValue = Integer.parseInt(splittedMsg[6]); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + } else { logger.log(Level.INFO, - myAgent.getLocalName() + " Unexpected message received from " + msg.getSender().getLocalName()); + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); } } else { // if no message is arrived, block the behaviour From 475e7f435eaf766aff4b363b71bf3a76790a7241 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Thu, 17 Apr 2025 20:50:25 -0300 Subject: [PATCH 5/7] :sparkles: adds voting registration logic to voters Co-authored-by: dartmol203 --- Makefile | 2 +- .../simple_voting_structure/BaseAgent.java | 21 ++++++++++++++++ .../simple_voting_structure/Mediator.java | 3 +++ .../java/simple_voting_structure/Voter.java | 25 ++++++++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5d5313d..d2a2ca0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -QUORUM ?= 2 +QUORUM ?= 3 PATH_PROJECT_JAR = target/simple_voting_structure-0.0.1-SNAPSHOT.jar PROJECT_GROUP = simple_voting_structure JADE_AGENTS = simple_voting_structure:$(PROJECT_GROUP).App($(QUORUM)); diff --git a/src/main/java/simple_voting_structure/BaseAgent.java b/src/main/java/simple_voting_structure/BaseAgent.java index c7ec1aa..17b37b0 100644 --- a/src/main/java/simple_voting_structure/BaseAgent.java +++ b/src/main/java/simple_voting_structure/BaseAgent.java @@ -24,6 +24,7 @@ public abstract class BaseAgent extends Agent { public static final String START = "START"; public static final String VOTEID = "VOTEID"; public static final String INVITE = "INVITE"; + public static final String REGISTERED = "REGISTERED"; public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLUE = "\u001B[34m"; @@ -96,6 +97,26 @@ protected DFAgentDescription[] searchAgentByType (String type) { return foundAgents; } + protected DFAgentDescription[] searchAgentByType (String [] type) { + DFAgentDescription search = new DFAgentDescription(); + + DFAgentDescription [] foundAgents = null; + + for ( int i = 0; i < type.length; ++i ) { + ServiceDescription sd = new ServiceDescription(); + sd.setType(type[i]); + search.addServices(sd); + } + + try { + foundAgents = DFService.search(this, search); + } catch ( Exception any ) { + any.printStackTrace(); + } + + return foundAgents; + } + protected void takeDown() { // Deregister with the DF try { diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index adad657..9810e31 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -21,6 +21,7 @@ public class Mediator extends BaseAgent { private int answersCnt = 0; private int inpA; private int inpB; + private int registeredQuorum = 0; @Override protected void setup() { @@ -78,6 +79,8 @@ public void action() { setAns(); registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + registeredQuorum = 0; logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), votingCode)); diff --git a/src/main/java/simple_voting_structure/Voter.java b/src/main/java/simple_voting_structure/Voter.java index 4e3b746..d5df0c7 100644 --- a/src/main/java/simple_voting_structure/Voter.java +++ b/src/main/java/simple_voting_structure/Voter.java @@ -76,7 +76,10 @@ public void action() { registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - ArrayList foundAgents = new ArrayList(Arrays.asList(searchAgentByType("voter"))); + informVotingRegistration(); + + ArrayList foundAgents = new ArrayList( + Arrays.asList(searchAgentByType("voter"))); ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); @@ -89,6 +92,8 @@ public void action() { send(msg2); logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); + + } else if (msg.getContent().startsWith(INVITE)) { logger.log(Level.INFO, String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); @@ -101,6 +106,7 @@ public void action() { registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + informVotingRegistration(); } else { logger.log(Level.INFO, String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); @@ -110,6 +116,23 @@ public void action() { block(); } } + + private void informVotingRegistration() { + ACLMessage informMsg = new ACLMessage(ACLMessage.INFORM); + informMsg.setContent(String.format("%s IN %d", REGISTERED, votingCode)); + + ArrayList foundVotingParticipants = new ArrayList<>(); + String [] types = { Integer.toString(votingCode), "mediator" }; + foundVotingParticipants = new ArrayList( + Arrays.asList(searchAgentByType(types))); + + foundVotingParticipants.forEach(ag -> { + informMsg.addReceiver(ag.getName()); + }); + + send(informMsg); + logger.log(Level.INFO, String.format("%s INFORMED VOTING REGISTRATION TO MEDIATOR!", getLocalName())); + } }); } } From 282d5ce87029e71673a9dea92061aff14de97331 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Fri, 18 Apr 2025 11:43:27 -0300 Subject: [PATCH 6/7] :sparkles: adds vote request logic and refactor msg handling behaviours Co-authored-by: dartmol203 --- .../simple_voting_structure/BaseAgent.java | 1 + .../simple_voting_structure/Mediator.java | 50 +++- .../java/simple_voting_structure/Voter.java | 226 ++++++++++-------- 3 files changed, 175 insertions(+), 102 deletions(-) diff --git a/src/main/java/simple_voting_structure/BaseAgent.java b/src/main/java/simple_voting_structure/BaseAgent.java index 17b37b0..afd67d8 100644 --- a/src/main/java/simple_voting_structure/BaseAgent.java +++ b/src/main/java/simple_voting_structure/BaseAgent.java @@ -25,6 +25,7 @@ public abstract class BaseAgent extends Agent { public static final String VOTEID = "VOTEID"; public static final String INVITE = "INVITE"; public static final String REGISTERED = "REGISTERED"; + public static final String INFORM = "INFORM"; public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLUE = "\u001B[34m"; diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index 9810e31..fd5bcaa 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -1,11 +1,13 @@ package simple_voting_structure; import java.util.ArrayList; +import java.util.Arrays; import java.util.logging.Level; import FIPA.stringsHelper; import jade.core.AID; import jade.core.behaviours.CyclicBehaviour; +import jade.domain.FIPAException; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; @@ -22,6 +24,7 @@ public class Mediator extends BaseAgent { private int inpA; private int inpB; private int registeredQuorum = 0; + private int totalQuorum = 0; @Override protected void setup() { @@ -89,11 +92,24 @@ public void action() { msg2.setContent(String.format("VOTEID %d MINVALUE %d MAXVALUE %d", votingCode, MIN_VOTING_VALUE, MAX_VOTING_VALUE)); send(msg2); - logger.log(Level.INFO, getLocalName() + " SENT VOTING CODE TO " + msg.getSender().getLocalName()); - + logger.log(Level.INFO, String.format("%s SENT VOTING CODE TO %s", getLocalName(), msg.getSender().getLocalName())); + } else if ( msg.getContent().startsWith(INFORM) ) { + String [] splittedMsg = msg.getContent().split(" "); + + totalQuorum = Integer.parseInt(splittedMsg[2]); + + logger.log(Level.INFO, String.format("EXPECTED QUORUM BY %s: %d VOTERS!", getLocalName(), totalQuorum)); + } else if ( msg.getContent().startsWith(REGISTERED) ) { + ++registeredQuorum; + + if ( registeredQuorum == totalQuorum ) { + logger.log(Level.INFO, "TOTAL QUORUM REACHED! REQUESTING VOTES!"); + + requestVotes(); + } } else { logger.log(Level.INFO, - myAgent.getLocalName() + " Unexpected message received from " + msg.getSender().getLocalName()); + String.format("%s RECEIVED AN UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); } } else { // if no message is arrived, block the behaviour @@ -103,6 +119,34 @@ public void action() { }); } + private void requestVotes() { + try { + + ACLMessage requestVoteMsg = new ACLMessage(ACLMessage.REQUEST); + requestVoteMsg.setContent(String.format("%s VOTE FOR %d", REQUEST, votingCode)); + + ArrayList foundVotingParticipants = new ArrayList<>(); + String [] types = { Integer.toString(votingCode), "voter" }; + foundVotingParticipants = new ArrayList( + Arrays.asList(searchAgentByType(types))); + + if ( foundVotingParticipants.size() != registeredQuorum ) { + throw new Exception(String.format("FOUND VOTERS DIFFERS FROM REGISTERED QUORUM! (%d x %d)", + foundVotingParticipants.size(), registeredQuorum)); + } + + foundVotingParticipants.forEach(ag -> { + requestVoteMsg.addReceiver(ag.getName()); + }); + + send(requestVoteMsg); + logger.log(Level.INFO, + String.format("%s REQUESTED A VOTE FOR ALL %d VOTERS!", getLocalName(), foundVotingParticipants.size())); + } catch (Exception e) { + e.printStackTrace(); + } + } + private int votingCodeGenerator () { int proposedCode; DFAgentDescription [] foundAgents; diff --git a/src/main/java/simple_voting_structure/Voter.java b/src/main/java/simple_voting_structure/Voter.java index d5df0c7..85cefc3 100644 --- a/src/main/java/simple_voting_structure/Voter.java +++ b/src/main/java/simple_voting_structure/Voter.java @@ -5,7 +5,9 @@ import java.util.logging.Level; import jade.core.AID; +import jade.core.Agent; import jade.core.behaviours.CyclicBehaviour; +import jade.core.behaviours.OneShotBehaviour; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; @@ -23,116 +25,142 @@ protected void setup() { this.registerDF(this, "Voter", "voter"); - addBehaviour(new CyclicBehaviour(this) { - public void action() { - // listen if a greetings message arrives - ACLMessage msg = receive(MessageTemplate.MatchPerformative(ACLMessage.INFORM)); - if (msg != null) { - if (REQUEST.equalsIgnoreCase(msg.getContent())) { - final int Max = 10; - final int Min = 1; + addBehaviour(new HandleMessages()); + } + + private class HandleMessages extends CyclicBehaviour { + private static final long serialVersionUID = 1L; - // if a greetings message is arrived then send an ANSWER - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED REQUEST MESSAGE FROM " + msg.getSender().getLocalName()); - ACLMessage reply = msg.createReply(); - reply.setContent(ANSWER + " " + (Min + (int) (Math.random() * ((Max - Min) + 1)))); - myAgent.send(reply); - logger.log(Level.INFO, myAgent.getLocalName() + " SENT ANSWER MESSAGE"); - } else if (START.equalsIgnoreCase(msg.getContent())) { - ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); - msg2.setContent(START); - - DFAgentDescription [] foundAgents = searchAgentByType("mediator"); - - try { - AID foundMediator = null; - if ( foundAgents.length > 0 ) { - foundMediator = foundAgents[0].getName(); - - msg2.addReceiver(foundMediator); - - send(msg2); - logger.log(Level.INFO, String.format("%s SENT START MESSAGE TO %s", getLocalName(), foundMediator.getLocalName())); - } - } catch ( Exception any ) { - logger.log(Level.SEVERE, ANSI_RED + "ERROR WHILE SENDING MESSAGE" + ANSI_RESET); - any.printStackTrace(); - } - } else if (THANKS.equalsIgnoreCase(msg.getContent())) { - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED THANKS MESSAGE FROM " + msg.getSender().getLocalName()); - } else if (ODD.equalsIgnoreCase(msg.getContent().split(" ")[0]) - || EVEN.equalsIgnoreCase(msg.getContent().split(" ")[0])) { - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED RESULTS MESSAGE FROM " + msg.getSender().getLocalName()); - logger.log(Level.INFO, myAgent.getLocalName() + " " + msg.getContent()); - } else if (msg.getContent().startsWith(VOTEID)) { - logger.log(Level.INFO, - String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); - - String [] splittedMsg = msg.getContent().split(" "); - - votingCode = Integer.parseInt(splittedMsg[1]); - minVotingValue = Integer.parseInt(splittedMsg[3]); - maxVotingValue = Integer.parseInt(splittedMsg[5]); - - registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - - informVotingRegistration(); - - ArrayList foundAgents = new ArrayList( - Arrays.asList(searchAgentByType("voter"))); - - ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); - msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); - - foundAgents.forEach(ag -> { - if ( !ag.getName().equals(myAgent.getAID()) ) { - msg2.addReceiver(ag.getName()); - } - }); - - send(msg2); - logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); - - - } else if (msg.getContent().startsWith(INVITE)) { - logger.log(Level.INFO, - String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); - - String [] splittedMsg = msg.getContent().split(" "); + public void action() { + ACLMessage msg = receive(); + + if ( msg == null ) block(); + else { + switch ( msg.getPerformative() ) { + case ACLMessage.INFORM: + addBehaviour(new HandleInform(msg)); + default: + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE PERFORMATIVE FROM %s", getLocalName(), msg.getSender().getLocalName())); + } + } + } + } + + private class HandleInform extends OneShotBehaviour { + private static final long serialVersionUID = 1L; + private ACLMessage msg; + + private HandleInform (ACLMessage msg) { + this.msg = msg; + } + + public void action () { + if (REQUEST.equalsIgnoreCase(msg.getContent())) { + final int Max = 10; + final int Min = 1; - votingCode = Integer.parseInt(splittedMsg[2]); - minVotingValue = Integer.parseInt(splittedMsg[4]); - maxVotingValue = Integer.parseInt(splittedMsg[6]); + // if a greetings message is arrived then send an ANSWER + logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED REQUEST MESSAGE FROM " + msg.getSender().getLocalName()); + ACLMessage reply = msg.createReply(); + reply.setContent(ANSWER + " " + (Min + (int) (Math.random() * ((Max - Min) + 1)))); + myAgent.send(reply); + logger.log(Level.INFO, myAgent.getLocalName() + " SENT ANSWER MESSAGE"); + } else if (START.equalsIgnoreCase(msg.getContent())) { + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); + msg2.setContent(START); + + DFAgentDescription [] foundAgents = searchAgentByType("mediator"); + + try { + AID foundMediator = null; + if ( foundAgents.length > 0 ) { + foundMediator = foundAgents[0].getName(); - registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + msg2.addReceiver(foundMediator); - informVotingRegistration(); - } else { - logger.log(Level.INFO, - String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); + send(msg2); + logger.log(Level.INFO, String.format("%s SENT START MESSAGE TO %s", getLocalName(), foundMediator.getLocalName())); } - } else { - // if no message is arrived, block the behaviour - block(); + } catch ( Exception any ) { + logger.log(Level.SEVERE, ANSI_RED + "ERROR WHILE SENDING MESSAGE" + ANSI_RESET); + any.printStackTrace(); } - } - - private void informVotingRegistration() { - ACLMessage informMsg = new ACLMessage(ACLMessage.INFORM); - informMsg.setContent(String.format("%s IN %d", REGISTERED, votingCode)); + } else if (THANKS.equalsIgnoreCase(msg.getContent())) { + logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED THANKS MESSAGE FROM " + msg.getSender().getLocalName()); + } else if (ODD.equalsIgnoreCase(msg.getContent().split(" ")[0]) + || EVEN.equalsIgnoreCase(msg.getContent().split(" ")[0])) { + logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED RESULTS MESSAGE FROM " + msg.getSender().getLocalName()); + logger.log(Level.INFO, myAgent.getLocalName() + " " + msg.getContent()); + } else if (msg.getContent().startsWith(VOTEID)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); + + votingCode = Integer.parseInt(splittedMsg[1]); + minVotingValue = Integer.parseInt(splittedMsg[3]); + maxVotingValue = Integer.parseInt(splittedMsg[5]); - ArrayList foundVotingParticipants = new ArrayList<>(); - String [] types = { Integer.toString(votingCode), "mediator" }; - foundVotingParticipants = new ArrayList( - Arrays.asList(searchAgentByType(types))); + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - foundVotingParticipants.forEach(ag -> { - informMsg.addReceiver(ag.getName()); + informVotingRegistration(); + + ArrayList foundAgents = new ArrayList( + Arrays.asList(searchAgentByType("voter"))); + + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); + msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); + + foundAgents.forEach(ag -> { + if ( !ag.getName().equals(myAgent.getAID()) ) { + msg2.addReceiver(ag.getName()); + } }); - send(informMsg); - logger.log(Level.INFO, String.format("%s INFORMED VOTING REGISTRATION TO MEDIATOR!", getLocalName())); + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); ACLMessage reply = msg.createReply(); + reply.setContent(String.format("%s QUORUM %d", INFORM, foundAgents.size())); + myAgent.send(reply); + + send(msg2); + logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); + + + } else if (msg.getContent().startsWith(INVITE)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); + + votingCode = Integer.parseInt(splittedMsg[2]); + minVotingValue = Integer.parseInt(splittedMsg[4]); + maxVotingValue = Integer.parseInt(splittedMsg[6]); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + informVotingRegistration(); + } else { + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); } + } + } + + private void informVotingRegistration() { + ACLMessage informMsg = new ACLMessage(ACLMessage.INFORM); + informMsg.setContent(String.format("%s IN %d", REGISTERED, votingCode)); + + ArrayList foundVotingParticipants = new ArrayList<>(); + String [] types = { Integer.toString(votingCode), "mediator" }; + foundVotingParticipants = new ArrayList( + Arrays.asList(searchAgentByType(types))); + + foundVotingParticipants.forEach(ag -> { + informMsg.addReceiver(ag.getName()); }); + + send(informMsg); + logger.log(Level.INFO, String.format("%s INFORMED VOTING REGISTRATION TO MEDIATOR!", getLocalName())); } } From 869f4392c0b600346f8e0d82a2417206d010c2a3 Mon Sep 17 00:00:00 2001 From: gabrielm2q Date: Fri, 18 Apr 2025 20:10:04 -0300 Subject: [PATCH 7/7] :sparkles: adds vote logic and refactor message handling structure Co-authored-by: dartmol203 --- .../simple_voting_structure/BaseAgent.java | 51 ++++ .../simple_voting_structure/Mediator.java | 136 ++++------- .../java/simple_voting_structure/Voter.java | 224 +++++++++--------- 3 files changed, 212 insertions(+), 199 deletions(-) diff --git a/src/main/java/simple_voting_structure/BaseAgent.java b/src/main/java/simple_voting_structure/BaseAgent.java index afd67d8..0ea0a1f 100644 --- a/src/main/java/simple_voting_structure/BaseAgent.java +++ b/src/main/java/simple_voting_structure/BaseAgent.java @@ -2,11 +2,14 @@ import jade.core.AID; import jade.core.Agent; +import jade.core.behaviours.CyclicBehaviour; +import jade.core.behaviours.OneShotBehaviour; import jade.domain.DFService; import jade.domain.FIPAException; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.lang.acl.ACLMessage; + import java.util.logging.Logger; import java.util.Random; import java.util.logging.ConsoleHandler; @@ -26,6 +29,7 @@ public abstract class BaseAgent extends Agent { public static final String INVITE = "INVITE"; public static final String REGISTERED = "REGISTERED"; public static final String INFORM = "INFORM"; + public static final String VOTE = "VOTE"; public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLUE = "\u001B[34m"; @@ -46,6 +50,53 @@ public abstract class BaseAgent extends Agent { @Override protected void setup() {} + protected CyclicBehaviour handleMessages () { + CyclicBehaviour handleMessages = new CyclicBehaviour(this) { + private static final long serialVersionUID = 1L; + + public void action() { + ACLMessage msg = receive(); + + if ( msg == null ) block(); + else { + switch ( msg.getPerformative() ) { + case ACLMessage.INFORM: + addBehaviour(handleInform(msg)); + break; + case ACLMessage.REQUEST: + addBehaviour(handleRequest(msg)); + break; + default: + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE PERFORMATIVE FROM %s", getLocalName(), msg.getSender().getLocalName())); + } + } + } + }; + + return handleMessages; + } + + protected OneShotBehaviour handleInform ( ACLMessage msg ) { + OneShotBehaviour handleInform = new OneShotBehaviour(this) { + private static final long serialVersionUID = 1L; + + public void action () {} + }; + + return handleInform; + } + + protected OneShotBehaviour handleRequest ( ACLMessage msg ) { + OneShotBehaviour handleRequest = new OneShotBehaviour(this) { + private static final long serialVersionUID = 1L; + + public void action () {} + }; + + return handleRequest; + } + protected void registerDF(Agent regAgent, String sdName, String sdType) { try { DFAgentDescription dfd = new DFAgentDescription(); diff --git a/src/main/java/simple_voting_structure/Mediator.java b/src/main/java/simple_voting_structure/Mediator.java index fd5bcaa..ae3be71 100644 --- a/src/main/java/simple_voting_structure/Mediator.java +++ b/src/main/java/simple_voting_structure/Mediator.java @@ -7,6 +7,7 @@ import FIPA.stringsHelper; import jade.core.AID; import jade.core.behaviours.CyclicBehaviour; +import jade.core.behaviours.OneShotBehaviour; import jade.domain.FIPAException; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.lang.acl.ACLMessage; @@ -19,10 +20,7 @@ public class Mediator extends BaseAgent { private static final int MIN_VOTING_VALUE = 1; private static final int MAX_VOTING_VALUE = 100; - private int ans; - private int answersCnt = 0; - private int inpA; - private int inpB; + private int votingAnswer = 0; private int registeredQuorum = 0; private int totalQuorum = 0; @@ -30,98 +28,62 @@ public class Mediator extends BaseAgent { protected void setup() { logger.log(Level.INFO, "I'm the mediator!"); - - Object[] args = getArguments(); - ArrayList votersName = new ArrayList(); - - if (args != null && args.length > 0) { - for (Object voter : args) { - votersName.add(voter.toString()); - } - } - this.registerDF(this, "Mediator", "mediator"); - - addBehaviour(new CyclicBehaviour(this) { - public void action() { - // listen if a greetings message arrives - ACLMessage msg = receive(MessageTemplate.MatchPerformative(ACLMessage.INFORM)); - if (msg != null) { - if (ANSWER.equalsIgnoreCase(msg.getContent().split(" ")[0])) { - // if an ANSWER to a greetings message is arrived - // then send a THANKS message - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED ANSWER MESSAGE FROM " + msg.getSender().getLocalName()); - ACLMessage replyT = msg.createReply(); - replyT.setContent(THANKS); - myAgent.send(replyT); - logger.log(Level.INFO, myAgent.getLocalName() + " SENT THANKS MESSAGE"); - - if (msg.getSender().getLocalName().equals(votersName.get(0))) { - inpA = Integer.parseInt(msg.getContent().split(" ")[1]); - } else { - inpB = Integer.parseInt(msg.getContent().split(" ")[1]); - } - - answersCnt++; - if (answersCnt == 2) { - ACLMessage replyW = new ACLMessage(ACLMessage.INFORM); - - replyW.setContent((((inpA + inpB) % 2 != 0) ? ODD + " " + votersName.get(0) - : EVEN + " " + votersName.get(1)) + " WINNER!"); - replyW.addReceiver(new AID(votersName.get(0), AID.ISLOCALNAME)); - replyW.addReceiver(new AID(votersName.get(1), AID.ISLOCALNAME)); - myAgent.send(replyW); - - logger.log(Level.INFO, myAgent.getLocalName() + " SENT WINNER MESSAGE"); - } - } else if (START.equalsIgnoreCase(msg.getContent())) { - // send them a message requesting for a number; - - votingCode = votingCodeGenerator(); - - setAns(); - - registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - - registeredQuorum = 0; - - logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), votingCode)); - - ACLMessage msg2 = msg.createReply(); - - msg2.setContent(String.format("VOTEID %d MINVALUE %d MAXVALUE %d", votingCode, MIN_VOTING_VALUE, MAX_VOTING_VALUE)); - - send(msg2); - logger.log(Level.INFO, String.format("%s SENT VOTING CODE TO %s", getLocalName(), msg.getSender().getLocalName())); - } else if ( msg.getContent().startsWith(INFORM) ) { - String [] splittedMsg = msg.getContent().split(" "); - - totalQuorum = Integer.parseInt(splittedMsg[2]); - - logger.log(Level.INFO, String.format("EXPECTED QUORUM BY %s: %d VOTERS!", getLocalName(), totalQuorum)); - } else if ( msg.getContent().startsWith(REGISTERED) ) { - ++registeredQuorum; + + addBehaviour(handleMessages()); + } + + @Override + protected OneShotBehaviour handleInform ( ACLMessage msg ) { + OneShotBehaviour handleInform = new OneShotBehaviour(this) { + private static final long serialVersionUID = 1L; + + public void action () { + if (msg.getContent().startsWith(START)) { + // send them a message requesting for a number; + + votingCode = votingCodeGenerator(); + + setAns(); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + registeredQuorum = 0; + + logger.log(Level.INFO, String.format("%s AGENT GENERATED VOTING WITH CODE %d!", getLocalName(), votingCode)); + + ACLMessage msg2 = msg.createReply(); + + msg2.setContent(String.format("VOTEID %d MINVALUE %d MAXVALUE %d", votingCode, MIN_VOTING_VALUE, MAX_VOTING_VALUE)); + + send(msg2); + logger.log(Level.INFO, String.format("%s SENT VOTING CODE TO %s", getLocalName(), msg.getSender().getLocalName())); + } else if ( msg.getContent().startsWith(INFORM) ) { + String [] splittedMsg = msg.getContent().split(" "); + + totalQuorum = Integer.parseInt(splittedMsg[2]); + + logger.log(Level.INFO, String.format("EXPECTED QUORUM BY %s: %d VOTERS!", getLocalName(), totalQuorum)); + } else if ( msg.getContent().startsWith(REGISTERED) ) { + ++registeredQuorum; + + if ( registeredQuorum == totalQuorum ) { + logger.log(Level.INFO, "TOTAL QUORUM REACHED! REQUESTING VOTES!"); - if ( registeredQuorum == totalQuorum ) { - logger.log(Level.INFO, "TOTAL QUORUM REACHED! REQUESTING VOTES!"); - - requestVotes(); - } - } else { - logger.log(Level.INFO, - String.format("%s RECEIVED AN UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); + requestVotes(); } } else { - // if no message is arrived, block the behaviour - block(); + logger.log(Level.INFO, + String.format("%s RECEIVED AN UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); } } - }); + }; + + return handleInform; } private void requestVotes() { try { - ACLMessage requestVoteMsg = new ACLMessage(ACLMessage.REQUEST); requestVoteMsg.setContent(String.format("%s VOTE FOR %d", REQUEST, votingCode)); @@ -161,6 +123,6 @@ private int votingCodeGenerator () { } private void setAns(){ - ans = rand.nextInt(MIN_VOTING_VALUE, MAX_VOTING_VALUE); + votingAnswer = rand.nextInt(MIN_VOTING_VALUE, MAX_VOTING_VALUE + 1); } } diff --git a/src/main/java/simple_voting_structure/Voter.java b/src/main/java/simple_voting_structure/Voter.java index 85cefc3..ecd92bf 100644 --- a/src/main/java/simple_voting_structure/Voter.java +++ b/src/main/java/simple_voting_structure/Voter.java @@ -16,8 +16,9 @@ public class Voter extends BaseAgent { private static final long serialVersionUID = 1L; - private int minVotingValue; - private int maxVotingValue; + private int minVotingValue = 0; + private int maxVotingValue = 0; + private int myVotingValue = 0; @Override protected void setup() { @@ -25,128 +26,127 @@ protected void setup() { this.registerDF(this, "Voter", "voter"); - addBehaviour(new HandleMessages()); + addBehaviour(handleMessages()); } - private class HandleMessages extends CyclicBehaviour { - private static final long serialVersionUID = 1L; + @Override + protected OneShotBehaviour handleInform ( ACLMessage msg ) { + + OneShotBehaviour handleInform = new OneShotBehaviour(this) { + private static final long serialVersionUID = 1L; + + public void action () { + if (msg.getContent().startsWith(START)) { + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); + msg2.setContent(START); + + DFAgentDescription [] foundAgents = searchAgentByType("mediator"); + + try { + AID foundMediator = null; + if ( foundAgents.length > 0 ) { + foundMediator = foundAgents[0].getName(); + + msg2.addReceiver(foundMediator); + + send(msg2); + logger.log(Level.INFO, String.format("%s SENT START MESSAGE TO %s", getLocalName(), foundMediator.getLocalName())); + } + } catch ( Exception any ) { + logger.log(Level.SEVERE, ANSI_RED + "ERROR WHILE SENDING MESSAGE" + ANSI_RESET); + any.printStackTrace(); + } + } else if (THANKS.equalsIgnoreCase(msg.getContent())) { + logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED THANKS MESSAGE FROM " + msg.getSender().getLocalName()); + } else if (ODD.equalsIgnoreCase(msg.getContent().split(" ")[0]) + || EVEN.equalsIgnoreCase(msg.getContent().split(" ")[0])) { + logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED RESULTS MESSAGE FROM " + msg.getSender().getLocalName()); + logger.log(Level.INFO, myAgent.getLocalName() + " " + msg.getContent()); + } else if (msg.getContent().startsWith(VOTEID)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); + + votingCode = Integer.parseInt(splittedMsg[1]); + minVotingValue = Integer.parseInt(splittedMsg[3]); + maxVotingValue = Integer.parseInt(splittedMsg[5]); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + informVotingRegistration(); + + ArrayList foundAgents = new ArrayList( + Arrays.asList(searchAgentByType("voter"))); + + ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); + msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); + + foundAgents.forEach(ag -> { + if ( !ag.getName().equals(myAgent.getAID()) ) { + msg2.addReceiver(ag.getName()); + } + }); + + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); ACLMessage reply = msg.createReply(); + reply.setContent(String.format("%s QUORUM %d", INFORM, foundAgents.size())); + myAgent.send(reply); + + send(msg2); + logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); + + + } else if (msg.getContent().startsWith(INVITE)) { + logger.log(Level.INFO, + String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); + + String [] splittedMsg = msg.getContent().split(" "); - public void action() { - ACLMessage msg = receive(); - - if ( msg == null ) block(); - else { - switch ( msg.getPerformative() ) { - case ACLMessage.INFORM: - addBehaviour(new HandleInform(msg)); - default: + votingCode = Integer.parseInt(splittedMsg[2]); + minVotingValue = Integer.parseInt(splittedMsg[4]); + maxVotingValue = Integer.parseInt(splittedMsg[6]); + + registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); + + informVotingRegistration(); + } else { logger.log(Level.INFO, - String.format("%s RECEIVED UNEXPECTED MESSAGE PERFORMATIVE FROM %s", getLocalName(), msg.getSender().getLocalName())); + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); } } - } + }; + + return handleInform; } - private class HandleInform extends OneShotBehaviour { - private static final long serialVersionUID = 1L; - private ACLMessage msg; - - private HandleInform (ACLMessage msg) { - this.msg = msg; - } - - public void action () { - if (REQUEST.equalsIgnoreCase(msg.getContent())) { - final int Max = 10; - final int Min = 1; + @Override + protected OneShotBehaviour handleRequest ( ACLMessage msg ) { + OneShotBehaviour handleRequest = new OneShotBehaviour(this) { + private static final long serialVersionUID = 1L; - // if a greetings message is arrived then send an ANSWER - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED REQUEST MESSAGE FROM " + msg.getSender().getLocalName()); - ACLMessage reply = msg.createReply(); - reply.setContent(ANSWER + " " + (Min + (int) (Math.random() * ((Max - Min) + 1)))); - myAgent.send(reply); - logger.log(Level.INFO, myAgent.getLocalName() + " SENT ANSWER MESSAGE"); - } else if (START.equalsIgnoreCase(msg.getContent())) { - ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); - msg2.setContent(START); - - DFAgentDescription [] foundAgents = searchAgentByType("mediator"); - - try { - AID foundMediator = null; - if ( foundAgents.length > 0 ) { - foundMediator = foundAgents[0].getName(); - - msg2.addReceiver(foundMediator); - - send(msg2); - logger.log(Level.INFO, String.format("%s SENT START MESSAGE TO %s", getLocalName(), foundMediator.getLocalName())); - } - } catch ( Exception any ) { - logger.log(Level.SEVERE, ANSI_RED + "ERROR WHILE SENDING MESSAGE" + ANSI_RESET); - any.printStackTrace(); - } - } else if (THANKS.equalsIgnoreCase(msg.getContent())) { - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED THANKS MESSAGE FROM " + msg.getSender().getLocalName()); - } else if (ODD.equalsIgnoreCase(msg.getContent().split(" ")[0]) - || EVEN.equalsIgnoreCase(msg.getContent().split(" ")[0])) { - logger.log(Level.INFO, myAgent.getLocalName() + " RECEIVED RESULTS MESSAGE FROM " + msg.getSender().getLocalName()); - logger.log(Level.INFO, myAgent.getLocalName() + " " + msg.getContent()); - } else if (msg.getContent().startsWith(VOTEID)) { - logger.log(Level.INFO, - String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); - - String [] splittedMsg = msg.getContent().split(" "); - - votingCode = Integer.parseInt(splittedMsg[1]); - minVotingValue = Integer.parseInt(splittedMsg[3]); - maxVotingValue = Integer.parseInt(splittedMsg[5]); - - registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - - informVotingRegistration(); - - ArrayList foundAgents = new ArrayList( - Arrays.asList(searchAgentByType("voter"))); - - ACLMessage msg2 = new ACLMessage(ACLMessage.INFORM); - msg2.setContent(String.format("%s %s", INVITE, msg.getContent())); - - foundAgents.forEach(ag -> { - if ( !ag.getName().equals(myAgent.getAID()) ) { - msg2.addReceiver(ag.getName()); - } - }); - - logger.log(Level.INFO, - String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); ACLMessage reply = msg.createReply(); - reply.setContent(String.format("%s QUORUM %d", INFORM, foundAgents.size())); - myAgent.send(reply); - - send(msg2); - logger.log(Level.INFO, String.format("%s SENT INVITE TO VOTERS!", getLocalName())); - - - } else if (msg.getContent().startsWith(INVITE)) { - logger.log(Level.INFO, - String.format("RECEIVED VOTING STRUCTURE FROM %s: %s", msg.getSender().getLocalName(), msg.getContent())); - - String [] splittedMsg = msg.getContent().split(" "); + public void action () { + if (msg.getContent().startsWith(REQUEST)) { + + myVotingValue = rand.nextInt(minVotingValue, maxVotingValue + 1); + + ACLMessage voteMsg = msg.createReply(); + voteMsg.setPerformative(ACLMessage.INFORM); + voteMsg.setContent(String.format("%s ON %d: %d", VOTE, votingCode, myVotingValue)); + + send(voteMsg); - votingCode = Integer.parseInt(splittedMsg[2]); - minVotingValue = Integer.parseInt(splittedMsg[4]); - maxVotingValue = Integer.parseInt(splittedMsg[6]); - - registerDF(myAgent, Integer.toString(votingCode), Integer.toString(votingCode)); - - informVotingRegistration(); - } else { - logger.log(Level.INFO, - String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); + logger.log(Level.INFO, String.format("%s SENT VOTE TO %s", getLocalName(), msg.getSender().getLocalName())); + } else { + logger.log(Level.INFO, + String.format("%s RECEIVED UNEXPECTED MESSAGE FROM %s", getLocalName(), msg.getSender().getLocalName())); + } } - } + }; + + return handleRequest; } - + private void informVotingRegistration() { ACLMessage informMsg = new ACLMessage(ACLMessage.INFORM); informMsg.setContent(String.format("%s IN %d", REGISTERED, votingCode));