package net.codjo.segmentation.server.blackboard; import net.codjo.agent.AclMessage; import net.codjo.agent.Aid; import net.codjo.agent.Behaviour; import net.codjo.agent.DFService; import net.codjo.agent.MessageTemplate; import static net.codjo.agent.MessageTemplate.and; import static net.codjo.agent.MessageTemplate.matchPerformative; import static net.codjo.agent.MessageTemplate.matchProtocol; import net.codjo.agent.protocol.InitiatorHandler; import net.codjo.agent.protocol.SubscribeInitiator; import net.codjo.agent.protocol.SubscribeProtocol; import net.codjo.segmentation.server.blackboard.message.BlackboardAction; import net.codjo.segmentation.server.blackboard.message.InformOfFailure; import net.codjo.segmentation.server.blackboard.message.Level; import net.codjo.segmentation.server.blackboard.message.MessageCodec; import net.codjo.segmentation.server.blackboard.message.Read; import net.codjo.segmentation.server.blackboard.message.Todo; import org.apache.log4j.Logger; /** * */ class ParticipantWrapperBehaviour extends Behaviour { private static final Logger LOG = Logger.getLogger(ParticipantWrapperBehaviour.class); private static final int MAX_TRY_COUNT = 100; private final BlackboardParticipant participant; private final Level listenedLevel; private final MessageTemplate requestTemplate; private boolean isStarting = true; private int searchBlackBoardTryCount = 0; private DFService.AgentDescription blackBoardDescription; private MessageCodec codec = new MessageCodec(); private Aid currentBlackBoardAid; private AclMessage receivedMessage; protected ParticipantWrapperBehaviour(BlackboardParticipant participant, Level level, DFService.AgentDescription blackBoardDescription) { this.participant = participant; this.listenedLevel = level; this.blackBoardDescription = blackBoardDescription; requestTemplate = and(matchPerformative(AclMessage.Performative.INFORM), matchProtocol(BlackboardBehaviour.BLACKBOARD_PROTOCOL)); } @Override protected final void action() { if (isStarting) { subscribeToBlackboards(); } else { listenRequestResponse(); } } private void subscribeToBlackboards() { try { DFService.AgentDescription[] descriptions = DFService.search(getAgent(), blackBoardDescription); if (descriptions.length == 0) { searchBlackBoardTryCount++; if (searchBlackBoardTryCount < MAX_TRY_COUNT) { block(100 * searchBlackBoardTryCount); return; } LOG.fatal("Impossible de trouver un blackboard"); getAgent().die(); return; } AclMessage subscribe = new AclMessage(AclMessage.Performative.SUBSCRIBE); subscribe.setProtocol(SubscribeProtocol.ID); subscribe.setContent(listenedLevel.getName()); for (DFService.AgentDescription description : descriptions) { subscribe.addReceiver(description.getAID()); } getAgent().addBehaviour( new SubscribeInitiator(getAgent(), new SubscriptionHandler(), subscribe)); isStarting = false; } catch (DFService.DFServiceException e) { LOG.fatal("Recherche d'un blackboard en erreur", e); getAgent().die(); } } private void listenRequestResponse() { AclMessage inform = getAgent().receive(requestTemplate); if (inform == null) { block(); return; } try { currentBlackBoardAid = inform.getSender(); Read read = codec.decodeRead(inform); receivedMessage = inform; Todo todo = null; Level level = null; try { todo = read.getTodo(); level = read.getLevel(); //noinspection unchecked participant.handleTodo(todo, level); } catch (Throwable e) { send(new InformOfFailure(todo, level).dueTo("Erreur : " + e.getLocalizedMessage())); throw e; } } catch (Throwable e) { LOG.error("Erreur lors de l'execution de la Todo :\n" + inform.toFipaACLString(), e); } } @Override public final boolean done() { return false; } void send(BlackboardAction action) { AclMessage request = new AclMessage(AclMessage.Performative.REQUEST); request.setProtocol(BlackboardBehaviour.BLACKBOARD_PROTOCOL); request.addReceiver(currentBlackBoardAid); codec.encode(request, action); getAgent().send(request); } public AclMessage getReceivedMessage() { return receivedMessage; } public Level getListenedLevel() { return listenedLevel; } public DFService.AgentDescription getBlackBoardDescription() { return blackBoardDescription; } static DFService.AgentDescription createDefaultBlackBoardDescription() { return new DFService.AgentDescription( new DFService.ServiceDescription(BlackboardBehaviour.BLACKBOARD_SERVICE)); } private class SubscriptionHandler implements InitiatorHandler { public void handleAgree(AclMessage agree) { currentBlackBoardAid = agree.getSender(); receivedMessage = agree; participant.handleConnectedToBlackBoard(agree); } public void handleRefuse(AclMessage refuse) { // Todo } public void handleInform(AclMessage inform) { currentBlackBoardAid = inform.getSender(); receivedMessage = inform; participant.handleTodoNotification(new Level(inform.getContent())); } public void handleFailure(AclMessage failure) { // Todo } public void handleOutOfSequence(AclMessage outOfSequenceMessage) { // Todo } public void handleNotUnderstood(AclMessage notUnderstoodMessage) { // Todo } } }