Switch to DS
This commit is contained in:
parent
be9dad3f2b
commit
61d1f49c70
|
@ -112,7 +112,6 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<instructions>
|
<instructions>
|
||||||
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
|
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
|
||||||
<Bundle-Activator>org.apache.activemq.artemis.osgi.Activator</Bundle-Activator>
|
|
||||||
<_exportcontents>*</_exportcontents>
|
<_exportcontents>*</_exportcontents>
|
||||||
</instructions>
|
</instructions>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
package org.apache.activemq.artemis.osgi;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
import org.osgi.framework.BundleActivator;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.Constants;
|
|
||||||
import org.osgi.framework.ServiceRegistration;
|
|
||||||
import org.osgi.service.cm.ManagedServiceFactory;
|
|
||||||
|
|
||||||
public class Activator implements BundleActivator {
|
|
||||||
|
|
||||||
ArtemisBrokerFactory factory;
|
|
||||||
ServiceRegistration<ManagedServiceFactory> registration;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(BundleContext context) throws Exception {
|
|
||||||
factory = new ArtemisBrokerFactory(context);
|
|
||||||
Hashtable<String, String> props = new Hashtable<>();
|
|
||||||
props.put(Constants.SERVICE_PID, ArtemisBrokerFactory.PID);
|
|
||||||
registration = context.registerService(ManagedServiceFactory.class, factory, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(BundleContext context) throws Exception {
|
|
||||||
registration.unregister();
|
|
||||||
factory.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.osgi;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
|
|
||||||
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
|
|
||||||
public class ArtemisBrokerFactory extends BaseManagedServiceFactory<OsgiBroker, OsgiBroker> {
|
|
||||||
|
|
||||||
public static final String PID = "org.apache.activemq.artemis";
|
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ArtemisBrokerFactory.class);
|
|
||||||
|
|
||||||
public ArtemisBrokerFactory(BundleContext context) {
|
|
||||||
super(context, ArtemisBrokerFactory.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected OsgiBroker doCreate(Dictionary<String, ?> properties) throws Exception {
|
|
||||||
String config = getMandatory(properties, "config");
|
|
||||||
String name = getMandatory(properties, "name");
|
|
||||||
String domain = getMandatory(properties, "domain");
|
|
||||||
|
|
||||||
ActiveMQJAASSecurityManager security = new ActiveMQJAASSecurityManager(domain);
|
|
||||||
String serverInstanceDir = null;
|
|
||||||
String karafDataDir = System.getProperty("karaf.data");
|
|
||||||
if (karafDataDir != null) {
|
|
||||||
serverInstanceDir = karafDataDir + "/artemis/" + name;
|
|
||||||
}
|
|
||||||
OsgiBroker server = new OsgiBroker(getContext(), name, serverInstanceDir, config, security);
|
|
||||||
server.start();
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMandatory(Dictionary<String, ?> properties, String key) {
|
|
||||||
String value = (String) properties.get(key);
|
|
||||||
if (value == null) {
|
|
||||||
throw new IllegalStateException("Property " + key + " must be set");
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doDestroy(OsgiBroker broker) throws Exception {
|
|
||||||
broker.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected OsgiBroker register(OsgiBroker broker, Dictionary<String, ?> properties) {
|
|
||||||
broker.register(getContext(), properties);
|
|
||||||
return broker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void unregister(OsgiBroker broker) {
|
|
||||||
broker.unregister();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void warn(String message, Throwable t) {
|
|
||||||
LOGGER.warn(message, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void info(String message, Throwable t) {
|
|
||||||
LOGGER.info(message, t);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.osgi;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.service.cm.ConfigurationException;
|
|
||||||
import org.osgi.service.cm.ManagedServiceFactory;
|
|
||||||
|
|
||||||
public abstract class BaseManagedServiceFactory<T, R> implements ManagedServiceFactory {
|
|
||||||
|
|
||||||
public static final long DEFAULT_TIMEOUT_BEFORE_INTERRUPT = 30000;
|
|
||||||
|
|
||||||
private final BundleContext context;
|
|
||||||
private final String name;
|
|
||||||
private final long timeoutBeforeInterrupt;
|
|
||||||
private final AtomicBoolean destroyed;
|
|
||||||
private final ExecutorService executor;
|
|
||||||
private final Map<String, Pair<T, R>> services;
|
|
||||||
|
|
||||||
public BaseManagedServiceFactory(BundleContext context, String name) {
|
|
||||||
this(context, name, DEFAULT_TIMEOUT_BEFORE_INTERRUPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseManagedServiceFactory(BundleContext context, String name, long timeoutBeforeInterrupt) {
|
|
||||||
this.context = context;
|
|
||||||
this.name = name;
|
|
||||||
this.timeoutBeforeInterrupt = timeoutBeforeInterrupt;
|
|
||||||
this.destroyed = new AtomicBoolean(false);
|
|
||||||
this.executor = Executors.newSingleThreadExecutor();
|
|
||||||
this.services = new ConcurrentHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BundleContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updated(final String pid, final Dictionary<String, ?> properties) throws ConfigurationException {
|
|
||||||
if (destroyed.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
executor.submit(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
internalUpdate(pid, properties);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
warn("Error destroying service for ManagedServiceFactory " + getName(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleted(final String pid) {
|
|
||||||
if (destroyed.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
executor.submit(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
internalDelete(pid);
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
warn("Error destroying service for ManagedServiceFactory " + getName(), throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void internalUpdate(String pid, Dictionary<String, ?> properties) {
|
|
||||||
Pair<T, R> pair = services.remove(pid);
|
|
||||||
if (pair != null) {
|
|
||||||
internalDelete(pid);
|
|
||||||
}
|
|
||||||
if (destroyed.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
T t = doCreate(properties);
|
|
||||||
try {
|
|
||||||
if (destroyed.get()) {
|
|
||||||
throw new IllegalStateException("ManagedServiceFactory has been destroyed");
|
|
||||||
}
|
|
||||||
R registration = register(t, properties);
|
|
||||||
services.put(pid, new Pair<>(t, registration));
|
|
||||||
} catch (Throwable throwable1) {
|
|
||||||
try {
|
|
||||||
doDestroy(t);
|
|
||||||
} catch (Throwable throwable2) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
throw throwable1;
|
|
||||||
}
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
warn("Error creating service for ManagedServiceFactory " + getName(), throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void internalDelete(String pid) {
|
|
||||||
Pair<T, R> pair = services.remove(pid);
|
|
||||||
if (pair != null) {
|
|
||||||
try {
|
|
||||||
unregister(pair.getSecond());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
info("Error unregistering service", t);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
doDestroy(pair.getFirst());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
info("Error destroying service", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract T doCreate(Dictionary<String, ?> properties) throws Exception;
|
|
||||||
|
|
||||||
protected abstract void doDestroy(T t) throws Exception;
|
|
||||||
|
|
||||||
protected abstract R register(T t, Dictionary<String, ?> properties);
|
|
||||||
|
|
||||||
protected abstract void unregister(R registration);
|
|
||||||
|
|
||||||
protected abstract void warn(String message, Throwable t);
|
|
||||||
|
|
||||||
protected abstract void info(String message, Throwable t);
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
if (destroyed.compareAndSet(false, true)) {
|
|
||||||
executor.shutdown();
|
|
||||||
try {
|
|
||||||
executor.awaitTermination(timeoutBeforeInterrupt, TimeUnit.MILLISECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException("Shutdown interrupted");
|
|
||||||
}
|
|
||||||
if (!executor.isTerminated()) {
|
|
||||||
executor.shutdownNow();
|
|
||||||
try {
|
|
||||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException("Shutdown interrupted");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!services.isEmpty()) {
|
|
||||||
String pid = services.keySet().iterator().next();
|
|
||||||
internalDelete(pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Pair<U,V> {
|
|
||||||
private U first;
|
|
||||||
private V second;
|
|
||||||
public Pair(U first, V second) {
|
|
||||||
this.first = first;
|
|
||||||
this.second = second;
|
|
||||||
}
|
|
||||||
public U getFirst() {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
public V getSecond() {
|
|
||||||
return second;
|
|
||||||
}
|
|
||||||
public void setFirst(U first) {
|
|
||||||
this.first = first;
|
|
||||||
}
|
|
||||||
public void setSecond(V second) {
|
|
||||||
this.second = second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -36,43 +36,36 @@ import org.apache.activemq.artemis.core.server.ActiveMQComponent;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||||
import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
|
import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
|
import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
|
||||||
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
|
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.ServiceRegistration;
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
import org.osgi.service.component.ComponentContext;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Deactivate;
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Component(configurationPid="org.apache.activemq.artemis")
|
||||||
public class OsgiBroker {
|
public class OsgiBroker {
|
||||||
private final String name;
|
private String name;
|
||||||
|
private String configurationUrl;
|
||||||
private final String configurationUrl;
|
|
||||||
|
|
||||||
private final String brokerInstance;
|
|
||||||
|
|
||||||
private boolean started;
|
|
||||||
|
|
||||||
private final ActiveMQSecurityManager securityManager;
|
|
||||||
|
|
||||||
private Map<String, ActiveMQComponent> components;
|
private Map<String, ActiveMQComponent> components;
|
||||||
|
|
||||||
private Map<String, ServiceRegistration<?>> registrations;
|
private Map<String, ServiceRegistration<?>> registrations;
|
||||||
|
|
||||||
private BundleContext context;
|
|
||||||
|
|
||||||
private ServiceTracker tracker;
|
private ServiceTracker tracker;
|
||||||
|
|
||||||
public OsgiBroker(BundleContext context, String name, String brokerInstance, String configuration, ActiveMQSecurityManager security) {
|
@Activate
|
||||||
this.context = context;
|
public void activate(ComponentContext cctx) throws Exception {
|
||||||
this.name = name;
|
BundleContext context = cctx.getBundleContext();
|
||||||
this.brokerInstance = brokerInstance;
|
Dictionary<String, Object> properties = cctx.getProperties();
|
||||||
this.securityManager = security;
|
configurationUrl = getMandatory(properties, "config");
|
||||||
this.configurationUrl = configuration;
|
name = getMandatory(properties, "name");
|
||||||
}
|
String domain = getMandatory(properties, "domain");
|
||||||
|
ActiveMQJAASSecurityManager security = new ActiveMQJAASSecurityManager(domain);
|
||||||
|
String brokerInstance = null;
|
||||||
public synchronized void start() throws Exception {
|
String karafDataDir = System.getProperty("karaf.data");
|
||||||
if (tracker != null) {
|
if (karafDataDir != null) {
|
||||||
return;
|
brokerInstance = karafDataDir + "/artemis/" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo if we start to pullout more configs from the main config then we
|
// todo if we start to pullout more configs from the main config then we
|
||||||
|
@ -86,7 +79,7 @@ public class OsgiBroker {
|
||||||
FileDeploymentManager fileDeploymentManager = new FileDeploymentManager(configurationUrl);
|
FileDeploymentManager fileDeploymentManager = new FileDeploymentManager(configurationUrl);
|
||||||
fileDeploymentManager.addDeployable(configuration).addDeployable(jmsConfiguration).readConfiguration();
|
fileDeploymentManager.addDeployable(configuration).addDeployable(jmsConfiguration).readConfiguration();
|
||||||
|
|
||||||
components = fileDeploymentManager.buildService(securityManager, ManagementFactory.getPlatformMBeanServer());
|
components = fileDeploymentManager.buildService(security, ManagementFactory.getPlatformMBeanServer());
|
||||||
|
|
||||||
final ActiveMQServer server = (ActiveMQServer)components.get("core");
|
final ActiveMQServer server = (ActiveMQServer)components.get("core");
|
||||||
|
|
||||||
|
@ -129,9 +122,17 @@ public class OsgiBroker {
|
||||||
ProtocolTracker trackerCust = new ProtocolTracker(name, context, requiredProtocols, callback);
|
ProtocolTracker trackerCust = new ProtocolTracker(name, context, requiredProtocols, callback);
|
||||||
tracker = new ServiceTracker(context, ProtocolManagerFactory.class, trackerCust);
|
tracker = new ServiceTracker(context, ProtocolManagerFactory.class, trackerCust);
|
||||||
tracker.open();
|
tracker.open();
|
||||||
started = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getMandatory(Dictionary<String, ?> properties, String key) {
|
||||||
|
String value = (String) properties.get(key);
|
||||||
|
if (value == null) {
|
||||||
|
throw new IllegalStateException("Property " + key + " must be set");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private String[] getRequiredProtocols(Set<TransportConfiguration> acceptors) {
|
private String[] getRequiredProtocols(Set<TransportConfiguration> acceptors) {
|
||||||
ArrayList<String> protocols = new ArrayList<String>();
|
ArrayList<String> protocols = new ArrayList<String>();
|
||||||
for (TransportConfiguration acceptor : acceptors) {
|
for (TransportConfiguration acceptor : acceptors) {
|
||||||
|
@ -143,16 +144,9 @@ public class OsgiBroker {
|
||||||
return protocols.toArray(new String[]{});
|
return protocols.toArray(new String[]{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deactivate
|
||||||
public void stop() throws Exception {
|
public void stop() throws Exception {
|
||||||
if (!started) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tracker.close();
|
tracker.close();
|
||||||
tracker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStarted() {
|
|
||||||
return started;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, ActiveMQComponent> getComponents() {
|
public Map<String, ActiveMQComponent> getComponents() {
|
||||||
|
|
|
@ -32,6 +32,7 @@ public class ProtocolTrackerTest {
|
||||||
EasyMock.expectLastCall();
|
EasyMock.expectLastCall();
|
||||||
|
|
||||||
callback.removeFactory(protA.factory);
|
callback.removeFactory(protA.factory);
|
||||||
|
EasyMock.expectLastCall();
|
||||||
callback.stop();
|
callback.stop();
|
||||||
EasyMock.expectLastCall();
|
EasyMock.expectLastCall();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue