Search in sources :

Example 1 with ConsumerCallback

use of org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback in project nifi by apache.

the class ConsumeJMS method rendezvousWithJms.

/**
 * Will construct a {@link FlowFile} containing the body of the consumed JMS
 * message (if {@link JMSResponse} returned by {@link JMSConsumer} is not
 * null) and JMS properties that came with message which are added to a
 * {@link FlowFile} as attributes, transferring {@link FlowFile} to
 * 'success' {@link Relationship}.
 */
@Override
protected void rendezvousWithJms(final ProcessContext context, final ProcessSession processSession, final JMSConsumer consumer) throws ProcessException {
    final String destinationName = context.getProperty(DESTINATION).evaluateAttributeExpressions().getValue();
    final Boolean durableBoolean = context.getProperty(DURABLE_SUBSCRIBER).evaluateAttributeExpressions().asBoolean();
    final boolean durable = durableBoolean == null ? false : durableBoolean;
    final Boolean sharedBoolean = context.getProperty(SHARED_SUBSCRIBER).evaluateAttributeExpressions().asBoolean();
    final boolean shared = sharedBoolean == null ? false : sharedBoolean;
    final String subscriptionName = context.getProperty(SUBSCRIPTION_NAME).evaluateAttributeExpressions().getValue();
    final String charset = context.getProperty(CHARSET).evaluateAttributeExpressions().getValue();
    consumer.consume(destinationName, durable, shared, subscriptionName, charset, new ConsumerCallback() {

        @Override
        public void accept(final JMSResponse response) {
            if (response == null) {
                return;
            }
            FlowFile flowFile = processSession.create();
            flowFile = processSession.write(flowFile, out -> out.write(response.getMessageBody()));
            final Map<String, String> jmsHeaders = response.getMessageHeaders();
            final Map<String, String> jmsProperties = response.getMessageProperties();
            flowFile = ConsumeJMS.this.updateFlowFileAttributesWithJMSAttributes(jmsHeaders, flowFile, processSession);
            flowFile = ConsumeJMS.this.updateFlowFileAttributesWithJMSAttributes(jmsProperties, flowFile, processSession);
            flowFile = processSession.putAttribute(flowFile, JMS_SOURCE_DESTINATION_NAME, destinationName);
            processSession.getProvenanceReporter().receive(flowFile, destinationName);
            processSession.transfer(flowFile, REL_SUCCESS);
            processSession.commit();
        }
    });
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) JMSResponse(org.apache.nifi.jms.processors.JMSConsumer.JMSResponse) ConsumerCallback(org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with ConsumerCallback

use of org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback in project nifi by apache.

the class JMSPublisherConsumerIT method validateConsumeWithCustomHeadersAndProperties.

@Test
public void validateConsumeWithCustomHeadersAndProperties() throws Exception {
    final String destinationName = "validateConsumeWithCustomHeadersAndProperties";
    JmsTemplate jmsTemplate = CommonTest.buildJmsTemplateForDestination(false);
    try {
        jmsTemplate.send(destinationName, new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage message = session.createTextMessage("hello from the other side");
                message.setStringProperty("foo", "foo");
                message.setBooleanProperty("bar", false);
                message.setJMSReplyTo(session.createQueue("fooQueue"));
                return message;
            }
        });
        JMSConsumer consumer = new JMSConsumer((CachingConnectionFactory) jmsTemplate.getConnectionFactory(), jmsTemplate, mock(ComponentLog.class));
        final AtomicBoolean callbackInvoked = new AtomicBoolean();
        consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

            @Override
            public void accept(JMSResponse response) {
                callbackInvoked.set(true);
                assertEquals("hello from the other side", new String(response.getMessageBody()));
                assertEquals("fooQueue", response.getMessageHeaders().get(JmsHeaders.REPLY_TO));
                assertEquals("foo", response.getMessageProperties().get("foo"));
                assertEquals("false", response.getMessageProperties().get("bar"));
            }
        });
        assertTrue(callbackInvoked.get());
    } finally {
        ((CachingConnectionFactory) jmsTemplate.getConnectionFactory()).destroy();
    }
}
Also used : TextMessage(javax.jms.TextMessage) BytesMessage(javax.jms.BytesMessage) Message(javax.jms.Message) JMSResponse(org.apache.nifi.jms.processors.JMSConsumer.JMSResponse) ConsumerCallback(org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback) JMSException(javax.jms.JMSException) ComponentLog(org.apache.nifi.logging.ComponentLog) MessageCreator(org.springframework.jms.core.MessageCreator) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CachingConnectionFactory(org.springframework.jms.connection.CachingConnectionFactory) JmsTemplate(org.springframework.jms.core.JmsTemplate) TextMessage(javax.jms.TextMessage) Session(javax.jms.Session) Test(org.junit.Test)

