-
-
Save cescoffier/e8aec18cc86581923f1cc639c2a71c4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.vertx.example.osgi; | |
import org.apache.commons.io.IOUtils; | |
import org.osgi.framework.Bundle; | |
import org.osgi.framework.BundleContext; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.URL; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
/** | |
* A class loading SPI implementation for Vert.x | |
*/ | |
public class VertxSpiHelper { | |
private final static Logger LOGGER = Logger.getLogger("SPIHelper"); | |
public static <T> T lookup(Class<T> clazz, BundleContext bc, String hint) throws IOException { | |
Objects.requireNonNull(clazz); | |
Objects.requireNonNull(bc); | |
Bundle vertxBundle = getVertxCoreBundle(bc); | |
if (vertxBundle == null) { | |
throw new RuntimeException("Cannot find the vertx-core bundle"); | |
} | |
for (Bundle bundle : bc.getBundles()) { | |
if (bundle.getBundleId() == 0) { | |
// Skip system bundle. | |
continue; | |
} | |
T className = loadAndInstantiate(clazz, hint, bundle); | |
if (className != null) return className; | |
} | |
// Nothing found, try with system bundle | |
Bundle system = bc.getBundle(0); | |
return loadAndInstantiate(clazz, hint, system); | |
} | |
private static <T> T loadAndInstantiate(Class<T> clazz, String hint, Bundle bundle) throws IOException { | |
URL url = bundle.getResource("META-INF/services/" + clazz.getName()); | |
if (url != null) { | |
InputStream stream = url.openStream(); | |
List<String> content = IOUtils.readLines(stream, "UTF-8"); | |
String className = null; | |
for (String line : content) { | |
if (!line.startsWith("#") && !line.trim().isEmpty()) { | |
className = line.trim(); | |
} | |
} | |
if (className == null) { | |
throw new RuntimeException("Service file not formatted correctly " + url.toExternalForm()); | |
} | |
if (hint != null) { | |
if (className.toLowerCase().contains(hint.toLowerCase())) { | |
return instantiate(bundle, className); | |
} | |
} else { | |
return instantiate(bundle, className); | |
} | |
} | |
return null; | |
} | |
private static <T> T instantiate(Bundle bundle, String className) { | |
try { | |
Class<T> clazz = (Class<T>) bundle.loadClass(className); | |
return clazz.newInstance(); | |
} catch (ClassNotFoundException e) { | |
LOGGER.severe("Cannot load class " + className + " from " + bundle.getSymbolicName()); | |
} catch (InstantiationException | IllegalAccessException e) { | |
LOGGER.log(Level.SEVERE, "Cannot instantiate class " + className + " from " + bundle.getSymbolicName(), e); | |
} | |
return null; | |
} | |
private static Bundle getVertxCoreBundle(BundleContext context) { | |
for (Bundle bundle : context.getBundles()) { | |
if (bundle.getSymbolicName().toLowerCase().contains("io.vertx.core")) { | |
return bundle; | |
} | |
} | |
return null; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.vertx.example.osgi; | |
import io.vertx.core.Vertx; | |
import io.vertx.core.VertxOptions; | |
import io.vertx.core.eventbus.EventBus; | |
import io.vertx.core.spi.VertxMetricsFactory; | |
import io.vertx.ext.dropwizard.DropwizardMetricsOptions; | |
import org.osgi.framework.BundleActivator; | |
import org.osgi.framework.BundleContext; | |
import org.osgi.framework.ServiceRegistration; | |
import java.util.logging.Logger; | |
import static io.vertx.example.osgi.TcclSwitch.executeWithTCCLSwitch; | |
/** | |
* A bundle activator registering the Vert.x instance and the event bus as OSGi service. | |
*/ | |
public class VertxActivator implements BundleActivator { | |
private final static Logger LOGGER = Logger.getLogger("VertxPublisher"); | |
private ServiceRegistration<Vertx> vertxRegistration; | |
private ServiceRegistration<EventBus> ebRegistration; | |
@Override | |
public void start(BundleContext context) throws Exception { | |
LOGGER.info("Creating Vert.x instance"); | |
VertxOptions options = new VertxOptions().setMetricsOptions(new DropwizardMetricsOptions() | |
.setJmxEnabled(true) | |
.setJmxDomain("vertx") | |
.setRegistryName("my-registry") | |
.setFactory(VertxSpiHelper.lookup(VertxMetricsFactory.class, context, "dropwizard")) | |
); | |
Vertx vertx = executeWithTCCLSwitch(() -> Vertx.vertx(options)); | |
vertxRegistration = context.registerService(Vertx.class, vertx, null); | |
LOGGER.info("Vert.x service registered"); | |
ebRegistration = context.registerService(EventBus.class, vertx.eventBus(), null); | |
LOGGER.info("Vert.x Event Bus service registered"); | |
} | |
@Override | |
public void stop(BundleContext context) throws Exception { | |
if (vertxRegistration != null) { | |
vertxRegistration.unregister(); | |
vertxRegistration = null; | |
} | |
if (ebRegistration != null) { | |
ebRegistration.unregister(); | |
ebRegistration = null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment