camelagent.AgentConsumer.java Source code

Java tutorial

Introduction

Here is the source code for camelagent.AgentConsumer.java

Source

///////////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013 Cranefield S., Ranathunga S. All rights reserved.               /
// ---------------------------------------------------------------------------------- /
// This file is part of camel_jason.                                                  /

//    camel_jason is free software: you can redistribute it and/or modify             /
//   it under the terms of the GNU Lesser General Public License as published by      /
//    the Free Software Foundation, either version 3 of the License, or               /
//    (at your option) any later version.                                             /

//    camel_jason is distributed in the hope that it will be useful,                  /
//    but WITHOUT ANY WARRANTY; without even the implied warranty of                  /
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   /
//    GNU Lesser General Public License for more details.                             /

//    You should have received a copy of the GNU Lesser General Public License        /
//    along with camel_jason.  If not, see <http://www.gnu.org/licenses/>.            /  
///////////////////////////////////////////////////////////////////////////////////////

package camelagent;

import jason.asSemantics.ActionExec;
import jason.asSemantics.Message;
import jason.asSemantics.Unifier;
import jason.asSyntax.ListTerm;
import jason.asSyntax.Term;
import jason.asSyntax.Literal;
import jason.asSyntax.ASSyntax;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.impl.DefaultConsumer;
import org.apache.commons.lang.StringUtils;

/**
 * @author surangika
 * Contains the Jason-specific implementation of the Camel Consumer component 
 *
 */
public class AgentConsumer extends DefaultConsumer {
    private final AgentEndpoint endpoint;

    public AgentConsumer(AgentEndpoint endpoint, Processor processor) {
        super(endpoint, processor);
        this.endpoint = endpoint;
    }

    /**
     * @param agentName
     * @param actionName
     * @param parameters
     * @param unifier
     * @return
     * Maps internal Jason agent actions to camel messages
     */
    public Object agentInternallyActed(String agentName, String actionName, List<Term> parameters,
            Unifier unifier) {
        Object actionsucceeded = true;
        Exchange exchange = endpoint.createExchange();

        // Agent action can only be processed by an endpoint of type "action"
        if (endpoint.getUriOption().contains("action")) {

            try {

                List<String> paramsAsStrings = new ArrayList<String>();
                for (Term t : parameters) {
                    paramsAsStrings.add(t.toString());
                }
                sendActionToCamel(agentName, actionName, paramsAsStrings, exchange, "");

            } catch (Exception e) {

            } finally {

                // log exception if an exception occurred and was not handled
                if (exchange.getException() != null) {
                    getExceptionHandler().handleException("Error processing exchange", exchange,
                            exchange.getException());
                    actionsucceeded = false;
                } else {
                    String ep = endpoint.getExchangePattern().toString();
                    //Just send out camel message and inform success to agent
                    if (ep.equals("InOnly"))
                        actionsucceeded = true;

                    //Unification is applicable to InOut exchanges only. This waits for the return message from the exchange 
                    else if (ep.equals("InOut")) {
                        if (exchange.hasOut()) {
                            List<String[]> mappings = getResultHeaderSplitted();
                            for (String[] mapping : mappings) {
                                int unPos = Integer.parseInt(mapping[1]);
                                String headerVal = mapping[0];

                                //ArrayList<String> l = (ArrayList<String>)exchange.getIn().getHeader(headerVal);
                                //Iterator<String> it = l.iterator();
                                String unVal = exchange.getIn().getHeader(headerVal).toString();
                                try {
                                    unifier.unifies(parameters.get(unPos), ASSyntax.parseTerm(unVal));
                                } catch (jason.asSyntax.parser.ParseException e) {
                                    System.out.println(
                                            "Error parsing result header from synchronous InOut action: " + unVal);
                                    return false;
                                }
                            }
                            return true;
                        } else
                            actionsucceeded = false;
                    }
                }
            }
        }
        return actionsucceeded;
    }

    /**
     * @param jasonAction
     * @return
     * Maps external Jason agent actions to camel messages
     */
    public boolean agentActed(JasonAction jasonAction) {
        boolean actionsucceeded = true;
        Exchange exchange = endpoint.createExchange();
        if (endpoint.getUriOption().contains("action")) {
            try {
                ActionExec action = jasonAction.getAction();

                String agName = jasonAction.getAgName();
                List<String> paramsAsStrings = new ArrayList<String>();
                for (Term t : action.getActionTerm().getTerms())
                    paramsAsStrings.add(t.toString());

                //extract annotations
                List<Term> ann = action.getActionTerm().getAnnots();
                String annots = "";
                if (ann != null)
                    annots = ann.toString();//StringUtils.join(ann, ',');          
                exchange.getIn().setBody(action.getActionTerm().toString(), String.class);
                sendActionToCamel(agName, action.getActionTerm().getFunctor(), paramsAsStrings, exchange, annots);

            } catch (Exception e) {

            } finally {

                // log exception if an exception occurred and was not handled
                if (exchange.getException() != null) {
                    getExceptionHandler().handleException("Error processing exchange", exchange,
                            exchange.getException());
                    actionsucceeded = false;
                } else {
                    String ep = endpoint.getExchangePattern().toString();

                    //Just send out camel message and inform success to agent
                    if (ep.equals("InOnly"))
                        actionsucceeded = true;
                    else if (ep.equals("InOut")) {
                        if (exchange.getOut() != null)
                            actionsucceeded = true;
                        else
                            actionsucceeded = false;
                    }
                }
            }
        }
        return actionsucceeded;
    }

