001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.camel.karaf; 019 020import static java.net.URI.create; 021import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 022import static org.apache.http.HttpStatus.SC_OK; 023import static org.apache.http.impl.client.HttpClients.createDefault; 024import static org.junit.Assert.assertEquals; 025import static org.junit.Assert.assertNotNull; 026import static org.junit.Assert.assertTrue; 027import static org.ops4j.pax.exam.CoreOptions.bundle; 028import static org.ops4j.pax.exam.CoreOptions.maven; 029import static org.ops4j.pax.exam.CoreOptions.mavenBundle; 030import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; 031import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; 032import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; 033import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; 034import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; 035import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; 036import static org.ops4j.pax.exam.util.PathUtils.getBaseDir; 037import static org.osgi.framework.Bundle.ACTIVE; 038import static org.osgi.framework.Constants.OBJECTCLASS; 039import static org.osgi.framework.FrameworkUtil.createFilter; 040import static org.slf4j.LoggerFactory.getLogger; 041 042import java.io.File; 043import java.net.URI; 044import javax.inject.Inject; 045 046import org.apache.camel.CamelContext; 047import org.apache.camel.component.mock.MockEndpoint; 048import org.apache.http.client.methods.CloseableHttpResponse; 049import org.apache.http.client.methods.HttpGet; 050import org.apache.http.client.methods.HttpPost; 051import org.apache.http.entity.StringEntity; 052import org.apache.http.impl.client.CloseableHttpClient; 053import org.apache.karaf.features.FeaturesService; 054import org.fcrepo.client.FcrepoClient; 055import org.junit.Test; 056import org.junit.runner.RunWith; 057import org.ops4j.pax.exam.Configuration; 058import org.ops4j.pax.exam.ConfigurationManager; 059import org.ops4j.pax.exam.CoreOptions; 060import org.ops4j.pax.exam.Option; 061import org.ops4j.pax.exam.junit.PaxExam; 062import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; 063import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; 064import org.ops4j.pax.exam.spi.reactors.PerClass; 065import org.osgi.framework.BundleContext; 066import org.osgi.framework.InvalidSyntaxException; 067import org.osgi.util.tracker.ServiceTracker; 068import org.slf4j.Logger; 069 070/** 071 * @author Aaron Coburn 072 * @since February 8, 2016 073 */ 074@RunWith(PaxExam.class) 075@ExamReactorStrategy(PerClass.class) 076public class KarafIT { 077 078 private static Logger LOGGER = getLogger(KarafIT.class); 079 080 @Inject 081 protected FeaturesService featuresService; 082 083 @Inject 084 protected BundleContext bundleContext; 085 086 @Configuration 087 public Option[] config() { 088 final ConfigurationManager cm = new ConfigurationManager(); 089 final String fcrepoPort = cm.getProperty("fcrepo.dynamic.test.port"); 090 final String jmsPort = cm.getProperty("fcrepo.dynamic.jms.port"); 091 final String reindexingPort = cm.getProperty("fcrepo.dynamic.reindexing.port"); 092 final String rmiRegistryPort = cm.getProperty("karaf.rmiRegistry.port"); 093 final String rmiServerPort = cm.getProperty("karaf.rmiServer.port"); 094 final String sshPort = cm.getProperty("karaf.ssh.port"); 095 final String fcrepoBaseUrl = "localhost:" + fcrepoPort + "/fcrepo/rest"; 096 097 final String version = cm.getProperty("project.version"); 098 final String fcrepoAudit = getBundleUri("fcrepo-audit-triplestore", version); 099 final String fcrepoFixity = getBundleUri("fcrepo-fixity", version); 100 final String fcrepoReindexing = getBundleUri("fcrepo-reindexing", version); 101 final String fcrepoSerialization = getBundleUri("fcrepo-serialization", version); 102 final String fcrepoIndexingSolr = getBundleUri("fcrepo-indexing-solr", version); 103 final String fcrepoIndexingTriplestore = getBundleUri("fcrepo-indexing-triplestore", version); 104 final String fcrepoServiceAmq = getBundleUri("fcrepo-service-activemq", version); 105 final String fcrepoService = getBundleUri("fcrepo-service-camel", version); 106 107 return new Option[] { 108 karafDistributionConfiguration() 109 .frameworkUrl(maven().groupId("org.apache.karaf").artifactId("apache-karaf") 110 .versionAsInProject().type("zip")) 111 .unpackDirectory(new File("target", "exam")) 112 .useDeployFolder(false), 113 logLevel(LogLevel.WARN), 114 keepRuntimeFolder(), 115 configureConsole().ignoreLocalConsole(), 116 features(maven().groupId("org.apache.karaf.features").artifactId("standard") 117 .versionAsInProject().classifier("features").type("xml"), "scr"), 118 features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel") 119 .type("xml").classifier("features").versionAsInProject(), "camel-mustache", 120 "camel-blueprint", "camel-http4", "camel-spring", "camel-exec", "camel-jetty9", 121 "camel-jacksonxml"), 122 features(maven().groupId("org.apache.activemq").artifactId("activemq-karaf") 123 .type("xml").classifier("features").versionAsInProject(), "activemq-camel"), 124 features(maven().groupId("org.fcrepo.camel").artifactId("fcrepo-camel") 125 .type("xml").classifier("features").versionAsInProject(), "fcrepo-camel"), 126 mavenBundle().groupId("org.codehaus.woodstox").artifactId("woodstox-core-asl").versionAsInProject(), 127 128 CoreOptions.systemProperty("o.f.c.serialization-bundle").value(fcrepoSerialization), 129 CoreOptions.systemProperty("o.f.c.fixity-bundle").value(fcrepoFixity), 130 CoreOptions.systemProperty("o.f.c.reindexing-bundle").value(fcrepoReindexing), 131 CoreOptions.systemProperty("o.f.c.a.triplestore-bundle").value(fcrepoAudit), 132 CoreOptions.systemProperty("o.f.c.i.triplestore-bundle").value(fcrepoIndexingTriplestore), 133 CoreOptions.systemProperty("o.f.c.i.solr-bundle").value(fcrepoIndexingSolr), 134 CoreOptions.systemProperty("o.f.c.s.activemq-bundle").value(fcrepoServiceAmq), 135 CoreOptions.systemProperty("o.f.c.s.camel-bundle").value(fcrepoService), 136 137 bundle(fcrepoAudit).start(), 138 bundle(fcrepoIndexingSolr).start(), 139 bundle(fcrepoIndexingTriplestore).start(), 140 bundle(fcrepoFixity).start(), 141 bundle(fcrepoSerialization).start(), 142 bundle(fcrepoReindexing).start(), 143 bundle(fcrepoServiceAmq).start(), 144 bundle(fcrepoService).start(), 145 146 CoreOptions.systemProperty("fcrepo.port").value(fcrepoPort), 147 CoreOptions.systemProperty("karaf.reindexing.port").value(reindexingPort), 148 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort), 149 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort), 150 editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort), 151 editConfigurationFilePut("etc/org.fcrepo.camel.serialization.cfg", "serialization.descriptions", 152 "data/tmp/descriptions"), 153 editConfigurationFilePut("etc/org.fcrepo.camel.reindexing.cfg", "rest.port", reindexingPort), 154 editConfigurationFilePut("etc/org.fcrepo.camel.service.cfg", "fcrepo.baseUrl", fcrepoBaseUrl), 155 editConfigurationFilePut("etc/org.fcrepo.camel.service.activemq.cfg", "jms.brokerUrl", 156 "tcp://localhost:" + jmsPort) 157 }; 158 } 159 160 161 @Test 162 public void testInstallation() throws Exception { 163 164 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-core"))); 165 assertTrue(featuresService.isInstalled(featuresService.getFeature("fcrepo-camel"))); 166 assertTrue(featuresService.isInstalled(featuresService.getFeature("activemq-camel"))); 167 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-blueprint"))); 168 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-http4"))); 169 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-jetty9"))); 170 assertNotNull(bundleContext); 171 172 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.serialization-bundle")).getState()); 173 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.fixity-bundle")).getState()); 174 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.reindexing-bundle")).getState()); 175 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.i.solr-bundle")).getState()); 176 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.i.triplestore-bundle")).getState()); 177 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.s.activemq-bundle")).getState()); 178 assertEquals(ACTIVE, bundleContext.getBundle(System.getProperty("o.f.c.s.camel-bundle")).getState()); 179 } 180 181 @Test 182 public void testReindexingService() throws Exception { 183 final CamelContext ctx = getOsgiService(CamelContext.class, "(camel.context.name=FcrepoIndexer)", 10000); 184 assertNotNull(ctx); 185 186 // We aren't running solr or a triplestore, so stop these to prevent 187 // unnecessary errors. 188 bundleContext.getBundle(System.getProperty("o.f.c.i.solr-bundle")).stop(); 189 bundleContext.getBundle(System.getProperty("o.f.c.i.triplestore-bundle")).stop(); 190 bundleContext.getBundle(System.getProperty("o.f.c.a.triplestore-bundle")).stop(); 191 192 final FcrepoClient fcrepoClient = new FcrepoClient(null, null, null, true); 193 final URI baseUrl = create("http://localhost:" + System.getProperty("fcrepo.port") + "/fcrepo/rest"); 194 final URI url1 = fcrepoClient.post(baseUrl, null, null).getLocation(); 195 final URI url2 = fcrepoClient.post(baseUrl, null, null).getLocation(); 196 fcrepoClient.post(url1, null, null); 197 fcrepoClient.post(url2, null, null); 198 199 final MockEndpoint resultEndpoint = (MockEndpoint) ctx.getEndpoint("mock:results"); 200 resultEndpoint.expectedMessageCount(5); 201 202 final CloseableHttpClient client = createDefault(); 203 final String reindexingUrl = "http://localhost:" + System.getProperty("karaf.reindexing.port") + "/reindexing/"; 204 try (final CloseableHttpResponse response = client.execute(new HttpGet(reindexingUrl))) { 205 assertEquals(SC_OK, response.getStatusLine().getStatusCode()); 206 } 207 208 final HttpPost post = new HttpPost(reindexingUrl); 209 post.addHeader("Content-Type", "application/json"); 210 post.setEntity(new StringEntity("[\"mock:results\"]")); 211 try (final CloseableHttpResponse response = client.execute(post)) { 212 assertEquals(SC_OK, response.getStatusLine().getStatusCode()); 213 } 214 215 assertIsSatisfied(resultEndpoint); 216 } 217 218 private <T> T getOsgiService(final Class<T> type, final String filter, final long timeout) { 219 try { 220 final ServiceTracker tracker = new ServiceTracker(bundleContext, 221 createFilter("(&(" + OBJECTCLASS + "=" + type.getName() + ")" + filter + ")"), null); 222 tracker.open(true); 223 final Object svc = type.cast(tracker.waitForService(timeout)); 224 if (svc == null) { 225 throw new RuntimeException("Gave up waiting for service " + filter); 226 } 227 return type.cast(svc); 228 } catch (InvalidSyntaxException e) { 229 throw new IllegalArgumentException("Invalid filter", e); 230 } catch (InterruptedException e) { 231 throw new RuntimeException(e); 232 } 233 } 234 235 private static String getBundleUri(final String artifactId, final String version) { 236 final File artifact = new File(getBaseDir() + "/../" + artifactId + "/target/" + 237 artifactId + "-" + version + ".jar"); 238 if (artifact.exists()) { 239 return artifact.toURI().toString(); 240 } 241 return "mvn:org.fcrepo.camel/" + artifactId + "/" + version; 242 } 243 244}