Example 3 with ConsumerCallback

use of org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback in project nifi by apache.

the class JMSPublisherConsumerIT method validateMessageRedeliveryWhenNotAcked.

@Test(timeout = 10000)
public void validateMessageRedeliveryWhenNotAcked() throws Exception {
    String destinationName = "validateMessageRedeliveryWhenNotAcked";
    JmsTemplate jmsTemplate = CommonTest.buildJmsTemplateForDestination(false);
    try {
        JMSPublisher publisher = new JMSPublisher((CachingConnectionFactory) jmsTemplate.getConnectionFactory(), jmsTemplate, mock(ComponentLog.class));
        publisher.publish(destinationName, "1".getBytes(StandardCharsets.UTF_8));
        publisher.publish(destinationName, "2".getBytes(StandardCharsets.UTF_8));
        JMSConsumer consumer = new JMSConsumer((CachingConnectionFactory) jmsTemplate.getConnectionFactory(), jmsTemplate, mock(ComponentLog.class));
        final AtomicBoolean callbackInvoked = new AtomicBoolean();
        try {
            consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

                @Override
                public void accept(JMSResponse response) {
                    callbackInvoked.set(true);
                    assertEquals("1", new String(response.getMessageBody()));
                    throw new RuntimeException("intentional to avoid explicit ack");
                }
            });
        } catch (Exception e) {
        // expected
        }
        assertTrue(callbackInvoked.get());
        callbackInvoked.set(false);
        // should receive the same message, but will process it successfully
        while (!callbackInvoked.get()) {
            consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

                @Override
                public void accept(JMSResponse response) {
                    if (response == null) {
                        return;
                    }
                    callbackInvoked.set(true);
                    assertEquals("1", new String(response.getMessageBody()));
                }
            });
        }
        assertTrue(callbackInvoked.get());
        callbackInvoked.set(false);
        // receiving next message and fail again
        try {
            while (!callbackInvoked.get()) {
                consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

                    @Override
                    public void accept(JMSResponse response) {
                        if (response == null) {
                            return;
                        }
                        callbackInvoked.set(true);
                        assertEquals("2", new String(response.getMessageBody()));
                        throw new RuntimeException("intentional to avoid explicit ack");
                    }
                });
            }
        } catch (Exception e) {
        // ignore
        }
        assertTrue(callbackInvoked.get());
        callbackInvoked.set(false);
        // should receive the same message, but will process it successfully
        try {
            while (!callbackInvoked.get()) {
                consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

                    @Override
                    public void accept(JMSResponse response) {
                        if (response == null) {
                            return;
                        }
                        callbackInvoked.set(true);
                        assertEquals("2", new String(response.getMessageBody()));
                    }
                });
            }
        } catch (Exception e) {
        // ignore
        }
    } finally {
        ((CachingConnectionFactory) jmsTemplate.getConnectionFactory()).destroy();
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JMSResponse(org.apache.nifi.jms.processors.JMSConsumer.JMSResponse) CachingConnectionFactory(org.springframework.jms.connection.CachingConnectionFactory) JmsTemplate(org.springframework.jms.core.JmsTemplate) ConsumerCallback(org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback) ComponentLog(org.apache.nifi.logging.ComponentLog) JMSException(javax.jms.JMSException) Test(org.junit.Test)

Example 4 with ConsumerCallback

use of org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback in project nifi by apache.

the class JMSPublisherConsumerIT method validateFailOnUnsupportedMessageType.

/**
 * At the moment the only two supported message types are TextMessage and
 * BytesMessage which is sufficient for the type if JMS use cases NiFi is
 * used. The may change to the point where all message types are supported
 * at which point this test will no be longer required.
 */
@Test
public void validateFailOnUnsupportedMessageType() throws Exception {
    final String destinationName = "validateFailOnUnsupportedMessageType";
    JmsTemplate jmsTemplate = CommonTest.buildJmsTemplateForDestination(false);
    try {
        jmsTemplate.send(destinationName, new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                return session.createObjectMessage();
            }
        });
        JMSConsumer consumer = new JMSConsumer((CachingConnectionFactory) jmsTemplate.getConnectionFactory(), jmsTemplate, mock(ComponentLog.class));
        consumer.consume(destinationName, false, false, null, "UTF-8", new ConsumerCallback() {

            @Override
            public void accept(JMSResponse response) {
            // noop
            }
        });
    } finally {
        ((CachingConnectionFactory) jmsTemplate.getConnectionFactory()).destroy();
    }
}
Also used : TextMessage(javax.jms.TextMessage) BytesMessage(javax.jms.BytesMessage) Message(javax.jms.Message) JMSResponse(org.apache.nifi.jms.processors.JMSConsumer.JMSResponse) CachingConnectionFactory(org.springframework.jms.connection.CachingConnectionFactory) JmsTemplate(org.springframework.jms.core.JmsTemplate) ConsumerCallback(org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback) JMSException(javax.jms.JMSException) ComponentLog(org.apache.nifi.logging.ComponentLog) MessageCreator(org.springframework.jms.core.MessageCreator) Session(javax.jms.Session) Test(org.junit.Test)

