@Category({SmokeTests.class, RegressionTests.class})
  @Test
  public void testSaveObject() {
    try {
      MessageProcessor flow = lookupMessageProcessorConstruct("save-object");
      flow.process(getTestEvent(testObjects));

      DBObject element = (DBObject) testObjects.get("elementRef");

      // Check that object was inserted
      MongoCollection dbObjects = getObjects(testObjects);
      assertTrue(dbObjects.contains(element));

      // Get key and value from payload (defined in bean)
      String key = testObjects.get("key").toString();
      String value = testObjects.get("value").toString();

      // Modify object and save
      element.put(key, value);
      flow = lookupMessageProcessorConstruct("save-object");
      flow.process(getTestEvent(testObjects));

      // Check that object was changed in MongoDB
      dbObjects = getObjects(testObjects);
      assertTrue(dbObjects.contains(element));

    } catch (Exception e) {
      e.printStackTrace();
      fail();
    }
  }
  @SuppressWarnings("unchecked")
  @Before
  public void setUp() {
    try {
      testObjects = (HashMap<String, Object>) context.getBean("removeObjects");
      MessageProcessor flow = lookupFlowConstruct("create-collection");
      flow.process(getTestEvent(testObjects));

      flow = lookupFlowConstruct("insert-object");
      flow.process(getTestEvent(testObjects));
    } catch (Exception e) {
      e.printStackTrace();
      fail();
    }
  }
 @Test
 public void retryOnOriginalEvent() throws Exception {
   when(mockUntilSuccessfulConfiguration.getFailureExpressionFilter())
       .thenReturn(mockAlwaysTrueFailureExpressionFilter);
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(any(MuleEvent.class)))
       .then(
           new Answer<MuleEvent>() {
             @Override
             public MuleEvent answer(InvocationOnMock invocation) throws Throwable {
               MuleEvent argEvent = (MuleEvent) invocation.getArguments()[0];
               assertThat(argEvent.getMessageAsString(), is(TEST_DATA));
               argEvent.getMessage().setPayload(PROCESSED_DATA);
               return argEvent;
             }
           });
   try {
     processingStrategy.route(event);
     fail("processing should throw exception");
   } catch (MessagingException e) {
     assertThat(e, instanceOf(RoutingException.class));
     verify(mockRoute, times(DEFAULT_RETRIES + 1)).process(event);
     verify(mockAlwaysTrueFailureExpressionFilter, times(DEFAULT_RETRIES + 1))
         .accept(any(MuleMessage.class));
   }
 }
 @Test
 public void successfulExecution() throws Exception {
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(event)).thenReturn(event);
   assertThat(processingStrategy.route(event), is(event));
   verify(mockRoute).process(event);
 }
  @Test(expected = MessagingException.class)
  public void testProcessOneWayNoThreadingWithException() throws Exception {
    ThreadingProfile threadingProfile =
        new ChainedThreadingProfile(muleContext.getDefaultThreadingProfile());
    threadingProfile.setDoThreading(false);
    threadingProfile.setMuleContext(muleContext);

    MessageProcessor mockListener = mock(MessageProcessor.class);
    when(mockListener.process((MuleEvent) any())).thenThrow(new RuntimeException());

    SedaStageInterceptingMessageProcessor sedaStageInterceptingMessageProcessor =
        new SedaStageInterceptingMessageProcessor(
            "testProcessOneWayNoThreadingWithException",
            "testProcessOneWayNoThreadingWithException",
            queueProfile,
            queueTimeout,
            threadingProfile,
            queueStatistics,
            muleContext);
    sedaStageInterceptingMessageProcessor.setListener(mockListener);
    sedaStageInterceptingMessageProcessor.initialise();
    sedaStageInterceptingMessageProcessor.start();

    MessagingExceptionHandler exceptionHandler = mock(MessagingExceptionHandler.class);
    Flow flow = mock(Flow.class);
    when(flow.getExceptionListener()).thenReturn(exceptionHandler);
    when(flow.getProcessingStrategy()).thenReturn(new AsynchronousProcessingStrategy());
    MuleEvent event = getTestEvent(TEST_MESSAGE, flow, MessageExchangePattern.ONE_WAY);

    sedaStageInterceptingMessageProcessor.process(event);
  }
 @Override
 public void start() throws MuleException {
   DefaultMuleMessage muleMessage = new DefaultMuleMessage("TEST", context);
   DefaultMuleEvent defaultMuleEvent =
       new DefaultMuleEvent(muleMessage, MessageExchangePattern.ONE_WAY, flowConstruct);
   listener.process(defaultMuleEvent);
 }
  @Category({RegressionTests.class})
  @Test
  public void testRemoveObjects() {
    try {
      MessageProcessor flow = lookupFlowConstruct("remove-objects");
      MuleEvent response = flow.process(getTestEvent(testObjects));

      flow = lookupFlowConstruct("find-objects");
      response = flow.process(getTestEvent(testObjects));

      MongoCollection payload = (MongoCollection) response.getMessage().getPayload();
      assertTrue(payload.isEmpty());
    } catch (Exception e) {
      e.printStackTrace();
      fail();
    }
  }
 @After
 public void tearDown() {
   try {
     MessageProcessor flow = lookupMessageProcessorConstruct("drop-collection");
     flow.process(getTestEvent(testObjects));
   } catch (Exception e) {
     e.printStackTrace();
     fail();
   }
 }
  @Test
  public void testProcessOneWayThreadWaitTimeout() throws Exception {
    final int threadTimeout = 20;
    ThreadingProfile threadingProfile =
        new ChainedThreadingProfile(muleContext.getDefaultThreadingProfile());
    threadingProfile.setThreadWaitTimeout(threadTimeout);
    // Need 3 threads: 1 for polling, 2 to process work successfully without timeout
    threadingProfile.setMaxThreadsActive(3);
    threadingProfile.setPoolExhaustedAction(ThreadingProfile.WHEN_EXHAUSTED_WAIT);
    threadingProfile.setMuleContext(muleContext);

    MessageProcessor mockListener = mock(MessageProcessor.class);
    when(mockListener.process((MuleEvent) any()))
        .thenAnswer(
            new Answer<MuleEvent>() {
              public MuleEvent answer(InvocationOnMock invocation) throws Throwable {
                Thread.sleep(threadTimeout * 2);
                return (MuleEvent) invocation.getArguments()[0];
              }
            });

    SedaStageInterceptingMessageProcessor sedaStageInterceptingMessageProcessor =
        new SedaStageInterceptingMessageProcessor(
            "testProcessOneWayThreadWaitTimeout",
            "testProcessOneWayThreadWaitTimeout",
            queueProfile,
            queueTimeout,
            threadingProfile,
            queueStatistics,
            muleContext);
    sedaStageInterceptingMessageProcessor.setListener(mockListener);
    sedaStageInterceptingMessageProcessor.initialise();
    sedaStageInterceptingMessageProcessor.start();

    MessagingExceptionHandler exceptionHandler = mock(MessagingExceptionHandler.class);
    Flow flow = mock(Flow.class);
    when(flow.getExceptionListener()).thenReturn(exceptionHandler);
    when(flow.getProcessingStrategy()).thenReturn(new AsynchronousProcessingStrategy());
    final MuleEvent event = getTestEvent(TEST_MESSAGE, flow, MessageExchangePattern.ONE_WAY);

    for (int i = 0; i < 3; i++) {
      sedaStageInterceptingMessageProcessor.process(event);
    }

    ArgumentMatcher<MuleEvent> notSameEvent = createNotSameEventArgumentMatcher(event);

    // Two events are processed
    verify(mockListener, timeout(RECEIVE_TIMEOUT).times(2)).process(argThat(notSameEvent));

    // One event gets processed by the exception strategy
    verify(exceptionHandler, timeout(RECEIVE_TIMEOUT).times(1))
        .handleException((Exception) any(), argThat(notSameEvent));
  }
 @Test
 public void alwaysFail() throws MuleException {
   when(mockRoute.process(any(MuleEvent.class)))
       .thenThrow(new RuntimeException("expected failure"));
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   try {
     processingStrategy.route(event);
     fail("processing should throw exception");
   } catch (MessagingException e) {
     assertThat(e, instanceOf(RoutingException.class));
     verify(mockRoute, times(DEFAULT_RETRIES + 1)).process(event);
   }
 }
  @Test
  public void testProcessOneWayWithException() throws Exception {
    final Latch latch = new Latch();
    ThreadingProfile threadingProfile =
        new ChainedThreadingProfile(muleContext.getDefaultThreadingProfile());
    threadingProfile.setMuleContext(muleContext);

    MessageProcessor mockListener = mock(MessageProcessor.class);
    when(mockListener.process((MuleEvent) any()))
        .thenAnswer(
            new Answer<MuleEvent>() {
              public MuleEvent answer(InvocationOnMock invocation) throws Throwable {
                latch.countDown();
                throw new RuntimeException();
              }
            });

    SedaStageInterceptingMessageProcessor sedaStageInterceptingMessageProcessor =
        new SedaStageInterceptingMessageProcessor(
            "testProcessOneWayWithException",
            "testProcessOneWayWithException",
            queueProfile,
            queueTimeout,
            threadingProfile,
            queueStatistics,
            muleContext);
    sedaStageInterceptingMessageProcessor.setListener(mockListener);
    sedaStageInterceptingMessageProcessor.initialise();
    sedaStageInterceptingMessageProcessor.start();

    MessagingExceptionHandler exceptionHandler = mock(MessagingExceptionHandler.class);
    Flow flow = mock(Flow.class);
    when(flow.getExceptionListener()).thenReturn(exceptionHandler);
    when(flow.getProcessingStrategy()).thenReturn(new AsynchronousProcessingStrategy());
    final MuleEvent event = getTestEvent(TEST_MESSAGE, flow, MessageExchangePattern.ONE_WAY);

    sedaStageInterceptingMessageProcessor.process(event);

    assertTrue(latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));

    ArgumentMatcher<MuleEvent> notSameEvent = createNotSameEventArgumentMatcher(event);

    // One event get processed but then throws an exception
    verify(mockListener, timeout(RECEIVE_TIMEOUT).times(1)).process(argThat(notSameEvent));

    // One event gets processed by the exception strategy
    verify(exceptionHandler, timeout(RECEIVE_TIMEOUT).times(1))
        .handleException((Exception) any(), argThat(notSameEvent));
  }
 @Test
 public void successfulExecutionWithAckExpression() throws Exception {
   String ackExpression = "some-expression";
   String expressionEvalutaionResult = "new payload";
   event.setMessage(spy(event.getMessage()));
   when(mockUntilSuccessfulConfiguration.getAckExpression()).thenReturn(ackExpression);
   when(mockUntilSuccessfulConfiguration
           .getMuleContext()
           .getExpressionManager()
           .evaluate(ackExpression, event))
       .thenReturn(expressionEvalutaionResult);
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(event)).thenReturn(event);
   assertThat(processingStrategy.route(event), is(event));
   verify(mockRoute).process(event);
   verify(mockUntilSuccessfulConfiguration.getMuleContext().getExpressionManager())
       .evaluate(ackExpression, event);
   verify(event.getMessage()).setPayload(expressionEvalutaionResult);
 }
  @Category({RegressionTests.class})
  @Test
  public void testCountObjects() {

    int numObjects = (Integer) testObjects.get("numObjects");

    insertObjects(getEmptyDBObjects(numObjects));

    MuleEvent response = null;
    try {
      MessageProcessor countFlow = lookupMessageProcessorConstruct("count-objects");
      testObjects.put("queryRef", new BasicDBObject());
      response = countFlow.process(getTestEvent(testObjects));
    } catch (Exception e) {
      e.printStackTrace();
      fail();
    }
    assertEquals(new Long(numObjects), response.getMessage().getPayload());
  }
 @Test
 public void successfulWithNullEventResponseFromRoute() throws Exception {
   when(mockRoute.process(event)).thenReturn(VoidMuleEvent.getInstance());
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   assertThat((VoidMuleEvent) processingStrategy.route(event), is(VoidMuleEvent.getInstance()));
 }