killbill-uncached
Changes
osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyActivator.java 58(+37 -21)
Details
diff --git a/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyActivator.java b/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyActivator.java
index 569e265..5824a65 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyActivator.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyActivator.java
@@ -22,15 +22,16 @@ import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.log.LogService;
-
-import org.killbill.commons.concurrent.Executors;
import org.killbill.billing.osgi.api.config.PluginConfig.PluginType;
import org.killbill.billing.osgi.api.config.PluginConfigServiceApi;
import org.killbill.billing.osgi.api.config.PluginRubyConfig;
+import org.killbill.commons.concurrent.Executors;
import org.killbill.killbill.osgi.libs.killbill.KillbillActivatorBase;
+import org.killbill.killbill.osgi.libs.killbill.KillbillServiceListener;
+import org.killbill.killbill.osgi.libs.killbill.KillbillServiceListenerCallback;
import org.killbill.killbill.osgi.libs.killbill.OSGIKillbillEventDispatcher.OSGIKillbillEventHandler;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
import com.google.common.base.Objects;
@@ -52,6 +53,22 @@ public class JRubyActivator extends KillbillActivatorBase {
public void start(final BundleContext context) throws Exception {
super.start(context);
+ final String osgiKillbillClass = "org.killbill.billing.osgi.api.OSGIKillbill";
+ final KillbillServiceListenerCallback listenerCallback = new KillbillServiceListenerCallback() {
+ @Override
+ public void isRegistered(final BundleContext context) {
+ startWithContextClassLoader(context);
+ }
+ };
+ KillbillServiceListener.listenForService(context, osgiKillbillClass, listenerCallback);
+ }
+
+ private void startWithContextClassLoader(final BundleContext context) {
+ if (restartFuture != null) {
+ // If the restart future is already configured, the plugin had already started
+ return;
+ }
+
withContextClassLoader(new PluginCall() {
@Override
public void doCall() {
@@ -108,26 +125,26 @@ public class JRubyActivator extends KillbillActivatorBase {
restartFuture = Executors.newSingleThreadScheduledExecutor("jruby-restarter-" + pluginMain)
.scheduleWithFixedDelay(new Runnable() {
- long lastRestartMillis = System.currentTimeMillis();
+ long lastRestartMillis = System.currentTimeMillis();
- @Override
- public void run() {
+ @Override
+ public void run() {
- final File restartFile = new File(tmpDirPath + "/" + RESTART_FILE_NAME);
- if (!restartFile.isFile()) {
- return;
- }
+ final File restartFile = new File(tmpDirPath + "/" + RESTART_FILE_NAME);
+ if (!restartFile.isFile()) {
+ return;
+ }
- if (restartFile.lastModified() > lastRestartMillis) {
- logService.log(LogService.LOG_INFO, "Restarting JRuby plugin " + rubyConfig.getRubyMainClass());
+ if (restartFile.lastModified() > lastRestartMillis) {
+ logService.log(LogService.LOG_INFO, "Restarting JRuby plugin " + rubyConfig.getRubyMainClass());
- doStopPlugin(context);
- doStartPlugin(pluginMain, context, killbillServices);
+ doStopPlugin(context);
+ doStartPlugin(pluginMain, context, killbillServices);
- lastRestartMillis = restartFile.lastModified();
- }
- }
- }, JRUBY_PLUGINS_RESTART_DELAY_SECS, JRUBY_PLUGINS_RESTART_DELAY_SECS, TimeUnit.SECONDS);
+ lastRestartMillis = restartFile.lastModified();
+ }
+ }
+ }, JRUBY_PLUGINS_RESTART_DELAY_SECS, JRUBY_PLUGINS_RESTART_DELAY_SECS, TimeUnit.SECONDS);
}
private PluginRubyConfig retrievePluginRubyConfig(final BundleContext context) {
@@ -148,7 +165,7 @@ public class JRubyActivator extends KillbillActivatorBase {
}, this.getClass().getClassLoader());
}
- private void doStartPlugin(final String pluginMain, final BundleContext context, final Map<String, Object> killbillServices) {
+ private void doStartPlugin(final String pluginMain, final BundleContext context, final Map<String, Object> killbillServices) {
logService.log(LogService.LOG_INFO, "Starting JRuby plugin " + pluginMain);
plugin.instantiatePlugin(killbillServices, pluginMain);
plugin.startPlugin(context);
@@ -186,7 +203,6 @@ public class JRubyActivator extends KillbillActivatorBase {
return killbillUserApis;
}
-
private static interface PluginCall {
public void doCall();
diff --git a/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListener.java b/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListener.java
new file mode 100644
index 0000000..9f1af06
--- /dev/null
+++ b/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListener.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project 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.killbill.killbill.osgi.libs.killbill;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+public class KillbillServiceListener implements ServiceListener {
+
+ private final BundleContext context;
+ private final KillbillServiceListenerCallback killbillServiceListenerCallback;
+
+ public static KillbillServiceListener listenForService(final BundleContext context, final String serviceClass, final KillbillServiceListenerCallback listenerCallback) throws InvalidSyntaxException {
+ final String filter = "(objectclass=" + serviceClass + ")";
+
+ final KillbillServiceListener killbillServiceListener = new KillbillServiceListener(context, listenerCallback);
+ context.addServiceListener(killbillServiceListener, filter);
+
+ // If the service was already registered, manually construct a REGISTERED ServiceEvent
+ final ServiceReference[] serviceReferences = context.getServiceReferences((String) null, filter);
+ for (int i = 0; serviceReferences != null && i < serviceReferences.length; i++) {
+ killbillServiceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, serviceReferences[i]));
+ }
+
+ return killbillServiceListener;
+ }
+
+ public KillbillServiceListener(final BundleContext context, final KillbillServiceListenerCallback killbillServiceListenerCallback) {
+ this.context = context;
+ this.killbillServiceListenerCallback = killbillServiceListenerCallback;
+ }
+
+ @Override
+ public void serviceChanged(final ServiceEvent event) {
+ final ServiceReference serviceReference = event.getServiceReference();
+ if (serviceReference == null || serviceReference.getBundle() == null) {
+ return;
+ }
+
+ final BundleContext bundleContext = serviceReference.getBundle().getBundleContext();
+ if (bundleContext == null) {
+ return;
+ }
+
+ final Object service = bundleContext.getService(serviceReference);
+ if (service != null) {
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ killbillServiceListenerCallback.isRegistered(context);
+ } else if (event.getType() == ServiceEvent.UNREGISTERING) {
+ killbillServiceListenerCallback.isUnRegistering(context);
+ }
+ }
+ }
+}
diff --git a/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListenerCallback.java b/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListenerCallback.java
new file mode 100644
index 0000000..1ae028e
--- /dev/null
+++ b/osgi-bundles/libs/killbill/src/main/java/org/killbill/killbill/osgi/libs/killbill/KillbillServiceListenerCallback.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project 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.killbill.killbill.osgi.libs.killbill;
+
+import org.osgi.framework.BundleContext;
+
+public abstract class KillbillServiceListenerCallback {
+
+ public void isRegistered(final BundleContext context) {
+ }
+
+ public void isUnRegistering(final BundleContext context) {
+ }
+}