/* * codjo.net * * Common Apache License 2.0 */ package net.codjo.segmentation.server.plugin; import java.util.List; import net.codjo.agent.Behaviour; import net.codjo.agent.DFService; import net.codjo.aspect.AspectManager; import net.codjo.segmentation.server.blackboard.BlackboardBehaviour; import net.codjo.segmentation.server.blackboard.BlackboardListener; import net.codjo.segmentation.server.blackboard.message.Level; import net.codjo.segmentation.server.blackboard.message.Todo; import net.codjo.segmentation.server.participant.SegmentationLevels; import net.codjo.segmentation.server.participant.context.ContextManager; import net.codjo.segmentation.server.participant.context.SessionContext; import net.codjo.sql.server.JdbcServiceUtil; import net.codjo.workflow.common.message.Arguments; import net.codjo.workflow.common.message.JobAudit; import net.codjo.workflow.common.message.JobException; import net.codjo.workflow.common.message.JobRequest; import net.codjo.workflow.common.protocol.JobProtocolParticipant; import net.codjo.workflow.server.api.JobAgent; import org.apache.log4j.Logger; import static net.codjo.segmentation.server.participant.SegmentationParticipant.BLACKBOARD_SERVICE; import static net.codjo.segmentation.server.participant.SegmentationParticipant.SEGMENTATION_SERVICE; class SegmentationJobAgent extends JobAgent { private static final Logger LOG = Logger.getLogger(SegmentationJobAgent.class); SegmentationJobAgent(ContextManager manager, AspectManager aspectManager, JdbcServiceUtil jdbcServiceUtil) { this(manager, aspectManager, jdbcServiceUtil, MODE.NOT_DELEGATE); } SegmentationJobAgent(ContextManager manager, AspectManager aspectManager, JdbcServiceUtil jdbcServiceUtil, MODE mode) { super(mode); setAgentDescription(createAgentDescription()); SegmentationAspectParticipant aspectParticipant = new SegmentationAspectParticipant(jdbcServiceUtil, aspectManager); setJobProtocolParticipant(aspectParticipant); BlackboardBehaviour blackboard = new BlackboardBehaviour(SegmentationLevels.FIRST, SegmentationLevels.TO_DELETE, SegmentationLevels.TO_PAGINATE, SegmentationLevels.TO_COMPUTE, SegmentationLevels.INFORMATION, SegmentationLevels.FINAL); blackboard.doNotRegisterToDf(); addBehaviour(blackboard); MyGlueBehaviour glue = new MyGlueBehaviour(aspectParticipant, blackboard, manager, new CurrentSegmentationEnvironment()); getJobProtocolParticipant().setExecuteJobBehaviour(glue); blackboard.setListener(glue); } private static DFService.AgentDescription createAgentDescription() { DFService.AgentDescription description = new DFService.AgentDescription(); declareService(description, SEGMENTATION_SERVICE, "segmentation-service"); declareService(description, BLACKBOARD_SERVICE, "segmentation-blackboard"); return description; } private static void declareService(DFService.AgentDescription description, String service, String name) { description.addService(new DFService.ServiceDescription(service, name)); } private static class MyGlueBehaviour extends Behaviour implements BlackboardListener { private final JobProtocolParticipant aspectParticipant; private final BlackboardBehaviour blackboard; private final ContextManager manager; private final CurrentSegmentationEnvironment currentSegmentationEnvironment; private State state = State.POST_TODO; private StringBuffer errorMessage = null; private boolean isDone = false; MyGlueBehaviour(JobProtocolParticipant aspectParticipant, BlackboardBehaviour blackboard, ContextManager manager, CurrentSegmentationEnvironment environment) { this.aspectParticipant = aspectParticipant; this.blackboard = blackboard; this.manager = manager; this.currentSegmentationEnvironment = environment; } @Override protected void action() { JobRequest request = aspectParticipant.getRequest(); switch (state) { case POST_TODO: isDone = false; errorMessage = null; LOG.debug("SegmentationJobRequest recu"); if (currentSegmentationEnvironment.addTreatment(request)) { blackboard.setUserId(aspectParticipant.getRequestMessage().decodeUserId()); blackboard.postTodo(SegmentationLevels.FIRST, new Todo<JobRequest>(request)); LOG.debug("SegmentationJobRequest ajout�"); } else { LOG.debug("SegmentationJobRequest refus�"); blackboard.setUserId(aspectParticipant.getRequestMessage().decodeUserId()); blackboard.postTodo(SegmentationLevels.FIRST, new Todo<JobRequest>(null)); errorMessage = new StringBuffer( "Lancement impossible car il y a une segmentation en cours par "); errorMessage.append(currentSegmentationEnvironment.getUserForJobRequest( request)); errorMessage.append(" avec le(s) parametre(s) : "); errorMessage.append(request.getArguments().toString()); } state = State.RUNNING; block(); break; case RUNNING: block(); break; case DECLARE_JOB_DONE: LOG.debug("DECLARE_JOB_DONE : Request trait�e"); finalizeJob(request); isDone = true; state = State.POST_TODO; manager.remove(request.getId()); currentSegmentationEnvironment.removeTreatment(request); if (errorMessage == null) { aspectParticipant.declareJobDone(); } else { //noinspection ThrowableInstanceNeverThrown aspectParticipant.declareJobDone(new JobException(errorMessage.toString())); errorMessage = null; } break; } } private void finalizeJob(JobRequest request) { if ((manager != null) && (request != null)) { SessionContext sessionContext = manager.getSessionContext(request.getId()); if (sessionContext != null) { // close the report if (sessionContext.getReport() != null) { try { sessionContext.getReport().close(); } catch (Exception e) { LOG.error("An error has happened while closing the report", e); } } // if (sessionContext.getErrorLogLimiter() != null) { try { sessionContext.getErrorLogLimiter().close(); } catch (Exception e) { LOG.error("An error has happened while closing the error log limiter", e); } } } } } @Override public boolean done() { return isDone; } public void todoWrited(Level level, Todo todo) { if (level.equals(SegmentationLevels.INFORMATION)) { blackboard.removeTodo(level, todo); JobAudit jobAudit = new JobAudit(JobAudit.Type.MID); jobAudit.setArguments((Arguments)todo.getContent()); aspectParticipant.sendAudit(jobAudit); } } public void informOfFailure(Level level, Todo todo, String error) { if (errorMessage == null) { errorMessage = new StringBuffer("Erreur rencontr�e lors de la segmentation"); } errorMessage.append("\n\t").append(error) .append("\n\n* Localisation : ").append(level) .append("\n* todo(").append(todo.getContent()).append(")"); blackboard.removeTodo(level, todo); } public void blackboardFinished(List<Todo> lastTodos) { state = State.DECLARE_JOB_DONE; restart(); } } enum State { POST_TODO, RUNNING, DECLARE_JOB_DONE } }