Example #1
0
  public void testRemovingListeners() throws Exception {
    TestSubscriptionEventBean subscriptionBean =
        (TestSubscriptionEventBean) context.getBean("testSubscribingEventBean1");
    assertNotNull(subscriptionBean);
    MuleEventMulticaster multicaster =
        (MuleEventMulticaster)
            context.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
    assertNotNull(multicaster);

    Latch whenFinished = new Latch();
    subscriptionBean.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));

    multicaster.removeApplicationListener(subscriptionBean);
    MuleClient client = new MuleClient();
    client.send("vm://event.multicaster", "Test Spring Event", null);

    assertEquals(0, eventCounter1.get());

    multicaster.addApplicationListener(subscriptionBean);
    client.send("vm://event.multicaster", "Test Spring Event", null);

    assertTrue(whenFinished.await(3000, TimeUnit.MILLISECONDS));
    assertEquals(1, eventCounter1.get());
    eventCounter1.set(0);

    multicaster.removeAllListeners();
    client.send("vm://event.multicaster", "Test Spring Event", null);

    assertEquals(0, eventCounter1.get());
    multicaster.addApplicationListener(subscriptionBean);
    context.refresh();
    subscriptionBean.setEventCallback(null);
  }
Example #2
0
  public void testReceivingASpringEvent() throws Exception {
    TestApplicationEventBean bean =
        (TestApplicationEventBean) context.getBean("testEventSpringBean");
    assertNotNull(bean);

    final Latch whenFinished = new Latch();
    EventCallback callback =
        new EventCallback() {
          public void eventReceived(UMOEventContext context, Object o) throws Exception {
            assertNull(context);
            if (o instanceof TestApplicationEvent) {
              if (eventCounter1.incrementAndGet() == 1) {
                whenFinished.countDown();
              }
            }
          }
        };

    bean.setEventCallback(callback);

    context.publishEvent(new TestApplicationEvent(context));

    whenFinished.await(3000, TimeUnit.MILLISECONDS);
    assertEquals(1, eventCounter1.get());
  }
Example #3
0
  public void testPublishWithEventAwareTransformer() throws Exception {
    CountDownLatch transformerLatch = new CountDownLatch(1);

    TestEventAwareTransformer trans = new TestEventAwareTransformer();
    trans.setLatch(transformerLatch);
    managementContext.getRegistry().registerTransformer(trans);

    MuleApplicationEvent event =
        new MuleApplicationEvent(
            "Event from a spring bean", "vm://testBean2?transformers=dummyTransformer");

    TestSubscriptionEventBean bean2 =
        (TestSubscriptionEventBean) context.getBean("testSubscribingEventBean2");
    assertNotNull(bean2);

    Latch whenFinished = new Latch();
    bean2.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));

    // publish asynchronously
    this.doPublish(event, 1);

    whenFinished.await(3000, TimeUnit.MILLISECONDS);
    assertTrue(transformerLatch.await(3000, TimeUnit.MILLISECONDS));
    assertEquals(1, eventCounter1.get());
  }
Example #4
0
  public void testReceivingANonSubscriptionMuleEvent() throws Exception {
    TestMuleEventBean bean = (TestMuleEventBean) context.getBean("testNonSubscribingMuleEventBean");
    assertNotNull(bean);

    // register a callback
    Latch whenFinished = new Latch();
    bean.setEventCallback(new CountingEventCallback(eventCounter1, 1, whenFinished));

    MuleClient client = new MuleClient();
    client.send("vm://event.multicaster", "Test Spring Event", null);

    whenFinished.await(3000, TimeUnit.MILLISECONDS);
    assertEquals(1, eventCounter1.get());
  }
Example #5
0
  public void testReceivingAllEvents() throws Exception {
    TestAllEventBean bean = (TestAllEventBean) context.getBean("testAllEventBean");
    assertNotNull(bean);

    Latch whenFinished = new Latch();
    bean.setEventCallback(new CountingEventCallback(eventCounter1, 2, whenFinished));

    MuleClient client = new MuleClient();
    client.send("vm://event.multicaster", "Test Spring Event", null);
    context.publishEvent(new TestApplicationEvent(context));

    whenFinished.await(3000, TimeUnit.MILLISECONDS);
    assertEquals(2, eventCounter1.get());
  }
  @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));
  }
