/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.jms.cf;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.ServiceLoader;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
/**
*
*/
public class JMSConnectionFactoryProviderTest {
private static Logger logger = LoggerFactory.getLogger(JMSConnectionFactoryProviderTest.class);
@Test
public void validateFullConfigWithUserLib() throws Exception {
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI, "myhost:1234");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH,
new File("test-lib").getAbsolutePath()); // see README in 'test-lib' dir for more info
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"org.apache.nifi.jms.testcflib.TestConnectionFactory");
runner.setProperty(cfProvider, "Foo", "foo");
runner.setProperty(cfProvider, "Bar", "3");
runner.enableControllerService(cfProvider);
runner.assertValid(cfProvider);
ConnectionFactory cf = cfProvider.getConnectionFactory();
assertNotNull(cf);
assertEquals("org.apache.nifi.jms.testcflib.TestConnectionFactory", cf.getClass().getName());
assertEquals("myhost", this.get("getHost", cf));
assertEquals(1234, ((Integer) this.get("getPort", cf)).intValue());
assertEquals("foo", this.get("getFoo", cf));
assertEquals(3, ((Integer) this.get("getBar", cf)).intValue());
}
@Test(expected = AssertionError.class)
public void validateOnConfigureFailsIfCNFonConnectionFactory() throws Exception {
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI, "myhost:1234");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH, "test-lib");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"foo.bar.NonExistingConnectionFactory");
runner.enableControllerService(cfProvider);
}
@Test
public void validateNotValidForNonExistingLibPath() throws Exception {
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI, "myhost:1234");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH, "foo");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"org.apache.nifi.jms.testcflib.TestConnectionFactory");
runner.assertNotValid(cfProvider);
}
@Test(expected = AssertionError.class)
public void validateFailsIfURINotHostPortAndNotActiveMQ() throws Exception {
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI, "myhost");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH, "test-lib");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"org.apache.nifi.jms.testcflib.TestConnectionFactory");
runner.enableControllerService(cfProvider);
runner.assertNotValid(cfProvider);
}
@Test
public void validateNotValidForNonDirectoryPath() throws Exception {
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI, "myhost:1234");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH, "pom.xml");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"org.apache.nifi.jms.testcflib.TestConnectionFactory");
runner.assertNotValid(cfProvider);
}
@Test(expected = IllegalStateException.class)
public void validateGetConnectionFactoryFailureIfServiceNotConfigured() throws Exception {
new JMSConnectionFactoryProvider().getConnectionFactory();
}
/**
* This test simply validates that {@link ConnectionFactory} can be setup by
* pointing to the location of the client libraries at runtime. It uses
* ActiveMQ which is not present at the POM but instead pulled from Maven
* repo using {@link TestUtils#setupActiveMqLibForTesting(boolean)}, which
* implies that for this test to run the computer must be connected to the
* Internet. If computer is not connected to the Internet, this test will
* quietly fail logging a message.
*/
@Test
public void validateFactoryCreationWithActiveMQLibraries() throws Exception {
try {
String libPath = TestUtils.setupActiveMqLibForTesting(true);
TestRunner runner = TestRunners.newTestRunner(mock(Processor.class));
JMSConnectionFactoryProvider cfProvider = new JMSConnectionFactoryProvider();
runner.addControllerService("cfProvider", cfProvider);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.BROKER_URI,
"vm://localhost?broker.persistent=false");
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CLIENT_LIB_DIR_PATH, libPath);
runner.setProperty(cfProvider, JMSConnectionFactoryProvider.CONNECTION_FACTORY_IMPL,
"org.apache.activemq.ActiveMQConnectionFactory");
runner.enableControllerService(cfProvider);
runner.assertValid(cfProvider);
Connection connection = cfProvider.getConnectionFactory().createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination queue = session.createQueue("myqueue");
MessageProducer producer = session.createProducer(queue);
MessageConsumer consumer = session.createConsumer(queue);
TextMessage message = session.createTextMessage("Hello");
producer.send(message);
assertEquals("Hello", ((TextMessage) consumer.receive()).getText());
connection.stop();
connection.close();
} catch (Exception e) {
logger.error("'validateFactoryCreationWithActiveMQLibraries' failed due to ", e);
}
}
@Test
public void validateServiceIsLocatableViaServiceLoader() {
ServiceLoader<ControllerService> loader = ServiceLoader.<ControllerService> load(ControllerService.class);
Iterator<ControllerService> iter = loader.iterator();
boolean present = false;
while (iter.hasNext()) {
ControllerService cs = iter.next();
assertTrue(cs instanceof JMSConnectionFactoryProviderDefinition);
present = true;
}
assertTrue(present);
}
@SuppressWarnings("unchecked")
private <T> T get(String methodName, ConnectionFactory cf) throws Exception {
Method m = Utils.findMethod(methodName, cf.getClass());
return (T) m.invoke(cf);
}
}