Example 5 with ConsumerCallback

use of org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback in project nifi by apache.

the class JMSPublisherConsumerIT method testMultipleThreads.

@Test(timeout = 20000)
public void testMultipleThreads() throws Exception {
    String destinationName = "testMultipleThreads";
    JmsTemplate publishTemplate = CommonTest.buildJmsTemplateForDestination(false);
    final CountDownLatch consumerTemplateCloseCount = new CountDownLatch(4);
    try {
        JMSPublisher publisher = new JMSPublisher((CachingConnectionFactory) publishTemplate.getConnectionFactory(), publishTemplate, mock(ComponentLog.class));
        for (int i = 0; i < 4000; i++) {
            publisher.publish(destinationName, String.valueOf(i).getBytes(StandardCharsets.UTF_8));
        }
        final AtomicInteger msgCount = new AtomicInteger(0);
        final ConsumerCallback callback = new ConsumerCallback() {

            @Override
            public void accept(JMSResponse response) {
                msgCount.incrementAndGet();
            }
        };
        final Thread[] threads = new Thread[4];
        for (int i = 0; i < 4; i++) {
            final Thread t = new Thread(() -> {
                JmsTemplate consumeTemplate = CommonTest.buildJmsTemplateForDestination(false);
                try {
                    JMSConsumer consumer = new JMSConsumer((CachingConnectionFactory) consumeTemplate.getConnectionFactory(), consumeTemplate, mock(ComponentLog.class));
                    for (int j = 0; j < 1000 && msgCount.get() < 4000; j++) {
                        consumer.consume(destinationName, false, false, null, "UTF-8", callback);
                    }
                } finally {
                    ((CachingConnectionFactory) consumeTemplate.getConnectionFactory()).destroy();
                    consumerTemplateCloseCount.countDown();
                }
            });
            threads[i] = t;
            t.start();
        }
        int iterations = 0;
        while (msgCount.get() < 4000) {
            Thread.sleep(10L);
            if (++iterations % 100 == 0) {
                System.out.println(msgCount.get() + " messages received so far");
            }
        }
    } finally {
        ((CachingConnectionFactory) publishTemplate.getConnectionFactory()).destroy();
        consumerTemplateCloseCount.await();
    }
}
Also used : JMSResponse(org.apache.nifi.jms.processors.JMSConsumer.JMSResponse) ConsumerCallback(org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback) CountDownLatch(java.util.concurrent.CountDownLatch) ComponentLog(org.apache.nifi.logging.ComponentLog) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CachingConnectionFactory(org.springframework.jms.connection.CachingConnectionFactory) JmsTemplate(org.springframework.jms.core.JmsTemplate) Test(org.junit.Test)

Aggregations

ConsumerCallback (org.apache.nifi.jms.processors.JMSConsumer.ConsumerCallback)5 JMSResponse (org.apache.nifi.jms.processors.JMSConsumer.JMSResponse)5 ComponentLog (org.apache.nifi.logging.ComponentLog)4 Test (org.junit.Test)4 CachingConnectionFactory (org.springframework.jms.connection.CachingConnectionFactory)4 JmsTemplate (org.springframework.jms.core.JmsTemplate)4 JMSException (javax.jms.JMSException)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 BytesMessage (javax.jms.BytesMessage)2 Message (javax.jms.Message)2 Session (javax.jms.Session)2 TextMessage (javax.jms.TextMessage)2 MessageCreator (org.springframework.jms.core.MessageCreator)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 FlowFile (org.apache.nifi.flowfile.FlowFile)1