Example #7
0
  public void testReceiveAndPublishEvent() throws Exception {
    TestSubscriptionEventBean bean1 =
        (TestSubscriptionEventBean) context.getBean("testSubscribingEventBean1");
    assertNotNull(bean1);

    final Latch whenFinished1 = new Latch();
    EventCallback callback =
        new EventCallback() {
          public void eventReceived(UMOEventContext context, Object o) throws Exception {
            MuleApplicationEvent returnEvent =
                new MuleApplicationEvent("Event from a spring bean", "vm://testBean2");
            MuleApplicationEvent e = (MuleApplicationEvent) o;
            e.getApplicationContext().publishEvent(returnEvent);
            if (eventCounter1.incrementAndGet() == NUMBER_OF_MESSAGES) {
              whenFinished1.countDown();
            }
          }
        };
    bean1.setEventCallback(callback);

    TestSubscriptionEventBean bean2 =
        (TestSubscriptionEventBean) context.getBean("testSubscribingEventBean2");
    assertNotNull(bean2);

    Latch whenFinished2 = new Latch();
    bean2.setEventCallback(
        new CountingEventCallback(eventCounter2, NUMBER_OF_MESSAGES, whenFinished2));

    // send asynchronously
    this.doSend("vm://event.multicaster", "Test Spring Event", NUMBER_OF_MESSAGES);

    whenFinished1.await(3000, TimeUnit.MILLISECONDS);
    whenFinished2.await(3000, TimeUnit.MILLISECONDS);
    assertEquals(NUMBER_OF_MESSAGES, eventCounter1.get());
    assertEquals(NUMBER_OF_MESSAGES, eventCounter2.get());
  }
Example #8
0
  public void testPublishOnly() throws Exception {
    final MuleApplicationEvent event =
        new MuleApplicationEvent("Event from a spring bean", "vm://testBean2");

    TestSubscriptionEventBean bean2 =
        (TestSubscriptionEventBean) context.getBean("testSubscribingEventBean2");
    assertNotNull(bean2);

    Latch whenFinished = new Latch();
    bean2.setEventCallback(
        new CountingEventCallback(eventCounter1, NUMBER_OF_MESSAGES, whenFinished));

    // publish asynchronously
    this.doPublish(event, NUMBER_OF_MESSAGES);

    whenFinished.await(3000, TimeUnit.MILLISECONDS);
    assertEquals(NUMBER_OF_MESSAGES, eventCounter1.get());
  }
Example #9
0
  private MuleMessage dispatchMessage(MuleEvent event) throws Exception {
    Session session = null;
    MessageProducer producer = null;
    MessageConsumer consumer = null;
    Destination replyTo = null;
    boolean transacted = false;
    boolean cached = false;
    boolean useReplyToDestination;

    final Transaction muleTx = TransactionCoordination.getInstance().getTransaction();

    if (logger.isDebugEnabled()) {
      logger.debug(
          "dispatching on endpoint: "
              + event.getEndpoint().getEndpointURI()
              + ". MuleEvent id is: "
              + event.getId()
              + ". Outbound transformers are: "
              + event.getEndpoint().getTransformers());
    }

    // assume session is transacted first, and thus, managed
    boolean sessionManaged = true;
    try {
      session = connector.getSessionFromTransaction();
      if (session != null) {
        transacted = true;
      }
      // Should we be caching sessions? Note this is not part of the JMS spec.
      // and is turned off by default.
      else if (event
          .getMessage()
          .getBooleanProperty(
              JmsConstants.CACHE_JMS_SESSIONS_PROPERTY, connector.isCacheJmsSessions())) {
        sessionManaged = false;
        cached = true;
        if (cachedSession != null) {
          session = cachedSession;
        } else {
          session = connector.getSession(event.getEndpoint());
          cachedSession = session;
        }
      } else {
        // by now we're running with a different connector and connection
        sessionManaged = muleTx != null && muleTx.isXA();

        session = connector.getSession(event.getEndpoint());
        if (event.getEndpoint().getTransactionConfig().isTransacted()) {
          transacted = true;
        }
      }

      // If a transaction is running, we can not receive any messages
      // in the same transaction using a replyTo destination
      useReplyToDestination = returnResponse(event) && !transacted;

      boolean topic = connector.getTopicResolver().isTopic(event.getEndpoint(), true);

      Destination dest = connector.getJmsSupport().createDestination(session, endpoint);
      producer = connector.getJmsSupport().createProducer(session, dest, topic);

      preTransformMessage(event.getMessage());

      Object message = event.transformMessage();
      if (!(message instanceof Message)) {
        throw new DispatchException(
            JmsMessages.checkTransformer("JMS message", message.getClass(), connector.getName()),
            event.getMessage(),
            event.getEndpoint());
      }

      Message msg = (Message) message;

      MuleMessage eventMsg = event.getMessage();

      replyTo = getReplyToDestination(msg, session, event, useReplyToDestination, topic);

      // Set the replyTo property
      if (replyTo != null) {
        msg.setJMSReplyTo(replyTo);
      }

      // Allow overrides to alter the message if necessary
      processMessage(msg, event);

      // QoS support
      String ttlString = (String) eventMsg.removeProperty(JmsConstants.TIME_TO_LIVE_PROPERTY);
      String priorityString = (String) eventMsg.removeProperty(JmsConstants.PRIORITY_PROPERTY);
      String persistentDeliveryString =
          (String) eventMsg.removeProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY);

      long ttl =
          StringUtils.isNotBlank(ttlString)
              ? NumberUtils.toLong(ttlString)
              : Message.DEFAULT_TIME_TO_LIVE;
      int priority =
          StringUtils.isNotBlank(priorityString)
              ? NumberUtils.toInt(priorityString)
              : Message.DEFAULT_PRIORITY;
      boolean persistent =
          StringUtils.isNotBlank(persistentDeliveryString)
              ? BooleanUtils.toBoolean(persistentDeliveryString)
              : connector.isPersistentDelivery();

      // If we are honouring the current QoS message headers we need to use the ones set on the
      // current message
      if (connector.isHonorQosHeaders()) {
        Object priorityProp = eventMsg.getProperty(JmsConstants.JMS_PRIORITY);
        Object deliveryModeProp = eventMsg.getProperty(JmsConstants.JMS_DELIVERY_MODE);

        if (priorityProp != null) {
          priority = NumberUtils.toInt(priorityProp);
        }
        if (deliveryModeProp != null) {
          persistent = NumberUtils.toInt(deliveryModeProp) == DeliveryMode.PERSISTENT;
        }
      }

      if (logger.isDebugEnabled()) {
        logger.debug("Sending message of type " + ClassUtils.getSimpleName(msg.getClass()));
        logger.debug(
            "Sending JMS Message type "
                + msg.getJMSType()
                + "\n  JMSMessageID="
                + msg.getJMSMessageID()
                + "\n  JMSCorrelationID="
                + msg.getJMSCorrelationID()
                + "\n  JMSDeliveryMode="
                + (persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT)
                + "\n  JMSPriority="
                + priority
                + "\n  JMSReplyTo="
                + msg.getJMSReplyTo());
      }
      connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic, endpoint);

      if (useReplyToDestination && replyTo != null) {
        consumer = createReplyToConsumer(msg, event, session, replyTo, topic);

        if (topic) {
          // need to register a listener for a topic
          Latch l = new Latch();
          ReplyToListener listener = new ReplyToListener(l);
          consumer.setMessageListener(listener);

          connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic, endpoint);

          int timeout = event.getTimeout();

          if (logger.isDebugEnabled()) {
            logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
          }

          l.await(timeout, TimeUnit.MILLISECONDS);
          consumer.setMessageListener(null);
          listener.release();
          Message result = listener.getMessage();
          if (result == null) {
            logger.debug("No message was returned via replyTo destination");
            return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
          } else {
            MessageAdapter adapter = connector.getMessageAdapter(result);
            return new DefaultMuleMessage(
                JmsMessageUtils.toObject(
                    result, connector.getSpecification(), endpoint.getEncoding()),
                adapter,
                connector.getMuleContext());
          }
        } else {
          int timeout = event.getTimeout();

          if (logger.isDebugEnabled()) {
            logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
          }

          Message result = consumer.receive(timeout);
          if (result == null) {
            logger.debug("No message was returned via replyTo destination " + replyTo);
            return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext());
          } else {
            MessageAdapter adapter = connector.getMessageAdapter(result);
            return new DefaultMuleMessage(
                JmsMessageUtils.toObject(
                    result, connector.getSpecification(), endpoint.getEncoding()),
                adapter,
                connector.getMuleContext());
          }
        }
      }

      return new DefaultMuleMessage(
          returnOriginalMessageAsReply ? msg : NullPayload.getInstance(),
          connector.getMuleContext());
    } finally {
      connector.closeQuietly(producer);
      connector.closeQuietly(consumer);

      // TODO AP check if TopicResolver is to be utilized for temp destinations as well
      if (replyTo != null
          && (replyTo instanceof TemporaryQueue || replyTo instanceof TemporaryTopic)) {
        if (replyTo instanceof TemporaryQueue) {
          connector.closeQuietly((TemporaryQueue) replyTo);
        } else {
          // hope there are no more non-standard tricks from JMS vendors
          // here ;)
          connector.closeQuietly((TemporaryTopic) replyTo);
        }
      }

      if (!sessionManaged && transacted && muleTx instanceof TransactionCollection) {
        handleMultiTx(session);
      }

      // If the session is from the current transaction, it is up to the
      // transaction to close it.
      if (session != null && !cached && !transacted) {
        connector.closeQuietly(session);
      }
    }
  }
