Package org.mokai.impl.camel.test

Source Code of org.mokai.impl.camel.test.CamelConnectorServiceTest

package org.mokai.impl.camel.test;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.component.mock.MockEndpoint;
import org.mockito.Mockito;
import org.mokai.Acceptor;
import org.mokai.Action;
import org.mokai.Configurable;
import org.mokai.Connector;
import org.mokai.ConnectorContext;
import org.mokai.ConnectorService;
import org.mokai.Execution;
import org.mokai.ExecutionException;
import org.mokai.Message;
import org.mokai.Message.Direction;
import org.mokai.MessageProducer;
import org.mokai.Monitorable;
import org.mokai.Monitorable.Status;
import org.mokai.Processor;
import org.mokai.Service;
import org.mokai.Service.State;
import org.mokai.Serviceable;
import org.mokai.annotation.Resource;
import org.mokai.impl.camel.AbstractCamelConnectorService;
import org.mokai.impl.camel.ResourceRegistry;
import org.mokai.persist.MessageStore;
import org.mokai.types.mock.MockAcceptor;
import org.mokai.types.mock.MockConnector;
import org.testng.annotations.Test;

/**
*
* @author German Escobar
*/
public class CamelConnectorServiceTest extends CamelBaseTest {

  private final String PROCESSED_MESSAGES_URI = "mock:processedMessages";
  private final String FAILED_MESSAGES_URI = "mock:failedMessages";
  private final String RECEIVED_MESSAGES_URI = "mock:receivedRouter";

  private final long DEFAULT_TIMEOUT = 3000;

  @Test
  public void testProcessMessage() throws Exception {
    // add processed validation
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(1);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    MockProcessor processor = new MockProcessor();
    ConnectorService connectorService = new MockConnectorService("test", processor, resourceRegistry);
    connectorService.start();

    Assert.assertEquals(Status.UNKNOWN, connectorService.getStatus());

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(Status.UNKNOWN, connectorService.getStatus());
    Assert.assertEquals(1, processor.getCount());

    Message message = (Message) processor.getMessage(0);
    Assert.assertNotNull(message);
    Assert.assertEquals("test", message.getDestination());
  }

  @Test
  public void testConnectorServiceState() throws Exception {
    Connector connector = Mockito.mock(Connector.class);
    ConnectorService processorService = new MockConnectorService("test", connector, resourceRegistry);
    Assert.assertEquals(State.STOPPED, processorService.getState());

    processorService.start();
    Assert.assertEquals(State.STARTED, processorService.getState());

    processorService.stop();
    Assert.assertEquals(State.STOPPED, processorService.getState());
  }

  /**
   * Tests that a failed processor recovers after it process a good message
   * @throws Exception
   */
  @Test
  public void testProcessorStatus() throws Exception {
    // add failed validation
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(1);

    Processor processor = Mockito.mock(Processor.class);
    Mockito
      .doThrow(new NullPointerException())
      .when(processor).process(Mockito.any(Message.class));

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    // check that the status is UNKNOWN
    Assert.assertEquals(Status.UNKNOWN, processorService.getStatus());

    // simulate the message
    simulateMessage(new Message(), "activemq:mokai-test");

    // wait until the message fails
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    // check that the status is FAILED
    Assert.assertEquals(Status.FAILED, processorService.getStatus());

    // add processed validation
    outboundEndpoint.reset();
    outboundEndpoint.expectedMessageCount(1);
    failedEndpoint.reset();
    failedEndpoint.expectedMessageCount(0);

    Mockito.doNothing()
      .when(processor)
      .process(Mockito.any(Message.class));

    // simulate the message
    simulateMessage(new Message(), "activemq:mokai-test");

    // wait until the message is processed
    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    // check that the status is back to UNKNOWN
    Assert.assertEquals(Status.UNKNOWN, processorService.getStatus());
  }

