diff --git a/artemis-features/pom.xml b/artemis-features/pom.xml
index ea07a24972..805beb1a86 100644
--- a/artemis-features/pom.xml
+++ b/artemis-features/pom.xml
@@ -67,6 +67,7 @@
target/classes/features.xml
xml
+ features
target/classes/artemis.xml
diff --git a/artemis-features/src/main/resources/features.xml b/artemis-features/src/main/resources/features.xml
index 82d4cfc541..0a88f80590 100644
--- a/artemis-features/src/main/resources/features.xml
+++ b/artemis-features/src/main/resources/features.xml
@@ -43,23 +43,23 @@
mvn:org.apache.activemq/artemis-features/${pom.version}/xml/artemis
mvn:org.apache.geronimo.specs/geronimo-jms_2.0_spec/${geronimo.jms.2.spec.version}
- mvn:com.google.guava/guava/18.0
+ mvn:com.google.guava/guava/${guava.version}
mvn:io.netty/netty-codec-http/${netty.version}
- mvn:commons-beanutils/commons-beanutils/1.9.2
- mvn:commons-collections/commons-collections/3.2.2
+ mvn:commons-beanutils/commons-beanutils/${commons.beanutils.version}
+ mvn:commons-collections/commons-collections/${commons.collections.version}
- mvn:org.jboss.logging/jboss-logging/3.3.0.Final
- mvn:org.jgroups/jgroups/3.6.0.Final
+ mvn:org.jboss.logging/jboss-logging/${jboss.logging.version}
+ mvn:org.jgroups/jgroups/${jgroups.version}
mvn:org.apache.activemq/artemis-native/${pom.version}
mvn:org.apache.activemq/artemis-server-osgi/${pom.version}
+ wrap
artemis-core
- mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.qpid/0.32_1
- wrap:mvn:org.apache.qpid/proton-j/0.10
- wrap:mvn:org.apache.qpid/proton-jms/0.10
+ wrap:mvn:org.apache.qpid/proton-j/${proton.version}
+ wrap:mvn:org.apache.qpid/qpid-jms-client/${qpid.jms.version}
mvn:org.apache.activemq/artemis-proton-plug/${pom.version}
mvn:org.apache.activemq/artemis-amqp-protocol/${pom.version}
diff --git a/docs/user-manual/en/karaf.md b/docs/user-manual/en/karaf.md
index 5da4ac768f..2b6e8a62a2 100644
--- a/docs/user-manual/en/karaf.md
+++ b/docs/user-manual/en/karaf.md
@@ -2,6 +2,6 @@
Apache ActiveMQ Artemis can be installed on Apache Karaf (4.x or later) using the following commands from the Karaf shell:
- feature:repo-add mvn:org.apache.activemq/artemis-features/1.3.0-SNAPSHOT/xml
+ feature:repo-add mvn:org.apache.activemq/artemis-features/1.3.0-SNAPSHOT/xml/features
feature:install artemis
diff --git a/pom.xml b/pom.xml
index ed33038233..eef50be628 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,10 +68,23 @@
scp://people.apache.org/x1/www/activemq.apache.org
- 4.0.32.Final
+
+ 5.12.0
+ 10.11.1.1
+ 1.9.2
+ 3.2.2
+ 1.10
+ 18.0
+ 3.3.0.Final
9.2.11.v20150529
- 1.7.12
+ 3.6.8.Final
2.4
+ 4.0.32.Final
+ 0.12.1
+ 3.0.16.Final
+ 1.7.12
+ 0.9.0
+
${project.version}
1
0
@@ -81,11 +94,7 @@
${project.version}(${activemq.version.incrementingVersion})
- 3.0.16.Final
- 0.12.0
- 5.12.0
- 1.10
- 10.11.1.1
+
true
true
true
@@ -223,7 +232,7 @@
commons-collections
commons-collections-testframework
- 3.2.2
+ ${commons.collections.version}
@@ -295,13 +304,13 @@
com.google.guava
guava
- 18.0
+ ${guava.version}
org.jboss.logging
jboss-logging
- 3.3.0.Final
+ ${jboss.logging.version}
@@ -326,7 +335,7 @@
commons-collections
commons-collections
- 3.2.2
+ ${commons.collections.version}
@@ -379,7 +388,7 @@
org.jgroups
jgroups
- 3.6.8.Final
+ ${jgroups.version}
@@ -527,7 +536,7 @@
commons-beanutils
commons-beanutils
- 1.9.2
+ ${commons.beanutils.version}
diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 38ac4c2cda..e3106fcf9f 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -28,6 +28,8 @@
${project.basedir}/../..
+ 4.0.3
+ 4.7.0
2.1.2
2.0.3-final
@@ -143,6 +145,12 @@
artemis-hornetq-protocol
${project.version}
+
+ org.apache.activemq
+ artemis-features
+ ${project.version}
+ pom
+
@@ -194,7 +202,7 @@
org.apache.qpid
qpid-jms-client
- 0.7.0
+ ${qpid.jms.version}
org.apache.qpid
@@ -285,6 +293,38 @@
+
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-container-karaf
+ ${pax.exam.version}
+ test
+
+
+ org.ops4j.pax.exam
+ pax-exam-junit4
+ ${pax.exam.version}
+ test
+
+
+ org.apache.geronimo.specs
+ geronimo-atinject_1.0_spec
+ 1.0
+ provided
+
+
+ org.apache.karaf
+ apache-karaf
+ ${karaf.version}
+ tar.gz
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.console
+ ${karaf.version}
+
@@ -319,6 +359,19 @@
-Djgroups.bind_addr=::1 ${activemq-surefire-argline}
+
+ org.apache.servicemix.tooling
+ depends-maven-plugin
+ 1.2
+
+
+ generate-depends-file
+
+ generate-depends-file
+
+
+
+
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java
new file mode 100644
index 0000000000..e7594cc7aa
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java
@@ -0,0 +1,242 @@
+/**
+ * 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.activemq.artemis.tests.integration.karaf;
+
+import org.apache.karaf.jaas.boot.principal.RolePrincipal;
+import org.apache.karaf.jaas.boot.principal.UserPrincipal;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.console.SessionFactory;
+import org.apache.log4j.Logger;
+import org.apache.qpid.jms.JmsConnectionFactory;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.ProbeBuilder;
+import org.ops4j.pax.exam.TestProbeBuilder;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.options.UrlReference;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.util.tracker.ServiceTracker;
+
+import javax.inject.Inject;
+import javax.security.auth.Subject;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+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.logLevel;
+
+@RunWith(PaxExam.class)
+public class ArtemisFeatureTest extends Assert {
+
+ private static Logger LOG = Logger.getLogger(ArtemisFeatureTest.class.getName());
+
+ @Inject
+ BundleContext bundleContext;
+
+ @Inject
+ SessionFactory sessionFactory;
+
+ ExecutorService executor = Executors.newCachedThreadPool();
+
+ public static final long ASSERTION_TIMEOUT = 30000L;
+ public static final long COMMAND_TIMEOUT = 30000L;
+ public static final String USER = "karaf";
+ public static final String PASSWORD = "karaf";
+
+ @ProbeBuilder
+ public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
+ probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*,org.ops4j.pax.exam.options.*,org.apache.felix.service.*;status=provisional");
+ return probe;
+ }
+
+ @Configuration
+ public static Option[] configure() {
+ return configure("artemis");
+ }
+
+ public static Option[] configure(String... features) {
+
+ ArrayList f = new ArrayList();
+ f.addAll(Arrays.asList(features));
+
+ Option[] options =
+ new Option[]{
+ karafDistributionConfiguration().frameworkUrl(
+ maven().groupId("org.apache.karaf").artifactId("apache-karaf").type("tar.gz").versionAsInProject())
+ .unpackDirectory(new File("target/paxexam/unpack/")),
+
+ KarafDistributionOption.keepRuntimeFolder(),
+ logLevel(LogLevelOption.LogLevel.INFO),
+ editConfigurationFilePut("etc/config.properties", "karaf.startlevel.bundle", "50"),
+ //debugConfiguration("5005", true),
+ features(getArtemisMQKarafFeatureUrl(), f.toArray(new String[f.size()]))};
+
+ return options;
+ }
+
+ public static UrlReference getArtemisMQKarafFeatureUrl() {
+ String type = "xml/features";
+ UrlReference urlReference = mavenBundle().groupId("org.apache.activemq").
+ artifactId("artemis-features").versionAsInProject().type(type);
+ LOG.info("FeatureURL: " + urlReference.getURL());
+ return urlReference;
+ }
+
+ @Test(timeout = 5 * 60 * 1000)
+ public void test() throws Throwable {
+ executeCommand("bundle:list");
+
+ withinReason(new Callable() {
+ @Override
+ public Boolean call() throws Exception {
+ assertTrue("artemis bundle installed", verifyBundleInstalled("artemis-server-osgi"));
+ return true;
+ }
+ });
+
+ Object service = waitForService("(objectClass=org.apache.activemq.artemis.core.server.ActiveMQServer)", 30000);
+ assertNotNull(service);
+ LOG.info("have service " + service);
+
+ executeCommand("service:list -n");
+
+ String amqpURI = "amqp://localhost:5672";
+ JmsConnectionFactory factory = new JmsConnectionFactory(amqpURI);
+ factory.setUsername(USER);
+ factory.setPassword(PASSWORD);
+
+ //TODO fix security settings and test sending/receiving messages
+ /*
+ Connection connection = factory.createConnection();
+ connection.start();*/
+ }
+
+ protected String executeCommand(final String command, final Long timeout, final Boolean silent) {
+ String response;
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final PrintStream printStream = new PrintStream(byteArrayOutputStream);
+ final Session commandSession = sessionFactory.create(System.in, printStream, printStream);
+ commandSession.put("APPLICATION", System.getProperty("karaf.name", "root"));
+ commandSession.put("USER", USER);
+ FutureTask commandFuture = new FutureTask(
+ new Callable() {
+ @Override
+ public String call() {
+
+ Subject subject = new Subject();
+ subject.getPrincipals().add(new UserPrincipal("admin"));
+ subject.getPrincipals().add(new RolePrincipal("admin"));
+ subject.getPrincipals().add(new RolePrincipal("manager"));
+ subject.getPrincipals().add(new RolePrincipal("viewer"));
+ return Subject.doAs(subject, new PrivilegedAction() {
+ @Override
+ public String run() {
+ try {
+ if (!silent) {
+ System.out.println(command);
+ System.out.flush();
+ }
+ commandSession.execute(command);
+ }
+ catch (Exception e) {
+ e.printStackTrace(System.err);
+ }
+ printStream.flush();
+ return byteArrayOutputStream.toString();
+ }
+ });
+ }
+ });
+
+ try {
+ executor.submit(commandFuture);
+ response = commandFuture.get(timeout, TimeUnit.MILLISECONDS);
+ }
+ catch (Exception e) {
+ e.printStackTrace(System.err);
+ response = "SHELL COMMAND TIMED OUT: ";
+ }
+ LOG.info("Execute: " + command + " - Response:" + response);
+ return response;
+ }
+
+ protected String executeCommand(final String command) {
+ return executeCommand(command, COMMAND_TIMEOUT, false);
+ }
+
+ protected boolean withinReason(Callable callable) throws Throwable {
+ long max = System.currentTimeMillis() + ASSERTION_TIMEOUT;
+ while (true) {
+ try {
+ return callable.call();
+ }
+ catch (Throwable t) {
+ if (System.currentTimeMillis() < max) {
+ TimeUnit.SECONDS.sleep(1);
+ continue;
+ }
+ else {
+ throw t;
+ }
+ }
+ }
+ }
+
+ public boolean verifyBundleInstalled(final String bundleName) throws Exception {
+ boolean found = false;
+ for (Bundle bundle : bundleContext.getBundles()) {
+ LOG.debug("Checking: " + bundle.getSymbolicName());
+ if (bundle.getSymbolicName().contains(bundleName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ protected Object waitForService(String filter, long timeout) throws InvalidSyntaxException, InterruptedException {
+ ServiceTracker