Example #10
0
  private MuleMessage dispatchMessage(MuleEvent event) throws Exception {
    Session session = null;
    MessageProducer producer = null;
    MessageConsumer consumer = null;
    Destination replyTo = null;
    boolean transacted = false;
    boolean cached = false;
    boolean remoteSync = useRemoteSync(event);

    if (logger.isDebugEnabled()) {
      logger.debug(
          "dispatching on endpoint: "
              + event.getEndpoint().getEndpointURI()
              + ". MuleEvent id is: "
              + event.getId()
              + ". Outbound transformers are: "
              + event.getEndpoint().getTransformers());
    }

    try {
      session = connector.getSessionFromTransaction();
      if (session != null) {
        transacted = true;

        // If a transaction is running, we can not receive any messages
        // in the same transaction.
        if (remoteSync) {
          throw new IllegalTransactionStateException(
              JmsMessages.connectorDoesNotSupportSyncReceiveWhenTransacted());
        }
      }
      // Should we be caching sessions? Note this is not part of the JMS spec.
      // and is turned off by default.
      else if (event
          .getMessage()
          .getBooleanProperty(
              JmsConstants.CACHE_JMS_SESSIONS_PROPERTY, connector.isCacheJmsSessions())) {
        cached = true;
        if (cachedSession != null) {
          session = cachedSession;
        } else {
          session = connector.getSession(event.getEndpoint());
          cachedSession = session;
        }
      } else {
        session = connector.getSession(event.getEndpoint());
        if (event.getEndpoint().getTransactionConfig().isTransacted()) {
          transacted = true;
        }
      }

      boolean topic = connector.getTopicResolver().isTopic(event.getEndpoint(), true);

      Destination dest = connector.createDestinationMule3858Backport(session, endpoint);
      producer = connector.getJmsSupport().createProducer(session, dest, topic);

      Object message = event.transformMessage();
      if (!(message instanceof Message)) {
        throw new DispatchException(
            JmsMessages.checkTransformer("JMS message", message.getClass(), connector.getName()),
            event.getMessage(),
            event.getEndpoint());
      }

      Message msg = (Message) message;
      if (event.getMessage().getCorrelationId() != null) {
        msg.setJMSCorrelationID(event.getMessage().getCorrelationId());
      }

      MuleMessage eventMsg = event.getMessage();

      // Some JMS implementations might not support the ReplyTo property.
      if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO)) {
        Object tempReplyTo = eventMsg.removeProperty(JmsConstants.JMS_REPLY_TO);
        if (tempReplyTo == null) {
          // It may be a Mule URI or global endpoint Ref
          tempReplyTo = eventMsg.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
          if (tempReplyTo != null) {
            if (tempReplyTo.toString().startsWith("jms://")) {
              tempReplyTo = tempReplyTo.toString().substring(6);
            } else {
              EndpointBuilder epb =
                  event
                      .getMuleContext()
                      .getRegistry()
                      .lookupEndpointBuilder(tempReplyTo.toString());
              if (epb != null) {
                tempReplyTo = epb.buildOutboundEndpoint().getEndpointURI().getAddress();
              }
            }
          }
        }
        if (tempReplyTo != null) {
          if (tempReplyTo instanceof Destination) {
            replyTo = (Destination) tempReplyTo;
          } else {
            // TODO AP should this drill-down be moved into the resolver as well?
            boolean replyToTopic = false;
            String reply = tempReplyTo.toString();
            int i = reply.indexOf(":");
            if (i > -1) {
              // TODO MULE-1409 this check will not work for ActiveMQ 4.x,
              // as they have temp-queue://<destination> and temp-topic://<destination> URIs
              // Extract to a custom resolver for ActiveMQ4.x
              // The code path can be exercised, e.g. by a LoanBrokerESBTestCase
              String qtype = reply.substring(0, i);
              replyToTopic = JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(qtype);
              reply = reply.substring(i + 1);
            }
            replyTo = connector.getJmsSupport().createDestination(session, reply, replyToTopic);
          }
        }
        // Are we going to wait for a return event ?
        if (remoteSync && replyTo == null) {
          replyTo = connector.getJmsSupport().createTemporaryDestination(session, topic);
        }
        // Set the replyTo property
        if (replyTo != null) {
          msg.setJMSReplyTo(replyTo);
        }

        // Are we going to wait for a return event ?
        if (remoteSync) {
          try {
            consumer = connector.getJmsSupport().createConsumer(session, replyTo, topic);
          } catch (Exception e) {
            logger.warn(e);
          }
        }
      }

      // QoS support
      String ttlString = (String) eventMsg.removeProperty(JmsConstants.TIME_TO_LIVE_PROPERTY);
      String priorityString = (String) eventMsg.removeProperty(JmsConstants.PRIORITY_PROPERTY);
      String persistentDeliveryString =
          (String) eventMsg.removeProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY);

      long ttl =
          StringUtils.isNotBlank(ttlString)
              ? NumberUtils.toLong(ttlString)
              : Message.DEFAULT_TIME_TO_LIVE;
      int priority =
          StringUtils.isNotBlank(priorityString)
              ? NumberUtils.toInt(priorityString)
              : Message.DEFAULT_PRIORITY;
      boolean persistent =
          StringUtils.isNotBlank(persistentDeliveryString)
              ? BooleanUtils.toBoolean(persistentDeliveryString)
              : connector.isPersistentDelivery();

      if (connector.isHonorQosHeaders()) {
        int priorityProp =
            eventMsg.getIntProperty(JmsConstants.JMS_PRIORITY, Connector.INT_VALUE_NOT_SET);
        int deliveryModeProp =
            eventMsg.getIntProperty(JmsConstants.JMS_DELIVERY_MODE, Connector.INT_VALUE_NOT_SET);

        if (priorityProp != Connector.INT_VALUE_NOT_SET) {
          priority = priorityProp;
        }
        if (deliveryModeProp != Connector.INT_VALUE_NOT_SET) {
          persistent = deliveryModeProp == DeliveryMode.PERSISTENT;
        }
      }

      if (logger.isDebugEnabled()) {
        logger.debug("Sending message of type " + ClassUtils.getSimpleName(msg.getClass()));
      }

      if (consumer != null && topic) {
        // need to register a listener for a topic
        Latch l = new Latch();
        ReplyToListener listener = new ReplyToListener(l);
        consumer.setMessageListener(listener);

        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);

        int timeout = event.getTimeout();

        if (logger.isDebugEnabled()) {
          logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
        }

        l.await(timeout, TimeUnit.MILLISECONDS);
        consumer.setMessageListener(null);
        listener.release();
        Message result = listener.getMessage();
        if (result == null) {
          logger.debug("No message was returned via replyTo destination");
          return null;
        } else {
          MessageAdapter adapter = connector.getMessageAdapter(result);
          return new DefaultMuleMessage(
              JmsMessageUtils.toObject(
                  result, connector.getSpecification(), endpoint.getEncoding()),
              adapter);
        }
      } else {
        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);
        if (consumer != null) {
          int timeout = event.getTimeout();

          if (logger.isDebugEnabled()) {
            logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
          }

          Message result = consumer.receive(timeout);
          if (result == null) {
            logger.debug("No message was returned via replyTo destination");
            return null;
          } else {
            MessageAdapter adapter = connector.getMessageAdapter(result);
            return new DefaultMuleMessage(
                JmsMessageUtils.toObject(
                    result, connector.getSpecification(), endpoint.getEncoding()),
                adapter);
          }
        }
      }
      return null;
    } finally {
      connector.closeQuietly(producer);
      connector.closeQuietly(consumer);

      // TODO AP check if TopicResolver is to be utilized for temp destinations as well
      if (replyTo != null
          && (replyTo instanceof TemporaryQueue || replyTo instanceof TemporaryTopic)) {
        if (replyTo instanceof TemporaryQueue) {
          connector.closeQuietly((TemporaryQueue) replyTo);
        } else {
          // hope there are no more non-standard tricks from JMS vendors
          // here ;)
          connector.closeQuietly((TemporaryTopic) replyTo);
        }
      }

      // If the session is from the current transaction, it is up to the
      // transaction to close it.
      if (session != null && !cached && !transacted) {
        connector.closeQuietly(session);
      }
    }
  }
