/* * Licensed to DuraSpace under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * DuraSpace 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.fcrepo.camel.service.activemq; import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; import static org.apache.http.HttpStatus.SC_CREATED; import static org.apache.http.impl.client.HttpClientBuilder.create; import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.ops4j.pax.exam.CoreOptions.bundle; import static org.ops4j.pax.exam.CoreOptions.maven; import static org.ops4j.pax.exam.CoreOptions.streamBundle; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; import static org.ops4j.pax.exam.util.PathUtils.getBaseDir; import static org.osgi.framework.Bundle.ACTIVE; import static org.osgi.framework.Constants.OBJECTCLASS; import static org.osgi.framework.FrameworkUtil.createFilter; import static org.slf4j.LoggerFactory.getLogger; import java.io.File; import java.io.IOException; import javax.inject.Inject; import org.apache.camel.CamelContext; import org.apache.camel.component.mock.MockEndpoint; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.apache.karaf.features.FeaturesService; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.ConfigurationManager; import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerClass; import org.ops4j.pax.tinybundles.core.TinyBundles; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; /** * @author Aaron Coburn * @since May 4, 2016 */ @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) public class KarafIT { private static Logger LOGGER = getLogger(KarafIT.class); @Inject protected FeaturesService featuresService; @Inject protected BundleContext bundleContext; @Configuration public Option[] config() throws Exception { final ConfigurationManager cm = new ConfigurationManager(); final String artifactName = cm.getProperty("project.artifactId") + "-" + cm.getProperty("project.version"); final String fcrepoServiceBundle = "file:" + getBaseDir() + "/target/" + artifactName + ".jar"; final String fcrepoPort = cm.getProperty("fcrepo.dynamic.test.port"); final String jmsPort = cm.getProperty("fcrepo.dynamic.jms.port"); final String rmiRegistryPort = cm.getProperty("karaf.rmiRegistry.port"); final String rmiServerPort = cm.getProperty("karaf.rmiServer.port"); final String sshPort = cm.getProperty("karaf.ssh.port"); return new Option[] { karafDistributionConfiguration() .frameworkUrl(maven().groupId("org.apache.karaf").artifactId("apache-karaf") .versionAsInProject().type("zip")) .unpackDirectory(new File("target", "exam")) .useDeployFolder(false), logLevel(LogLevel.WARN), keepRuntimeFolder(), configureConsole().ignoreLocalConsole(), features(maven().groupId("org.apache.karaf.features").artifactId("standard") .type("xml").classifier("features").versionAsInProject(), "scr"), features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel") .type("xml").classifier("features").versionAsInProject(), "camel", "camel-blueprint", "camel-http4", "camel-jms"), features(maven().groupId("org.apache.activemq").artifactId("activemq-karaf") .type("xml").classifier("features").versionAsInProject(), "activemq-camel"), features(maven().groupId("org.fcrepo.camel").artifactId("fcrepo-camel") .type("xml").classifier("features").versionAsInProject(), "fcrepo-camel"), CoreOptions.systemProperty("fcrepo.port").value(fcrepoPort), CoreOptions.systemProperty("jms.port").value(jmsPort), CoreOptions.systemProperty("fcrepo.service.activemq.bundle").value(fcrepoServiceBundle), editConfigurationFilePut("etc/org.fcrepo.camel.service.activemq.cfg", "jms.brokerUrl", "tcp://localhost:" + jmsPort), editConfigurationFilePut("etc/org.ops4j.pax.logging.cfg", "log4j.logger.org.apache.camel.impl.converter", "ERROR, stdout"), bundle(fcrepoServiceBundle).start(), streamBundle( TinyBundles.bundle().add("OSGI-INF/blueprint/blueprint-test.xml", new File("src/test/resources/OSGI-INF/blueprint/blueprint-test.xml").toURL()) .set(Constants.BUNDLE_SYMBOLICNAME, "org.fcrepo.camel.service.activemq.test") .set(Constants.BUNDLE_MANIFESTVERSION, "2") .set(Constants.DYNAMICIMPORT_PACKAGE, "*") .build() ).start(), editConfigurationFilePut("etc/org.fcrepo.camel.service.activemq.cfg", "jms.consumers", "1"), editConfigurationFilePut("etc/org.fcrepo.camel.service.activemq.cfg", "jms.connections", "1"), editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort), editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort), editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort) }; } @Test public void testInstallation() throws Exception { assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-core"))); assertNotNull(bundleContext); assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("fcrepo.service.activemq.bundle")).getState()); } @Test public void testQueuingService() throws Exception { final CloseableHttpClient client = create().build(); final String baseUrl = "http://localhost:" + System.getProperty("fcrepo.port") + "/fcrepo/rest"; final CamelContext ctx = getOsgiService(CamelContext.class, "(camel.context.name=FcrepoQueuingService)", 10000); assertNotNull(ctx); final MockEndpoint resultEndpoint = (MockEndpoint) ctx.getEndpoint("mock:result"); resultEndpoint.reset(); final String url1 = post(baseUrl); final String url2 = post(baseUrl); resultEndpoint.expectedMessageCount(4); resultEndpoint.expectedHeaderValuesReceivedInAnyOrder(FCREPO_URI, url1, url2, baseUrl, baseUrl); assertIsSatisfied(resultEndpoint); } private String post(final String url) { final CloseableHttpClient httpclient = HttpClients.createDefault(); try { final HttpPost httppost = new HttpPost(url); final HttpResponse response = httpclient.execute(httppost); assertEquals(SC_CREATED, response.getStatusLine().getStatusCode()); return EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (IOException ex) { LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); return ""; } } private <T> T getOsgiService(final Class<T> type, final String filter, final long timeout) { try { final ServiceTracker tracker = new ServiceTracker(bundleContext, createFilter("(&(" + OBJECTCLASS + "=" + type.getName() + ")" + filter + ")"), null); tracker.open(true); final Object svc = type.cast(tracker.waitForService(timeout)); if (svc == null) { throw new RuntimeException("Gave up waiting for service " + filter); } return type.cast(svc); } catch (InvalidSyntaxException e) { throw new IllegalArgumentException("Invalid filter", e); } catch (InterruptedException e) { throw new RuntimeException(e); } } }