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.service; 019 020import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 021import static org.apache.http.HttpStatus.SC_CREATED; 022import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL; 023import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER; 024import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 025import static org.junit.Assert.assertEquals; 026import static org.junit.Assert.assertNotNull; 027import static org.junit.Assert.assertTrue; 028import static org.ops4j.pax.exam.CoreOptions.bundle; 029import static org.ops4j.pax.exam.CoreOptions.maven; 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.io.IOException; 044import java.util.HashMap; 045import java.util.Map; 046import javax.inject.Inject; 047 048import org.apache.camel.CamelContext; 049import org.apache.camel.ProducerTemplate; 050import org.apache.camel.component.mock.MockEndpoint; 051import org.apache.http.HttpResponse; 052import org.apache.http.auth.AuthScope; 053import org.apache.http.auth.UsernamePasswordCredentials; 054import org.apache.http.client.methods.HttpPost; 055import org.apache.http.impl.client.BasicCredentialsProvider; 056import org.apache.http.impl.client.CloseableHttpClient; 057import org.apache.http.impl.client.HttpClients; 058import org.apache.http.util.EntityUtils; 059import org.apache.karaf.features.FeaturesService; 060import org.junit.Test; 061import org.junit.runner.RunWith; 062import org.ops4j.pax.exam.Configuration; 063import org.ops4j.pax.exam.ConfigurationManager; 064import org.ops4j.pax.exam.CoreOptions; 065import org.ops4j.pax.exam.Option; 066import org.ops4j.pax.exam.junit.PaxExam; 067import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; 068import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; 069import org.ops4j.pax.exam.spi.reactors.PerClass; 070import org.osgi.framework.BundleContext; 071import org.osgi.framework.InvalidSyntaxException; 072import org.osgi.util.tracker.ServiceTracker; 073import org.slf4j.Logger; 074 075/** 076 * @author Aaron Coburn 077 * @since July 21, 2016 078 */ 079@RunWith(PaxExam.class) 080@ExamReactorStrategy(PerClass.class) 081public class KarafIT { 082 083 private final static String FEDORA_USERNAME = "fedoraAdmin"; 084 085 private final static String FEDORA_PASSWORD = "fedoraAdmin"; 086 087 private final BasicCredentialsProvider provider = new BasicCredentialsProvider(); 088 089 private final CloseableHttpClient httpclient; 090 091 private static Logger LOGGER = getLogger(KarafIT.class); 092 093 @Inject 094 protected FeaturesService featuresService; 095 096 @Inject 097 protected BundleContext bundleContext; 098 099 public KarafIT() { 100 provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(FEDORA_USERNAME, FEDORA_PASSWORD)); 101 httpclient = HttpClients.custom().setDefaultCredentialsProvider(provider).build(); 102 } 103 104 @Configuration 105 public Option[] config() throws Exception { 106 final ConfigurationManager cm = new ConfigurationManager(); 107 final String artifactName = cm.getProperty("project.artifactId") + "-" + cm.getProperty("project.version"); 108 final String fcrepoServiceBundle = "file:" + getBaseDir() + "/target/" + artifactName + ".jar"; 109 final String fcrepoPort = cm.getProperty("fcrepo.dynamic.test.port"); 110 final String jmsPort = cm.getProperty("fcrepo.dynamic.jms.port"); 111 final String rmiRegistryPort = cm.getProperty("karaf.rmiRegistry.port"); 112 final String rmiServerPort = cm.getProperty("karaf.rmiServer.port"); 113 final String sshPort = cm.getProperty("karaf.ssh.port"); 114 return new Option[] { 115 karafDistributionConfiguration() 116 .frameworkUrl(maven().groupId("org.apache.karaf").artifactId("apache-karaf") 117 .versionAsInProject().type("zip")) 118 .unpackDirectory(new File("target", "exam")) 119 .useDeployFolder(false), 120 logLevel(LogLevel.WARN), 121 keepRuntimeFolder(), 122 configureConsole().ignoreLocalConsole(), 123 features(maven().groupId("org.apache.karaf.features").artifactId("standard") 124 .type("xml").classifier("features").versionAsInProject(), "scr"), 125 features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel") 126 .type("xml").classifier("features").versionAsInProject(), "camel", 127 "camel-blueprint", "camel-jackson"), 128 features(maven().groupId("org.fcrepo.camel").artifactId("fcrepo-camel") 129 .type("xml").classifier("features").versionAsInProject(), "fcrepo-camel"), 130 131 CoreOptions.systemProperty("fcrepo.port").value(fcrepoPort), 132 CoreOptions.systemProperty("jms.port").value(jmsPort), 133 CoreOptions.systemProperty("fcrepo.service.bundle").value(fcrepoServiceBundle), 134 135 editConfigurationFilePut("etc/org.fcrepo.camel.service.cfg", "fcrepo.baseUrl", 136 "http://localhost:" + fcrepoPort + "/fcrepo/rest"), 137 editConfigurationFilePut("etc/org.fcrepo.camel.service.cfg", "fcrepo.authUsername", 138 FEDORA_USERNAME), 139 editConfigurationFilePut("etc/org.fcrepo.camel.service.cfg", "fcrepo.authPassword", 140 FEDORA_PASSWORD), 141 142 bundle(fcrepoServiceBundle).start(), 143 144 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort), 145 editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort), 146 editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort) 147 }; 148 } 149 150 @Test 151 public void testInstallation() throws Exception { 152 assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-core"))); 153 assertTrue(featuresService.isInstalled(featuresService.getFeature("fcrepo-camel"))); 154 assertNotNull(bundleContext); 155 assertEquals(ACTIVE, 156 bundleContext.getBundle(System.getProperty("fcrepo.service.bundle")).getState()); 157 } 158 159 @Test 160 public void testService() throws Exception { 161 final String baseUrl = "http://localhost:" + System.getProperty("fcrepo.port") + "/fcrepo/rest"; 162 final CamelContext ctx = getOsgiService(CamelContext.class, 163 "(camel.context.name=FcrepoService)", 10000); 164 165 assertNotNull(ctx); 166 167 final MockEndpoint resultEndpoint = (MockEndpoint) ctx.getEndpoint("mock:result"); 168 169 final String url1 = post(baseUrl).replace(baseUrl, ""); 170 final String url2 = post(baseUrl).replace(baseUrl, ""); 171 172 final ProducerTemplate template = ctx.createProducerTemplate(); 173 final Map<String, Object> headers = new HashMap<>(); 174 headers.put(FCREPO_BASE_URL, baseUrl); 175 headers.put(FCREPO_IDENTIFIER, url1); 176 template.sendBodyAndHeaders(ctx.getEndpoint("direct:start"), null, headers); 177 178 template.sendBodyAndHeader(ctx.getEndpoint("direct:start"), null, FCREPO_URI, baseUrl + url2); 179 180 resultEndpoint.expectedMinimumMessageCount(2); 181 assertIsSatisfied(resultEndpoint); 182 } 183 184 private String post(final String url) { 185 try { 186 final HttpPost httppost = new HttpPost(url); 187 final HttpResponse response = httpclient.execute(httppost); 188 assertEquals(SC_CREATED, response.getStatusLine().getStatusCode()); 189 return EntityUtils.toString(response.getEntity(), "UTF-8"); 190 } catch (final IOException ex) { 191 LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); 192 return ""; 193 } 194 } 195 196 private <T> T getOsgiService(final Class<T> type, final String filter, final long timeout) { 197 try { 198 final ServiceTracker tracker = new ServiceTracker(bundleContext, 199 createFilter("(&(" + OBJECTCLASS + "=" + type.getName() + ")" + filter + ")"), null); 200 tracker.open(true); 201 final Object svc = type.cast(tracker.waitForService(timeout)); 202 if (svc == null) { 203 throw new RuntimeException("Gave up waiting for service " + filter); 204 } 205 return type.cast(svc); 206 } catch (final InvalidSyntaxException e) { 207 throw new IllegalArgumentException("Invalid filter", e); 208 } catch (final InterruptedException e) { 209 throw new RuntimeException(e); 210 } 211 } 212}