Example #11
0
  private UMOMessage dispatchMessage(UMOEvent event) throws Exception {
    Session session = null;
    MessageProducer producer = null;
    MessageConsumer consumer = null;
    Destination replyTo = null;
    boolean transacted = false;
    boolean cached = false;
    boolean remoteSync = useRemoteSync(event);

    if (logger.isDebugEnabled()) {
      logger.debug(
          "dispatching on endpoint: "
              + event.getEndpoint().getEndpointURI()
              + ". Event id is: "
              + event.getId());
    }

    try {
      // Retrieve the session from the current transaction.
      session = connector.getSessionFromTransaction();
      if (session != null) {
        transacted = true;

        // If a transaction is running, we can not receive any messages
        // in the same transaction.
        if (remoteSync) {
          throw new IllegalTransactionStateException(new org.mule.config.i18n.Message("jms", 2));
        }
      }
      // Should we be caching sessions?  Note this is not part of the JMS spec.
      // and is turned off by default.
      else if (event
          .getMessage()
          .getBooleanProperty(
              JmsConstants.CACHE_JMS_SESSIONS_PROPERTY, connector.isCacheJmsSessions())) {
        cached = true;
        if (cachedSession != null) {
          session = cachedSession;
        } else {
          // Retrieve a session from the connector
          session = connector.getSession(event.getEndpoint());
          cachedSession = session;
        }
      } else {
        // Retrieve a session from the connector
        session = connector.getSession(event.getEndpoint());
        if (event.getEndpoint().getTransactionConfig().isTransacted()) {
          transacted = true;
        }
      }

      // Add a reference to the JMS session used so that an EventAwareTransformer
      // can later retrieve it.
      // TODO Figure out a better way to accomplish this: MULE-1079
      // event.getMessage().setProperty(MuleProperties.MULE_JMS_SESSION, session);

      UMOEndpointURI endpointUri = event.getEndpoint().getEndpointURI();

      // determine if endpointUri is a queue or topic
      // the format is topic:destination
      boolean topic = false;
      String resourceInfo = endpointUri.getResourceInfo();
      topic = (resourceInfo != null && JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(resourceInfo));
      // TODO MULE20 remove resource info support
      if (!topic) {
        topic =
            MapUtils.getBooleanValue(
                event.getEndpoint().getProperties(), JmsConstants.TOPIC_PROPERTY, false);
      }

      Destination dest =
          connector.getJmsSupport().createDestination(session, endpointUri.getAddress(), topic);
      producer = connector.getJmsSupport().createProducer(session, dest, topic);

      Object message = event.getTransformedMessage();
      if (!(message instanceof Message)) {
        throw new DispatchException(
            new org.mule.config.i18n.Message(
                Messages.MESSAGE_NOT_X_IT_IS_TYPE_X_CHECK_TRANSFORMER_ON_X,
                "JMS message",
                message.getClass().getName(),
                connector.getName()),
            event.getMessage(),
            event.getEndpoint());
      }

      Message msg = (Message) message;
      if (event.getMessage().getCorrelationId() != null) {
        msg.setJMSCorrelationID(event.getMessage().getCorrelationId());
      }

      UMOMessage eventMsg = event.getMessage();

      // Some JMS implementations might not support the ReplyTo property.
      if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO)) {
        Object tempReplyTo = eventMsg.removeProperty(JmsConstants.JMS_REPLY_TO);
        if (tempReplyTo != null) {
          if (tempReplyTo instanceof Destination) {
            replyTo = (Destination) tempReplyTo;
          } else {
            boolean replyToTopic = false;
            String reply = tempReplyTo.toString();
            int i = reply.indexOf(":");
            if (i > -1) {
              String qtype = reply.substring(0, i);
              replyToTopic = "topic".equalsIgnoreCase(qtype);
              reply = reply.substring(i + 1);
            }
            replyTo = connector.getJmsSupport().createDestination(session, reply, replyToTopic);
          }
        }
        // Are we going to wait for a return event ?
        if (remoteSync && replyTo == null) {
          replyTo = connector.getJmsSupport().createTemporaryDestination(session, topic);
        }
        // Set the replyTo property
        if (replyTo != null) {
          msg.setJMSReplyTo(replyTo);
        }

        // Are we going to wait for a return event ?
        if (remoteSync) {
          consumer = connector.getJmsSupport().createConsumer(session, replyTo, topic);
        }
      }

      // QoS support
      String ttlString = (String) eventMsg.removeProperty(JmsConstants.TIME_TO_LIVE_PROPERTY);
      String priorityString = (String) eventMsg.removeProperty(JmsConstants.PRIORITY_PROPERTY);
      String persistentDeliveryString =
          (String) eventMsg.removeProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY);

      long ttl = Message.DEFAULT_TIME_TO_LIVE;
      int priority = Message.DEFAULT_PRIORITY;
      boolean persistent = Message.DEFAULT_DELIVERY_MODE == DeliveryMode.PERSISTENT;

      if (ttlString != null) {
        ttl = Long.parseLong(ttlString);
      }
      if (priorityString != null) {
        priority = Integer.parseInt(priorityString);
      }
      if (persistentDeliveryString != null) {
        persistent = Boolean.valueOf(persistentDeliveryString).booleanValue();
      }

      logger.debug("Sending message of type " + msg.getClass().getName());
      if (consumer != null && topic) {
        // need to register a listener for a topic
        Latch l = new Latch();
        ReplyToListener listener = new ReplyToListener(l);
        consumer.setMessageListener(listener);

        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);

        int timeout = event.getTimeout();
        logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
        l.await(timeout, TimeUnit.MILLISECONDS);
        consumer.setMessageListener(null);
        listener.release();
        Message result = listener.getMessage();
        if (result == null) {
          logger.debug("No message was returned via replyTo destination");
          return null;
        } else {
          UMOMessageAdapter adapter = connector.getMessageAdapter(result);
          return new MuleMessage(JmsMessageUtils.getObjectForMessage(result), adapter);
        }
      } else {
        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);
        if (consumer != null) {
          int timeout = event.getTimeout();
          logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo);
          Message result = consumer.receive(timeout);
          if (result == null) {
            logger.debug("No message was returned via replyTo destination");
            return null;
          } else {
            UMOMessageAdapter adapter = connector.getMessageAdapter(result);
            return new MuleMessage(JmsMessageUtils.getObjectForMessage(result), adapter);
          }
        }
      }
      return null;
    } finally {
      connector.closeQuietly(consumer);
      connector.closeQuietly(producer);

      // TODO I wonder if those temporary destinations also implement BOTH interfaces...
      // keep it 'simple' for now
      if (replyTo != null
          && (replyTo instanceof TemporaryQueue || replyTo instanceof TemporaryTopic)) {
        if (replyTo instanceof TemporaryQueue) {
          connector.closeQuietly((TemporaryQueue) replyTo);
        } else {
          // hope there are no more non-standard tricks from jms vendors here ;)
          connector.closeQuietly((TemporaryTopic) replyTo);
        }
      }

      // If the session is from the current transaction, it is up to the
      // transaction to close it.
      if (session != null && !cached && !transacted) {
        connector.closeQuietly(session);
      }
    }
  }
