/* * MockAlbusHCSMessageHandler.java * * Created on Feb 3, 2010, 11:33:07 PM * * Description: A channel handler that transports messages from node to node in an Albus hierarchical control network. * * Copyright (C) Feb 3, 2010 reed. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.texai.network.netty.handler; import java.util.UUID; import net.jcip.annotations.NotThreadSafe; import org.apache.log4j.Logger; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.joda.time.DateTime; import org.texai.ahcsSupport.Message; import org.texai.util.TexaiException; /** A channel handler that transports messages from node to node in an Albus hierarchical control network. * * @author reed */ @NotThreadSafe public final class MockAlbusHCSMessageHandler extends AbstractAlbusHCSMessageHandler { /** the logger */ private static final Logger LOGGER = Logger.getLogger(MockAlbusHCSMessageHandler.class); /** the lock that allows the client to resume when the messaging is done */ final Object clientResume_lock; /** the test iteration limit */ final int iterationLimit; /** Constructs a new MockAlbusHCSMessageHandler instance. * * @param clientResume_lock the lock that allows the client to resume when the messaging is done, or * null if this is the client side handler * @param iterationLimit the test iteration limit */ public MockAlbusHCSMessageHandler(final Object clientResume_lock, final int iterationLimit) { //Preconditions assert iterationLimit >= 0 : "iterationLimit must not be negative"; this.clientResume_lock = clientResume_lock; this.iterationLimit = iterationLimit; } /** Receives a message object from a remote peer. * * @param channelHandlerContext the channel handler context * @param messageEvent the message event */ @Override public void messageReceived( final ChannelHandlerContext channelHandlerContext, final MessageEvent messageEvent) { //Preconditions assert channelHandlerContext != null : "channelHandlerContext must not be null"; assert messageEvent != null : "messageEvent must not be null"; final boolean isClient = clientResume_lock != null; if (isClient) { LOGGER.info("client received messageEvent: " + messageEvent); } else { LOGGER.info("server received messageEvent: " + messageEvent); } final Channel channel = channelHandlerContext.getChannel(); assert messageEvent.getMessage() instanceof Message; final Message message = (Message) messageEvent.getMessage(); int count = (Integer) message.get("count"); LOGGER.info("count: " + count); if (message.getOperation().equals("Echo_Task")) { // increment the count and send a repsonse message back to the sender final Message responseMessage = new Message( message.getSenderRoleId(), "TestSenderService", message.getRecipientRoleId(), message.getConversationId(), UUID.randomUUID(), // replyWith message.getReplyWith(), new DateTime(), // replyByDateTime "TestService", "Response_Task", message.getParameterDictionary(), "1.0.0"); // version count++; responseMessage.put("count", count); LOGGER.info("about to write message " + responseMessage + "\nto channel pipeline" + channel.getPipeline()); channel.write(responseMessage); } else { assert isClient; if (count > iterationLimit) { // signal the client thread to finish synchronized (clientResume_lock) { clientResume_lock.notifyAll(); } } else { // send another request message final Message echoMessage = new Message( message.getSenderRoleId(), "TestSenderService", message.getRecipientRoleId(), message.getConversationId(), UUID.randomUUID(), // replyWith message.getReplyWith(), new DateTime(), // replyByDateTime message.getSenderService(), "Echo_Task", message.getParameterDictionary(), "1.0.0"); // version channel.write(echoMessage); } } } /** Writes a message object to a remote peer. * * @param channelHandlerContext the channel handler context * @param messageEvent the message event */ @Override public void writeRequested( final ChannelHandlerContext channelHandlerContext, final MessageEvent messageEvent) { //Preconditions assert channelHandlerContext != null : "channelHandlerContext must not be null"; assert messageEvent != null : "messageEvent must not be null"; LOGGER.info("write requested messageEvent: " + messageEvent); LOGGER.info("pipeline: " + channelHandlerContext.getPipeline().toString()); channelHandlerContext.sendDownstream(messageEvent); } /** Handles a caught exception. * * @param channelHandlerContext the channel handler event * @param exceptionEvent the exception event */ @Override public void exceptionCaught( final ChannelHandlerContext channelHandlerContext, final ExceptionEvent exceptionEvent) { //Preconditions assert channelHandlerContext != null : "channelHandlerContext must not be null"; assert exceptionEvent != null : "exceptionEvent must not be null"; if (clientResume_lock == null) { LOGGER.error("server exceptionEvent: " + exceptionEvent); } else { LOGGER.error("client exceptionEvent: " + exceptionEvent); } throw new TexaiException(exceptionEvent.getCause()); } }