  /**
   * Tests a Monitorable Processor with an OK status.
   *
   * @throws Exception
   */
  @Test
  public void testMonitorableProcessorStatus() throws Exception {
    // add processed validation
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(1);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    Processor processor =
      Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Monitorable.class));
    Mockito
      .when(((Monitorable) processor).getStatus())
      .thenReturn(Status.OK);

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    Assert.assertEquals(Status.OK, processorService.getStatus());

    // simulate the message
    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(Status.OK, processorService.getStatus());
  }

  @Test
  public void testFailedMonitorableProcessorStatus() throws Exception {
    // add processed validation
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(1);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    Processor processor =
      Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Monitorable.class));
    Mockito
      .when(((Monitorable) processor).getStatus())
      .thenReturn(Status.FAILED);

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    Assert.assertEquals(Status.FAILED, processorService.getStatus());

    // simulate the message
    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(Status.FAILED, processorService.getStatus());
  }

  @Test
  public void testConflictMonitorableProcessorStatus() throws Exception {
    // add failed validation
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(1);

    Processor processor =
      Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Monitorable.class));
    Mockito
      .doThrow(new NullPointerException())
      .when(processor).process(Mockito.any(Message.class));
    Mockito
      .when(((Monitorable) processor).getStatus())
      .thenReturn(Status.OK);

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();
    Assert.assertEquals(Status.OK, processorService.getStatus());

    // simulate the message
    simulateMessage(new Message(), "activemq:mokai-test");

    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(Status.FAILED, processorService.getStatus());
  }

  @Test
  public void testReceiveMessage() throws Exception {
    // validation route
    MockEndpoint inboundEndpoint = getReceivedMessagesEndpoint(1);

    SimpleReceiverProcessor processor = new SimpleReceiverProcessor();
    new MockConnectorService("test", processor, resourceRegistry).start();

    // simulate receiving message
    processor.receiveMessage(new Message());

    // validate results
    inboundEndpoint.assertIsSatisfied();

    Exchange exchange = inboundEndpoint.getReceivedExchanges().iterator().next();
    Message message = exchange.getIn().getBody(Message.class);

    Assert.assertNotNull(message.getReference());
    Assert.assertEquals("test", message.getSource());
    Assert.assertEquals(Message.Direction.UNKNOWN, message.getDirection());
  }

  /**
   * Tests that processing actions (pre and post) are working
   * @throws Exception
   */
  @Test
  public void testProcessingActions() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(1);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    // add a pre-processing action
    MockAction preProcessingAction = new MockAction();
    processorService.addPreProcessingAction(preProcessingAction);

    // add another pre-processing action that changes the message
    processorService.addPreProcessingAction(new Action() {

      @Override
      public void execute(Message message) throws Exception {
        Message smsMessage = (Message) message;
        smsMessage.setProperty("from", "1234");
      }

    });

    // add a post-processing action
    MockAction postProcessingAction = new MockAction();
    processorService.addPostProcessingAction(postProcessingAction);

    // add another post-processing action that changes the message
    processorService.addPostProcessingAction(new Action() {

      @Override
      public void execute(Message message) throws Exception {
        Message smsMessage = (Message) message;
        smsMessage.setProperty("to", "1111");
      }

    });

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(1, processor.getCount());
    Assert.assertEquals(1, preProcessingAction.getChanged());
    Assert.assertEquals(1, postProcessingAction.getChanged());

    Message message = (Message) processor.getMessage(0);
    Assert.assertEquals("1234", message.getProperty("from", String.class));
    Assert.assertEquals("1111", message.getProperty("to", String.class));
  }

  @Test
  public void testPostReceivingActions() throws Exception {
    // validation route
    MockEndpoint inboundEndpoint = getReceivedMessagesEndpoint(1);

    SimpleReceiverProcessor processor = new SimpleReceiverProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    // add post-receiving action
    MockAction postReceivingAction = new MockAction();
    processorService.addPostReceivingAction(postReceivingAction);

    // add another post-receiving action that changes the message
    processorService.addPostReceivingAction(new Action() {

      @Override
      public void execute(Message message) throws Exception {
        message.setReference("germanescobar");
      }

    });

    // simulate we receive a message
    processor.receiveMessage(new Message());

    // validate results
    inboundEndpoint.assertIsSatisfied();
    Assert.assertEquals(1, postReceivingAction.getChanged());

    Exchange exchange = inboundEndpoint.getReceivedExchanges().iterator().next();
    Message message = exchange.getIn().getBody(Message.class);

    Assert.assertEquals("germanescobar", message.getReference());
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithoutResourceRegistry() throws Exception {
    MockProcessor processor = new MockProcessor();
    new MockConnectorService("test", processor, null);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithoutCamelContext() throws Exception {
    // an empty resource registry
    ResourceRegistry resourceRegistry = new ResourceRegistry();

    MockProcessor processor = new MockProcessor();
    new MockConnectorService("test", processor, resourceRegistry);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullConnector() throws Exception {
    new MockConnectorService("test", null, resourceRegistry);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullId() throws Exception {
    new MockConnectorService(null, new MockProcessor(), resourceRegistry);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullAcceptor() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);
    processorService.addAcceptor(null);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithEmptyId() throws Exception {
    new MockConnectorService("", new MockProcessor(), resourceRegistry);
  }

  @Test
  public void testIdWithSpaces() throws Exception {
    ConnectorService processorService = new MockConnectorService("T e s T", new MockProcessor(), resourceRegistry);
    Assert.assertEquals("test", processorService.getId());
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullPreProcessingAction() throws Exception {
    AbstractCamelConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);
    processorService.addPreProcessingAction(null);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullPostProcessingAction() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);
    processorService.addPostProcessingAction(null);
  }

  @Test(expectedExceptions=IllegalArgumentException.class)
  public void shouldFailWithNullPostReceivingAction() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);
    processorService.addPostReceivingAction(null);
  }

  /**
   * Tests that if an exception occurs in the processor, the message is sent to the failedMessages queue.
   * @throws Exception
   */
  @Test
  public void testProcessorException() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(1);

    AbstractCamelConnectorService processorService = new MockConnectorService("test", new Processor() {

      @Override
      public void process(Message message) {
        throw new NullPointerException();
      }

      @Override
      public boolean supports(Message message) {
        return true;
      }

    }, resourceRegistry);
    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Exchange exchange = failedEndpoint.getReceivedExchanges().iterator().next();
    Message smsMessage = exchange.getIn().getBody(Message.class);

    Assert.assertEquals("test", smsMessage.getDestination());
    Assert.assertEquals(Message.STATUS_FAILED, smsMessage.getStatus());
  }

  @Test
  public void testProcessorExceptionAndRecovery() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(1);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    ConnectorService processorService = new MockConnectorService("test", new Processor() {

      private int times = 0;

      @Override
      public void process(Message message) {
        if (times == 0) {
          times++;
          throw new NullPointerException();
        }
      }

      @Override
      public boolean supports(Message message) {
        return true;
      }

    }, resourceRegistry);
    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
  }

  @Test
  public void testAddRemoveAcceptors() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);

    Acceptor acceptor1 = Mockito.mock(Acceptor.class);
    Acceptor acceptor2 = Mockito.mock(Acceptor.class);

    // add first acceptor
    processorService.addAcceptor(acceptor1);
    Assert.assertEquals(1, processorService.getAcceptors().size());

    // add second acceptor
    processorService.addAcceptor(acceptor2);
    Assert.assertEquals(2, processorService.getAcceptors().size());

    List<Acceptor> acceptors = processorService.getAcceptors();
    Assert.assertEquals(acceptors.get(0), acceptor1);
    Assert.assertEquals(acceptors.get(1), acceptor2);

    // remove acceptor 1
    processorService.removeAcceptor(acceptor1);

    Assert.assertEquals(1, processorService.getAcceptors().size());
    acceptors = processorService.getAcceptors();
    Assert.assertEquals(acceptors.get(0), acceptor2);
  }

  @Test
  public void testAddRemovePreProcessingActions() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);

    Action action1 = new MockAction();
    Action action2 = new MockAction();

    // add first action
    processorService.addPreProcessingAction(action1);
    Assert.assertEquals(1, processorService.getPreProcessingActions().size());

    // add second action
    processorService.addPreProcessingAction(action2);
    Assert.assertEquals(2, processorService.getPreProcessingActions().size());

    List<Action> preProcessingActions  = processorService.getPreProcessingActions();
    Assert.assertEquals(preProcessingActions.get(0), action1);
    Assert.assertEquals(preProcessingActions.get(1), action2);

    // remove action 1
    processorService.removePreProcessingAction(action1);

    Assert.assertEquals(1, processorService.getPreProcessingActions().size());
    preProcessingActions  = processorService.getPreProcessingActions();
    Assert.assertEquals(preProcessingActions.get(0), action2);
  }

  @Test
  public void testAddRemovePostProcessingActions() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);

    Action action1 = new MockAction();
    Action action2 = new MockAction();

    // add first action
    processorService.addPostProcessingAction(action1);
    Assert.assertEquals(1, processorService.getPostProcessingActions().size());

    // add second action
    processorService.addPostProcessingAction(action2);
    Assert.assertEquals(2, processorService.getPostProcessingActions().size());

    List<Action> postProcessingActions  = processorService.getPostProcessingActions();
    Assert.assertEquals(postProcessingActions.get(0), action1);
    Assert.assertEquals(postProcessingActions.get(1), action2);

    // remove action 1
    processorService.removePostProcessingAction(action1);

    Assert.assertEquals(1, processorService.getPostProcessingActions().size());
    postProcessingActions  = processorService.getPostProcessingActions();
    Assert.assertEquals(postProcessingActions.get(0), action2);
  }

  @Test
  public void testAddRemovePostReceivingActions() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", new MockProcessor(), resourceRegistry);

    Action action1 = new MockAction();
    Action action2 = new MockAction();

    // add first action
    processorService.addPostReceivingAction(action1);
    Assert.assertEquals(1, processorService.getPostReceivingActions().size());

    // add second action
    processorService.addPostReceivingAction(action2);
    Assert.assertEquals(2, processorService.getPostReceivingActions().size());

    List<Action> postReceivingActions  = processorService.getPostReceivingActions();
    Assert.assertEquals(postReceivingActions.get(0), action1);
    Assert.assertEquals(postReceivingActions.get(1), action2);

    // remove action 1
    processorService.removePostReceivingAction(action1);

    Assert.assertEquals(1, processorService.getPostReceivingActions().size());
    postReceivingActions  = processorService.getPostReceivingActions();
    Assert.assertEquals(postReceivingActions.get(0), action2);
  }

  @Test
  public void testAddRemoveConfigurableAcceptor() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", Mockito.mock(Processor.class), resourceRegistry);

    Acceptor configurableAcceptor = Mockito.mock(Acceptor.class,
        Mockito.withSettings().extraInterfaces(Configurable.class));

    processorService.addAcceptor(configurableAcceptor);
    processorService.removeAcceptor(configurableAcceptor);

    Mockito.verify((Configurable) configurableAcceptor).configure();
    Mockito.verify((Configurable) configurableAcceptor).destroy();
  }

  @Test
  public void testAddRemoveConfigurablePreProcessingAction() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", Mockito.mock(Processor.class), resourceRegistry);

    Action configurableAction = Mockito.mock(Action.class,
        Mockito.withSettings().extraInterfaces(Configurable.class));

    processorService.addPreProcessingAction(configurableAction);
    processorService.removePreProcessingAction(configurableAction);

    Mockito.verify((Configurable) configurableAction).configure();
    Mockito.verify((Configurable) configurableAction).destroy();
  }

  @Test
  public void testAddRemoveConfigurablePostProcessingAction() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", Mockito.mock(Processor.class), resourceRegistry);

    Action configurableAction = Mockito.mock(Action.class,
        Mockito.withSettings().extraInterfaces(Configurable.class));

    processorService.addPostProcessingAction(configurableAction);
    processorService.removePostProcessingAction(configurableAction);

    Mockito.verify((Configurable) configurableAction).configure();
    Mockito.verify((Configurable) configurableAction).destroy();
  }

  @Test
  public void testAddRemoveConfigurablePostReceivingAction() throws Exception {
    ConnectorService processorService = new MockConnectorService("test", Mockito.mock(Processor.class), resourceRegistry);

    Action configurableAction = Mockito.mock(Action.class,
        Mockito.withSettings().extraInterfaces(Configurable.class));

    processorService.addPostReceivingAction(configurableAction);
    processorService.removePostReceivingAction(configurableAction);

    Mockito.verify((Configurable) configurableAction).configure();
    Mockito.verify((Configurable) configurableAction).destroy();
  }

  @Test
  public void testStoppingActionExecution() throws Exception {

    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    Action action = new StopAction();
    processorService.addPreProcessingAction(action);

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    Thread.sleep(3000);

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
  }

  @Test
  public void testRouteNewMessageAction() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(15);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    Action action1 = Mockito.mock(Action.class);
    Action action2 = new SplitterAction(5, true);
    Action action3 = Mockito.mock(Action.class);
    // duplicates the messages that arrive and generates 5 more as it wont stop the ones that arrived
    Action action4 = new SplitterAction(2, false);
    Action action5 = Mockito.mock(Action.class);

    processorService
      .addPreProcessingAction(action1)
      .addPreProcessingAction(action2)
      .addPreProcessingAction(action3)
      .addPreProcessingAction(action4)
      .addPreProcessingAction(action5);

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(5000);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Mockito.verify(action1).execute(Mockito.any(Message.class));
    Mockito.verify(action3, Mockito.times(5)).execute(Mockito.any(Message.class));
    Mockito.verify(action5, Mockito.times(15)).execute(Mockito.any(Message.class));
  }

  @Test
  public void testPreProcessingActionException() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(1);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    Action action = Mockito.mock(Action.class);
    Mockito.doThrow(new NullPointerException()).when(action).execute(Mockito.any(Message.class));

    processorService.addPreProcessingAction(action);

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Exchange exchange = failedEndpoint.getReceivedExchanges().iterator().next();
    Message smsMessage = exchange.getIn().getBody(Message.class);

    Assert.assertEquals("test", smsMessage.getDestination());
    Assert.assertEquals(Message.STATUS_FAILED, smsMessage.getStatus());
  }

  @Test
  public void testPostProcessingActionException() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(0);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(1);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    Action action = Mockito.mock(Action.class);
    Mockito.doThrow(new NullPointerException()).when(action).execute(Mockito.any(Message.class));

    processorService.addPostProcessingAction(action);

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Exchange exchange = failedEndpoint.getReceivedExchanges().iterator().next();
    Message smsMessage = exchange.getIn().getBody(Message.class);

    Assert.assertEquals("test", smsMessage.getDestination());
    Assert.assertEquals(Message.STATUS_FAILED, smsMessage.getStatus());

    System.out.println("testPreProcessingActionException finished ...");
  }

  @Test
  public void testNonServiceableConnector() throws Exception {
    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    processorService.start();
    Assert.assertEquals(Service.State.STARTED, processorService.getState());

    processorService.stop();
    Assert.assertEquals(Service.State.STOPPED, processorService.getState());
  }

  @Test
  public void testServiceableConnector() throws Exception {
    // mock Processor and Serviceable
    Processor processor = Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Serviceable.class));

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    // verify
    Assert.assertEquals(Service.State.STARTED, processorService.getState());
    Mockito.verify((Serviceable) processor).doStart();


    processorService.stop();

    // verify
    Assert.assertEquals(Service.State.STOPPED, processorService.getState());
    Mockito.verify((Serviceable) processor).doStop();
  }

  @Test(expectedExceptions=ExecutionException.class)
  public void shouldFailOnStartException() throws Exception {
    // mock Processor and Serviceable
    Processor processor = Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Serviceable.class));
    Mockito.doThrow(new NullPointerException()).when((Serviceable) processor).doStart();

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();
  }

  @Test(expectedExceptions=ExecutionException.class)
  public void shouldFailOnStopException() throws Exception {
    // mock Processor and Serviceable
    Processor processor = Mockito.mock(Processor.class, Mockito.withSettings().extraInterfaces(Serviceable.class));
    Mockito.doThrow(new NullPointerException()).when((Serviceable) processor).doStop();

    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);
    processorService.start();

    processorService.stop();
  }

  @Test
  public void testMessageStoppedProcessor() throws Exception {
    MockEndpoint outboundEndpoint = getProcessedMessagesEndpoint(2);
    MockEndpoint failedEndpoint = getFailedMessagesEndpoint(0);

    MockProcessor processor = new MockProcessor();
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    simulateMessage(new Message(), "activemq:mokai-test");
    Thread.sleep(3000);

    Assert.assertEquals(0, processor.getCount());

    processorService.start();

    simulateMessage(new Message(), "activemq:mokai-test");

    outboundEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);
    failedEndpoint.assertIsSatisfied(DEFAULT_TIMEOUT);

    Assert.assertEquals(2, processor.getCount());
  }

  @Test
  public void testInjectResourceToProcessor() throws Exception {
    // add the resource to the resource registry
    resourceRegistry.putResource(MessageStore.class, Mockito.mock(MessageStore.class));

    MockConnector processor = new MockConnector();
    new MockConnectorService("test", processor, resourceRegistry);

    Assert.assertNotNull(processor.getMessageStore());

    ConnectorContext context = processor.getContext();
    Assert.assertNotNull(context);
    Assert.assertEquals("test", context.getId());
  }

  @Test
  public void testInjectResourceToAcceptor() throws Exception {
    // add he resource to the resource registry
    resourceRegistry.putResource(MessageStore.class, Mockito.mock(MessageStore.class));

    Processor processor = Mockito.mock(Processor.class);
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    MockAcceptor acceptor = new MockAcceptor();
    processorService.addAcceptor(acceptor);

    Assert.assertNotNull(acceptor.getMessageStore());
  }

  @Test
  public void testInjectResourceToActions() throws Exception {
    // add he resource to the resource registry
    resourceRegistry.putResource(MessageStore.class, Mockito.mock(MessageStore.class));

    Processor processor = Mockito.mock(Processor.class);
    ConnectorService processorService = new MockConnectorService("test", processor, resourceRegistry);

    // test inject resource to pre-processing action
    MockAction action = new MockAction();
    processorService.addPreProcessingAction(action);
    Assert.assertNotNull(action.getMessageStore());

    // test inject resource to post-processing action
    action = new MockAction();
    processorService.addPostProcessingAction(action);
    Assert.assertNotNull(action.getMessageStore());

    // test inject resource to post-receiving action
    action = new MockAction();
    processorService.addPostReceivingAction(action);
    Assert.assertNotNull(action.getMessageStore());
  }

  @Test
  public void testInjectConnectorContext() throws Exception {
    MockConnectorWithContext connector = new MockConnectorWithContext();
    new MockConnectorService("test", connector, resourceRegistry) {

      @Override
      protected Direction getDirection() {
        return Direction.TO_CONNECTIONS;
      }

    };

    Assert.assertNotNull(connector.context);
    Assert.assertEquals(connector.context.getId(), "test");
    Assert.assertEquals(connector.context.getDirection(), Direction.TO_CONNECTIONS);
  }

  /**
   * Helper method to create the route that validates the output of the receivers.
   *
   * @return
   * @throws Exception
   */
  private MockEndpoint getReceivedMessagesEndpoint(int expectedMessages) throws Exception {
    CamelContext camelContext = resourceRegistry.getResource(CamelContext.class);

    MockEndpoint ret = camelContext.getEndpoint(RECEIVED_MESSAGES_URI, MockEndpoint.class);
    ret.expectedMessageCount(expectedMessages);

    return ret;
  }

  /**
   * Helper method to create the route that validates the output of the processors.
   *
   * @return
   * @throws Exception
   */
  private MockEndpoint getProcessedMessagesEndpoint(int expectedMessages) throws Exception {
    CamelContext camelContext = resourceRegistry.getResource(CamelContext.class);

    MockEndpoint ret = camelContext.getEndpoint(PROCESSED_MESSAGES_URI, MockEndpoint.class);
    ret.expectedMessageCount(expectedMessages);

    return ret;
  }

  /**
   * Helper method to create the route that validates the failed messages.
   *
   * @return
   * @throws Exception
   */
  private MockEndpoint getFailedMessagesEndpoint(int expectedMessages) throws Exception {
    CamelContext camelContext = resourceRegistry.getResource(CamelContext.class);

    MockEndpoint ret = camelContext.getEndpoint(FAILED_MESSAGES_URI, MockEndpoint.class);
    ret.expectedMessageCount(expectedMessages);

    return ret;
  }

  private class MockConnectorService extends AbstractCamelConnectorService {

    public MockConnectorService(String id, Connector connector, ResourceRegistry resourceRegistry)
        throws IllegalArgumentException, ExecutionException {
      super(id, connector, resourceRegistry);
    }

    @Override
    protected String getOutboundUriPrefix() {
      return "activemq:mokai-";
    }

    @Override
    protected String getOutboundIntUriPrefix() {
      return "direct:mokai-int-";
    }

    @Override
    protected String getInboundUriPrefix() {
      return "direct:mokai-";
    }

    @Override
    protected String getProcessedMessagesUri() {
      return PROCESSED_MESSAGES_URI;
    }

    @Override
    protected String getFailedMessagesUri() {
      return FAILED_MESSAGES_URI;
    }

    @Override
    protected String getMessagesRouterUri() {
      return RECEIVED_MESSAGES_URI;
    }

    @Override
    protected Direction getDirection() {
      return Direction.UNKNOWN;
    }

  }


  /**
   * Helper method to simulate sending messages
   * @param message the message that wants to be sent.
   * @param endpoint the enpoint to which we are going to send the message
   */
  private void simulateMessage(Message message, String endpoint) {
    camelProducer.sendBody(endpoint, message);
  }

  private class MockConnectorWithContext implements Connector {
    @Resource
    public ConnectorContext context;
  }

  /**
   * Mock Processor that counts processed messages.
   *
   * @author German Escobar
   */
  private class MockProcessor implements Processor {

    private List<Message> messages = new ArrayList<Message>();

    @Override
    public void process(Message message) {
      messages.add(message);
    }

    @Override
    public boolean supports(Message message) {
      if (Message.class.isInstance(message)) {
        return true;
      }

      return false;
    }

    public int getCount() {
      return messages.size();
    }

    public Message getMessage(int index) {
      return messages.get(index);
    }

  }

  /**
   * Simple receiver that exposes a sendMessage method to simulate messages.
   *
   * @author German Escobar
   */
  private class SimpleReceiverProcessor implements Processor {

    @Resource
    private MessageProducer messageProducer;

    public void receiveMessage(Message message) {
      messageProducer.produce(message);
    }

    @Override
    public void process(Message message) {
    }

    @Override
    public boolean supports(Message message) {
      return false;
    }
  }

  /**
   * An action to test the stop execution feature.
   *
   * @author German Escobar
   */
  private class StopAction implements Action {

    @Resource
    private Execution execution;

    @Override
    public void execute(Message message) throws Exception {
      execution.stop();
    }

  }

  private class SplitterAction implements Action {

    private int quantity;

    boolean stop;

    @Resource
    private Execution execution;

    public SplitterAction(int quantity, boolean stop) {
      this.quantity = quantity;
      this.stop = stop;
    }

    @Override
    public void execute(Message message) throws Exception {
      for (int i=0; i < quantity; i++) {
        execution.route(new Message());
      }

      if (stop) {
        execution.stop();
      }
    }
  }

}
TOP

Related Classes of org.mokai.impl.camel.test.CamelConnectorServiceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.