The Contract Net Protocol (CNP)

A CNP Initiator

public class CNIAgent extends Agent {

   int bestOffer = 50; // max price I will pay

   public void setup() {
      ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
      cfp.setProtocol(
         FIPANames.InteractionProtocol.FIPA_CONTRACT_NET);
      cfp.setContent("we must have whiskey or we'll die");
      AID[] providers = DFUtils.searchDF(this, "whiskey");
      for(int i = 0; i < providers.length; i++) {
         cfp.addReceiver(providers[i]);
      }
      addBehaviour(new CNIBehavior(this, cfp));
   }
}

Behavior

class CNIBehavior extends ContractNetInitiator {
   public CNIBehavior(Agent a, ACLMessage cfp) { super(a, cfp); }

   protected void handlePropose(ACLMessage msg, Vector acceptances) {
      int offer = Integer.parseInt( msg.getContent());
      System.out.println("CNI considering an offer for $" + offer);
      CNIAgent myCNIAgent = (CNIAgent)myAgent;
      ACLMessage response = msg.createReply();
      if (offer < myCNIAgent.bestOffer) {
         myCNIAgent.bestOffer = offer;
         response.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
         response.setContent("it's a deal!");
      } else {
         response.setPerformative(ACLMessage.REJECT_PROPOSAL);
         response.setContent("you gotta be kidding!");
      }
      acceptances.add(response);
   }
   protected void handleInform(ACLMessage msg) {
      System.out.println("Inform received: " + msg.getContent());
   }
   protected void handleRefuse(ACLMessage msg) {
      System.out.println("Refusal received: " + msg.getContent());
   }
   protected void handleFailure(ACLMessage msg) {
      System.out.println("Failure received: " + msg.getContent());
   }
}

A CNP Responder

public class CNRAgent extends Agent {

   Random generator = new Random();
   int price = generator.nextInt(70);

   public void setup() {

      DFAgentDescription dfd = new DFAgentDescription();
      dfd.setName(getAID());

      ServiceDescription service  = new ServiceDescription();
         service.setType( "whiskey" );
         service.setName( getLocalName() );

        try {
        DFAgentDescription list[] = DFService.search( this, dfd );
         if ( list.length > 0 ) DFService.deregister(this);
            dfd.addServices(service);
         DFService.register(this, dfd);
      }
        catch (FIPAException fe) {
         System.err.println(fe.getMessage());
      }

      MessageTemplate mt =
         ContractNetResponder.createMessageTemplate(
           FIPANames.InteractionProtocol.FIPA_CONTRACT_NET);
      addBehaviour(new CNRBehavior(this, mt));
   }
}

Behavior

class CNRBehavior extends ContractNetResponder {
   public CNRBehavior(Agent a, MessageTemplate mt) { super(a, mt); }

   protected  ACLMessage prepareResponse(ACLMessage msg)
      throws NotUnderstoodException, RefuseException {
         System.out.println("cfp  received: " + msg.getContent());

          ACLMessage response = msg.createReply();
         response.setPerformative(ACLMessage.PROPOSE);
         response.setContent("" + ((CNRAgent)myAgent).price);
         return response;
   }
   protected  ACLMessage prepareResultNotification(
      ACLMessage cfp, ACLMessage propose, ACLMessage accept) {
         System.out.println(
            "acceptance received: " + accept.getContent());
         ACLMessage response = accept.createReply();
         response.setPerformative(ACLMessage.INFORM);
         response.setContent("your whiskey is on its way!");
         return response;
   }

   protected  void handleRejectProposal(
      ACLMessage cfp, ACLMessage propose, ACLMessage reject) {
         System.out.println(
            "rejection received: " + reject.getContent());
   }
}

Output

cfp  received: we must have whiskey or we'll die
cfp  received: we must have whiskey or we'll die
cfp  received: we must have whiskey or we'll die
cfp  received: we must have whiskey or we'll die
CNI considering an offer for $53
CNI considering an offer for $54
CNI considering an offer for $19
CNI considering an offer for $14
rejection received: you gotta be kidding!
rejection received: you gotta be kidding!
acceptance received: it's a deal!
acceptance received: it's a deal!
Inform received: your whiskey is on its way!
Inform received: your whiskey is on its way!