Example #12
0
  public void testReconnection() throws Exception {

    if (!isPrereqsMet(
        "org.mule.test.integration.providers.jms.activemq.JmsReconnectionTestCase.testReconnection()")) {
      return;
    }

    MuleManager.getInstance().start();
    MuleManager.getInstance().registerListener(this);

    // Start time
    long t0, t1;
    // Check that connection fails
    t0 = System.currentTimeMillis();
    while (true) {
      ConnectionNotification event =
          (ConnectionNotification) events.poll(TIME_OUT, TimeUnit.MILLISECONDS);
      if (event != null && event.getAction() == ConnectionNotification.CONNECTION_FAILED) {
        break;
      } else {
        fail("no notification event was received: " + event);
      }
      t1 = System.currentTimeMillis() - t0;
      if (t1 > TIME_OUT) {
        fail("No connection attempt");
      }
    }

    // Launch activemq
    ServerTools.launchActiveMq(BROKER_URL);
    // Check that connection succeed
    t0 = System.currentTimeMillis();
    while (true) {
      ConnectionNotification event =
          (ConnectionNotification) events.poll(TIME_OUT, TimeUnit.MILLISECONDS);
      if (event.getAction() == ConnectionNotification.CONNECTION_CONNECTED) {
        break;
      }
      t1 = System.currentTimeMillis() - t0;
      if (t1 > TIME_OUT) {
        fail("Connection should have succeeded");
      }
    }

    Thread.sleep(3000);
    MuleClient client = new MuleClient();

    MuleManager.getInstance()
        .registerListener(
            new FunctionalTestNotificationListener() {
              public void onNotification(UMOServerNotification notification) {
                if (notification.getSource().equals("test1")) {
                  eventLatch1.countDown();
                } else if (notification.getSource().equals("test2")) {
                  eventLatch2.countDown();
                }
              }
            });
    client.sendNoReceive("jms://reconnect.queue", "test1", null);
    // we should be able to do a sync call here and get a response message back
    // but there is a bug in ActiveMq that causes a null pointer
    // assertNotNull(m);
    // assertEquals("Received: test", m.getPayloadAsString());
    assertTrue(
        "1st Event should have been received", eventLatch1.await(15000L, TimeUnit.MILLISECONDS));

    // Kill activemq
    ServerTools.killActiveMq();
    // Check that the connection is lost
    t0 = System.currentTimeMillis();
    while (true) {
      ConnectionNotification event =
          (ConnectionNotification) events.poll(TIME_OUT, TimeUnit.MILLISECONDS);
      assertNotNull("Disconnect event should have been received", event);
      if (event.getAction() == ConnectionNotification.CONNECTION_DISCONNECTED) {
        break;
      }
      t1 = System.currentTimeMillis() - t0;
      if (t1 > TIME_OUT) {
        fail("Connection should have been lost");
      }
    }
    // Restart activemq
    ServerTools.launchActiveMq(BROKER_URL);
    // Check that connection succeed
    t0 = System.currentTimeMillis();
    while (true) {
      ConnectionNotification event =
          (ConnectionNotification) events.poll(TIME_OUT, TimeUnit.MILLISECONDS);
      if (event.getAction() == ConnectionNotification.CONNECTION_CONNECTED) {
        break;
      }
      t1 = System.currentTimeMillis() - t0;
      if (t1 > TIME_OUT) {
        fail("Connection should have succeeded");
      }
    }

    // Lets send another test message to esure everything is back up
    client.sendNoReceive("jms://reconnect.queue", "test2", null);
    assertTrue(
        "2nd Event should have been received", eventLatch2.await(15000L, TimeUnit.MILLISECONDS));
  }