001/* 002 * Copyright 2016 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.camel.service; 017 018import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 019import static org.apache.http.HttpStatus.SC_CREATED; 020import static org.apache.http.impl.client.HttpClients.createDefault; 021import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL; 022import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER; 023import static org.junit.Assert.assertEquals; 024import static org.junit.Assert.assertNotNull; 025import static org.junit.Assert.assertTrue; 026import static org.ops4j.pax.exam.CoreOptions.bundle; 027import static org.ops4j.pax.exam.CoreOptions.maven; 028import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; 029import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; 030import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; 031import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; 032import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; 033import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; 034import static org.ops4j.pax.exam.util.PathUtils.getBaseDir; 035import static org.osgi.framework.Bundle.ACTIVE; 036import static org.osgi.framework.Constants.OBJECTCLASS; 037import static org.osgi.framework.FrameworkUtil.createFilter; 038import static org.slf4j.LoggerFactory.getLogger; 039 040import java.io.File; 041import java.io.IOException; 042import java.util.HashMap; 043import java.util.Map; 044import javax.inject.Inject; 045 046import org.apache.camel.CamelContext; 047import org.apache.camel.ProducerTemplate; 048import org.apache.camel.component.mock.MockEndpoint; 049import org.apache.http.HttpResponse; 050import org.apache.http.client.methods.HttpPost; 051import org.apache.http.impl.client.CloseableHttpClient; 052import org.apache.http.util.EntityUtils; 053import org.apache.karaf.features.FeaturesService; 054import org.junit.Test; 055import org.junit.runner.RunWith; 056import org.ops4j.pax.exam.Configuration; 057import org.ops4j.pax.exam.ConfigurationManager; 058import org.ops4j.pax.exam.CoreOptions; 059import org.ops4j.pax.exam.Option; 060import org.ops4j.pax.exam.junit.PaxExam; 061import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; 062import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; 063import org.ops4j.pax.exam.spi.reactors.PerClass; 064import org.osgi.framework.BundleContext; 065import org.osgi.framework.InvalidSyntaxException; 066import org.osgi.util.tracker.ServiceTracker; 067import org.slf4j.Logger; 068 069/** 070 * @author Aaron Coburn 071 * @since July 21, 2016 072 */ 073@RunWith(PaxExam.class) 074@ExamReactorStrategy(PerClass.class) 075public class KarafIT { 076 077 private final CloseableHttpClient httpclient = createDefault(); 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() throws Exception { 088 final ConfigurationManager cm = new ConfigurationManager(); 089 final String artifactName = cm.getProperty("project.artifactId") + "-" + cm.getProperty("project.version"); 090 final String fcrepoServiceBundle = "file:" + getBaseDir() + "/target/" + artifactName + ".jar"; 091 final String fcrepoPort = cm.getProperty("fcrepo.dynamic.test.port"); 092 final String jmsPort = cm.getProperty("fcrepo.dynamic.jms.port"); 093 final String rmiRegistryPort = cm.getProperty("karaf.rmiRegistry.port"); 094 final String rmiServerPort = cm.getProperty("karaf.rmiServer.port"); 095 final String sshPort = cm.getProperty("karaf.ssh.port"); 096 return new Option[] { 097 karafDistributionConfiguration() 098 .frameworkUrl(maven().groupId("org.apache.karaf").artifactId("apache-karaf") 099 .versionAsInProject().type("zip")) 100 .unpackDirectory(new File("target", "exam")) 101 .useDeployFolder(false), 102 logLevel(LogLevel.WARN), 103 keepRuntimeFolder(), 104 configureConsole().ignoreLocalConsole(), 105 features(maven().groupId("org.apache.karaf.features").artifactId("standard") 106 .type("xml").classifier("features").versionAsInProject(), "scr"), 107 features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel") 108 .type("xml").classifier("features").versionAsInProject(), "camel", 109 "camel-blueprint"), 110 features(maven().groupId("org.fcrepo.camel").artifactId("fcrepo-camel") 111 .type("xml").classifier("features").versionAsInProject(), "fcrepo-camel"), 112 113 CoreOptions.systemProperty("fcrepo.port").value(fcrepoPort), 114 CoreOptions.systemProperty("jms.port").value(jmsPort), 115 CoreOptions.systemProperty("fcrepo.service.bundle").value(fcrepoServiceBundle), 116 117 editConfigurationFilePut("etc/org.fcrepo.camel.service.cfg", "fcrepo.baseUrl", 118 "http://localhost:" + fcrepoPort + "/fcrepo/rest"), 119 120 bundle(fcrepoServiceBundle).start(), 121 122 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort), 123 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort), 124 editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort) 125 }; 126 } 127 128 @Test 129 public void testInstallation() throws Exception { 130 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-core"))); 131 assertTrue(featuresService.isInstalled(featuresService.getFeature("fcrepo-camel"))); 132 assertNotNull(bundleContext); 133 assertEquals(ACTIVE, 134 bundleContext.getBundle(System.getProperty("fcrepo.service.bundle")).getState()); 135 } 136 137 @Test 138 public void testService() throws Exception { 139 final String baseUrl = "http://localhost:" + System.getProperty("fcrepo.port") + "/fcrepo/rest"; 140 final CamelContext ctx = getOsgiService(CamelContext.class, 141 "(camel.context.name=FcrepoService)", 10000); 142 143 assertNotNull(ctx); 144 145 final MockEndpoint resultEndpoint = (MockEndpoint) ctx.getEndpoint("mock:result"); 146 147 final String url1 = post(baseUrl).replace(baseUrl, ""); 148 final String url2 = post(baseUrl).replace(baseUrl, ""); 149 150 final ProducerTemplate template = ctx.createProducerTemplate(); 151 final Map<String, Object> headers = new HashMap<>(); 152 headers.put(FCREPO_BASE_URL, baseUrl); 153 headers.put(FCREPO_IDENTIFIER, url1); 154 template.sendBodyAndHeaders(ctx.getEndpoint("direct:start"), null, headers); 155 156 headers.put(FCREPO_IDENTIFIER, url2); 157 template.sendBodyAndHeaders(ctx.getEndpoint("direct:start"), null, headers); 158 159 resultEndpoint.expectedMinimumMessageCount(2); 160 assertIsSatisfied(resultEndpoint); 161 } 162 163 private String post(final String url) { 164 try { 165 final HttpPost httppost = new HttpPost(url); 166 final HttpResponse response = httpclient.execute(httppost); 167 assertEquals(SC_CREATED, response.getStatusLine().getStatusCode()); 168 return EntityUtils.toString(response.getEntity(), "UTF-8"); 169 } catch (IOException ex) { 170 LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); 171 return ""; 172 } 173 } 174 175 private <T> T getOsgiService(final Class<T> type, final String filter, final long timeout) { 176 try { 177 final ServiceTracker tracker = new ServiceTracker(bundleContext, 178 createFilter("(&(" + OBJECTCLASS + "=" + type.getName() + ")" + filter + ")"), null); 179 tracker.open(true); 180 final Object svc = type.cast(tracker.waitForService(timeout)); 181 if (svc == null) { 182 throw new RuntimeException("Gave up waiting for service " + filter); 183 } 184 return type.cast(svc); 185 } catch (InvalidSyntaxException e) { 186 throw new IllegalArgumentException("Invalid filter", e); 187 } catch (InterruptedException e) { 188 throw new RuntimeException(e); 189 } 190 } 191}