    /**
     * @param message
     * Converts Jason Message to a camel Message and add to the exchange
     */
    public void agentMessaged(Message message) {
        Exchange exchange = endpoint.createExchange();

        if (endpoint.getUriOption().contains("message")) {
            try {
                String ei = endpoint.getIlloc_force();
                String es = endpoint.getSender();
                String er = endpoint.getReceiver();

                //create message header
                HashMap<String, Object> headerInfo = new HashMap<String, Object>();
                String s = message.getSender();
                String r = message.getReceiver();
                String i = message.getIlForce();
                headerInfo.put("sender", s);
                headerInfo.put("receiver", r);
                headerInfo.put("illoc_force", i);
                headerInfo.put("msg_id", message.getMsgId());

                //Extract out any annotations and add as "annotations" header
                try {
                    Literal lit = (Literal) message.getPropCont();
                    if (lit != null) {
                        ListTerm lt = lit.getAnnots();
                        if (lt != null)
                            headerInfo.put("annotations", StringUtils.join(lit.getAnnots(), ','));
                    } else
                        headerInfo.put("annotations", "");
                } catch (ClassCastException e) {
                }

                //COmpare the message content with uri options
                Matcher matcher = endpoint.getBodyMatcher(message.getPropCont().toString());

                exchange.getIn().setHeaders(headerInfo);

                // send message to next processor in the route after checking route conditions
                if ((i.equals(ei) || ei == null) && (s.equals(es) || es == null) || (r.equals(er) || er == null))
                    processMatchedMessage(matcher, exchange, message.getPropCont().toString());

            } catch (Exception e) {

            } finally {
                // log exception if an exception occurred and was not handled
                if (exchange.getException() != null)
                    getExceptionHandler().handleException("Error processing exchange", exchange,
                            exchange.getException());
                else {
                    String ep = endpoint.getExchangePattern().toString();
                    if (ep.equals("InOut")) { /*               
                                              if (exchange.getOut() != null)
                                              {
                                               Message m = new Message();
                                              } */
                    }
                }
            }
        }
    }

    /**
     * @param matcher
     * @param exchange
     * @param messageBody
     * @throws Exception
     * Sends out the camel message only if the uri information is matched with the message content
     */
    private void processMatchedMessage(Matcher matcher, Exchange exchange, String messageBody) throws Exception {
        if (matcher == null) {
            exchange.getIn().setBody(messageBody);
            getProcessor().process(exchange);
        } else if (matcher.matches()) {
            exchange.getIn().setBody(endpoint.getReplacedContent(matcher, messageBody));
            getProcessor().process(exchange);
        }
    }

    /**
     * @return List<String[]>
     * Auxiliary method to interpret the result values sent back for agent actions
     */
    private List<String[]> getResultHeaderSplitted() {

        List<String[]> mappings = new ArrayList<String[]>();
        if (endpoint.getResultHeaderMap() != null) {
            String[] temp = endpoint.getResultHeaderMap().split(",");
            for (String s : temp)
                mappings.add(s.split(":"));
            return mappings;
        } else
            return null;
    }

    /**
     * @param agName
     * @param actionName
     * @param paramsAStrings
     * @param exchange
     * @param annotations
     * @throws Exception
     * Contains common logic to send internal and external actions as camel messages
     */
    private void sendActionToCamel(String agName, String actionName, List<String> paramsAsStrings,
            Exchange exchange, String annotations) throws Exception {
        //create action header
        HashMap<String, Object> headerInfo = new HashMap<String, Object>();
        headerInfo.put("actor", agName);
        headerInfo.put("actionName", actionName);
        headerInfo.put("params", paramsAsStrings);
        headerInfo.put("annotations", annotations);
        exchange.getIn().setHeaders(headerInfo);

        String ea = endpoint.getActor();
        String ean = endpoint.getActionName();
        String match = endpoint.getMatch();

        boolean matchOk = true;
        if (match != null) {
            Pattern pattern = Pattern.compile(match);
            Matcher matcher = pattern.matcher(actionName);
            matchOk = matcher.find();
        }

        if ((agName.equals(ea) || ea == null) && (actionName.equals(ean) || ean == null) && matchOk) {
            if (endpoint.getReplace() != null)
                headerInfo.put("actionName", endpoint.getReplace());
            getProcessor().process(exchange);
        }
    }
}