killbill-uncached
Changes
beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyNotificationPlugin.java 33(+33 -0)
osgi-bundles/bundles/jruby/pom.xml 6(+6 -0)
osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java 10(+9 -1)
osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyNotificationPlugin.java 19(+16 -3)
osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java 54(+14 -40)
Details
diff --git a/api/src/main/java/com/ning/billing/notification/plugin/api/NotificationPluginApi.java b/api/src/main/java/com/ning/billing/notification/plugin/api/NotificationPluginApi.java
new file mode 100644
index 0000000..4dc0fdb
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/notification/plugin/api/NotificationPluginApi.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.notification.plugin.api;
+
+import com.ning.billing.beatrix.bus.api.ExtBusEvent;
+
+public interface NotificationPluginApi {
+
+ /**
+ * Dispatching of external Killbill events for notification plugins
+ *
+ * @param killbillEvent the killbill event
+ */
+ public void onEvent(ExtBusEvent killbillEvent);
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyNotificationPlugin.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyNotificationPlugin.java
new file mode 100644
index 0000000..e817a63
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyNotificationPlugin.java
@@ -0,0 +1,33 @@
+package com.ning.billing.beatrix.integration.osgi;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.beatrix.osgi.SetupBundleWithAssertion;
+
+public class TestJrubyNotificationPlugin extends TestOSGIBase {
+
+ private final String BUNDLE_TEST_RESOURCE_PREFIX = "killbill-notification-test";
+ private final String BUNDLE_TEST_RESOURCE = BUNDLE_TEST_RESOURCE_PREFIX + ".tar.gz";
+
+ @BeforeClass(groups = "slow", enabled = true)
+ public void beforeClass() throws Exception {
+
+ // OSGIDataSourceConfig
+ super.beforeClass();
+
+ // This is extracted from surefire system configuration-- needs to be added explicitly in IntelliJ for correct running
+ final String killbillVersion = System.getProperty("killbill.version");
+
+ SetupBundleWithAssertion setupTest = new SetupBundleWithAssertion(BUNDLE_TEST_RESOURCE, osgiConfig, killbillVersion);
+ setupTest.setupJrubyBundle();
+ }
+
+ @Test(groups = "slow", enabled = true)
+ public void testOnEventForAccountCreation() throws Exception {
+
+ final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(4));
+ }
+
+}
diff --git a/beatrix/src/test/resources/killbill-notification-test.tar.gz b/beatrix/src/test/resources/killbill-notification-test.tar.gz
new file mode 100644
index 0000000..9e9e3ea
Binary files /dev/null and b/beatrix/src/test/resources/killbill-notification-test.tar.gz differ
diff --git a/beatrix/src/test/resources/killbill-payment-test.tar.gz b/beatrix/src/test/resources/killbill-payment-test.tar.gz
index 6561b10..1d84c69 100644
Binary files a/beatrix/src/test/resources/killbill-payment-test.tar.gz and b/beatrix/src/test/resources/killbill-payment-test.tar.gz differ
osgi-bundles/bundles/jruby/pom.xml 6(+6 -0)
diff --git a/osgi-bundles/bundles/jruby/pom.xml b/osgi-bundles/bundles/jruby/pom.xml
index 8e19afc..dcf2aaf 100644
--- a/osgi-bundles/bundles/jruby/pom.xml
+++ b/osgi-bundles/bundles/jruby/pom.xml
@@ -49,6 +49,12 @@
<version>1.7.1</version>
</dependency>
<dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>14.0.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
index e70c2cc..0e5cd9a 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyActivator.java
@@ -38,6 +38,9 @@ public class JRubyActivator extends KillbillActivatorBase {
private JRubyPlugin plugin = null;
+ private final static String KILLBILL_PLUGIN_JPAYMENT = "Killbill::Plugin::JPayment";
+ private final static String KILLBILL_PLUGIN_JNOTIFICATION = "Killbill::Plugin::JNotification";
+
public void start(final BundleContext context) throws Exception {
super.start(context);
@@ -52,12 +55,17 @@ public class JRubyActivator extends KillbillActivatorBase {
final PluginRubyConfig rubyConfig = retrievePluginRubyConfig(context);
// Setup JRuby
+ final String pluginMain;
final ScriptingContainer scriptingContainer = setupScriptingContainer(rubyConfig);
if (PluginType.NOTIFICATION.equals(rubyConfig.getPluginType())) {
plugin = new JRubyNotificationPlugin(rubyConfig, scriptingContainer, context, logService);
dispatcher.registerEventHandler((OSGIKillbillEventHandler) plugin);
+ pluginMain = KILLBILL_PLUGIN_JNOTIFICATION;
} else if (PluginType.PAYMENT.equals(rubyConfig.getPluginType())) {
plugin = new JRubyPaymentPlugin(rubyConfig, scriptingContainer, context, logService);
+ pluginMain = KILLBILL_PLUGIN_JPAYMENT;
+ } else {
+ throw new IllegalStateException("Unsupported plugin type " + rubyConfig.getPluginType());
}
// Validate and instantiate the plugin
@@ -67,7 +75,7 @@ public class JRubyActivator extends KillbillActivatorBase {
killbillServices.put("logger", logService);
// Default to the plugin root dir if no jruby plugins specific configuration directory was specified
killbillServices.put("conf_dir", Objects.firstNonNull(jrubyPluginsConfDir, rubyConfig.getPluginVersionRoot().getAbsolutePath()));
- plugin.instantiatePlugin(killbillServices);
+ plugin.instantiatePlugin(killbillServices, pluginMain);
logService.log(LogService.LOG_INFO, "Starting JRuby plugin " + plugin.getPluginMainClass());
plugin.startPlugin(context);
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyNotificationPlugin.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyNotificationPlugin.java
index 2e49ec5..fa6118f 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyNotificationPlugin.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyNotificationPlugin.java
@@ -16,13 +16,17 @@
package com.ning.billing.osgi.bundles.jruby;
+import org.jruby.Ruby;
import org.jruby.embed.ScriptingContainer;
import org.jruby.javasupport.JavaEmbedUtils;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
import com.ning.billing.beatrix.bus.api.ExtBusEvent;
+import com.ning.billing.notification.plugin.api.NotificationPluginApi;
import com.ning.billing.osgi.api.config.PluginRubyConfig;
+import com.ning.billing.payment.plugin.api.PaymentPluginApi;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillEventDispatcher.OSGIKillbillEventHandler;
public class JRubyNotificationPlugin extends JRubyPlugin implements OSGIKillbillEventHandler {
@@ -39,8 +43,17 @@ public class JRubyNotificationPlugin extends JRubyPlugin implements OSGIKillbill
@Override
public void handleKillbillEvent(final ExtBusEvent killbillEvent) {
- checkValidNotificationPlugin();
- checkPluginIsRunning();
- pluginInstance.callMethod("on_event", JavaEmbedUtils.javaToRuby(getRuntime(), killbillEvent));
+
+ try {
+ callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.NOTIFICATION) {
+ @Override
+ public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
+ ((NotificationPluginApi) pluginInstance).onEvent(killbillEvent);
+ return null;
+ }
+ });
+ } catch (PaymentPluginApiException e) {
+ throw new IllegalStateException("Unexpected PaymentApiException for notification plugin");
+ }
}
}
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
index 99ab86b..3b52ee3 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
@@ -24,8 +24,6 @@ import java.util.UUID;
import org.jruby.Ruby;
import org.jruby.embed.ScriptingContainer;
-import org.jruby.javasupport.JavaEmbedUtils;
-import org.jruby.runtime.builtin.IRubyObject;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.log.LogService;
@@ -70,9 +68,9 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
- public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
+ public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public PaymentInfoPlugin doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).processPayment(kbAccountId, kbPaymentId, kbPaymentMethodId, amount, currency, context);
@@ -83,7 +81,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public PaymentInfoPlugin getPaymentInfo(final UUID kbAccountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public PaymentInfoPlugin doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).getPaymentInfo(kbAccountId, kbPaymentId, context);
@@ -94,7 +92,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public RefundInfoPlugin processRefund(final UUID kbAccountId, final UUID kbPaymentId, final BigDecimal refundAmount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public RefundInfoPlugin doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).processRefund(kbAccountId, kbPaymentId, refundAmount, currency, context);
@@ -105,7 +103,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public List<RefundInfoPlugin> getRefundInfo(final UUID kbAccountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public List<RefundInfoPlugin> doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).getRefundInfo(kbAccountId, kbPaymentId, context);
@@ -116,9 +114,9 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public void addPaymentMethod(final UUID kbAccountId, final UUID kbPaymentMethodId, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault, final CallContext context) throws PaymentPluginApiException {
- callWithRuntimeAndChecking(new PluginCallback() {
+ callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
- public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
+ public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
((PaymentPluginApi) pluginInstance).addPaymentMethod(kbAccountId, kbPaymentMethodId, paymentMethodProps, Boolean.valueOf(setDefault), context);
return null;
}
@@ -128,9 +126,9 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public void deletePaymentMethod(final UUID kbAccountId, final UUID kbPaymentMethodId, final CallContext context) throws PaymentPluginApiException {
- callWithRuntimeAndChecking(new PluginCallback() {
+ callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
- public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
+ public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
((PaymentPluginApi) pluginInstance).deletePaymentMethod(kbAccountId, kbPaymentMethodId, context);
return null;
}
@@ -140,7 +138,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public PaymentMethodPlugin getPaymentMethodDetail(final UUID kbAccountId, final UUID kbPaymentMethodId, final TenantContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public PaymentMethodPlugin doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).getPaymentMethodDetail(kbAccountId, kbPaymentMethodId, context);
@@ -151,7 +149,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public void setDefaultPaymentMethod(final UUID kbAccountId, final UUID kbPaymentMethodId, final CallContext context) throws PaymentPluginApiException {
- callWithRuntimeAndChecking(new PluginCallback() {
+ callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
((PaymentPluginApi) pluginInstance).setDefaultPaymentMethod(kbAccountId, kbPaymentMethodId, context);
@@ -162,7 +160,7 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public List<PaymentMethodInfoPlugin> getPaymentMethods(final UUID kbAccountId, final boolean refreshFromGateway, final CallContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback() {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public List<PaymentMethodInfoPlugin> doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).getPaymentMethods(kbAccountId, Boolean.valueOf(refreshFromGateway), context);
@@ -173,38 +171,14 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
@Override
public void resetPaymentMethods(final UUID kbAccountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
- callWithRuntimeAndChecking(new PluginCallback() {
+ callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
- public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
+ public Void doCall(final Ruby runtime) throws PaymentPluginApiException {
((PaymentPluginApi) pluginInstance).resetPaymentMethods(kbAccountId, paymentMethods);
return null;
}
});
}
- private abstract class PluginCallback {
-
- public abstract <T> T doCall(final Ruby runtime) throws PaymentPluginApiException;
-
- public boolean checkValidPaymentPlugin() {
- return true;
- }
- }
- private <T> T callWithRuntimeAndChecking(PluginCallback cb) throws PaymentPluginApiException {
- try {
- checkPluginIsRunning();
-
- if (cb.checkValidPaymentPlugin()) {
- checkValidPaymentPlugin();
- }
-
- final Ruby runtime = getRuntime();
- return cb.doCall(runtime);
-
- } catch (RuntimeException e) {
- // TODO STEPH not sure what ruby can throw
- throw e;
- }
- }
}
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPlugin.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPlugin.java
index d45ee1a..9f4f391 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPlugin.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPlugin.java
@@ -30,12 +30,17 @@ import org.jruby.runtime.builtin.IRubyObject;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.log.LogService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.ning.billing.osgi.api.config.PluginRubyConfig;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
// Bridge between the OSGI bundle and the ruby plugin
public abstract class JRubyPlugin {
+ private final static Logger log = LoggerFactory.getLogger(JRubyPlugin.class);
+
// Killbill gem base classes
private static final String KILLBILL_PLUGIN_BASE = "Killbill::Plugin::PluginBase";
private static final String KILLBILL_PLUGIN_NOTIFICATION = "Killbill::Plugin::Notification";
@@ -82,7 +87,7 @@ public abstract class JRubyPlugin {
return pluginLibdir;
}
- public void instantiatePlugin(final Map<String, Object> killbillApis) {
+ public void instantiatePlugin(final Map<String, Object> killbillApis, final String pluginMain) {
checkValidPlugin();
// Register all killbill APIs
@@ -93,7 +98,7 @@ public abstract class JRubyPlugin {
// Don't put any code here!
// Start the plugin
- pluginInstance = (RubyObject) container.runScriptlet("Killbill::Plugin::JPayment.new(" + KILLBILL_PLUGIN_CLASS_NAME + "," + KILLBILL_SERVICES + ")");
+ pluginInstance = (RubyObject) container.runScriptlet(pluginMain + ".new(" + KILLBILL_PLUGIN_CLASS_NAME + "," + KILLBILL_SERVICES + ")");
}
public void startPlugin(final BundleContext context) {
@@ -130,7 +135,7 @@ public abstract class JRubyPlugin {
}
protected void checkPluginIsRunning() {
- if (pluginInstance == null || ! (Boolean) pluginInstance.callMethod("is_active").toJava(Boolean.class)) {
+ if (pluginInstance == null || !(Boolean) pluginInstance.callMethod("is_active").toJava(Boolean.class)) {
throw new IllegalStateException(String.format("Plugin %s didn't start properly", pluginMainClass));
}
}
@@ -194,10 +199,10 @@ public abstract class JRubyPlugin {
.append("end\n");
builder.append("begin\n")
.append("require '").append(pluginGemName).append("'\n")
- .append("rescue LoadError\n")
- // Could be useful for debugging
- //.append("warn \"WARN: unable to require ").append(pluginGemName).append("\"\n")
- .append("end\n");
+ .append("rescue LoadError\n")
+ // Could be useful for debugging
+ //.append("warn \"WARN: unable to require ").append(pluginGemName).append("\"\n")
+ .append("end\n");
// Load the extra require file, if specified
if (rubyRequire != null) {
builder.append("begin\n")
@@ -218,4 +223,48 @@ public abstract class JRubyPlugin {
protected Ruby getRuntime() {
return pluginInstance.getMetaClass().getRuntime();
}
+
+ public enum VALIDATION_PLUGIN_TYPE {
+ NOTIFICATION,
+ PAYMENT,
+ NONE
+ }
+
+ protected abstract class PluginCallback {
+
+ private final VALIDATION_PLUGIN_TYPE pluginType;
+
+ public PluginCallback(final VALIDATION_PLUGIN_TYPE pluginType) {
+ this.pluginType = pluginType;
+ }
+
+ public abstract <T> T doCall(final Ruby runtime) throws PaymentPluginApiException;
+
+ public VALIDATION_PLUGIN_TYPE getPluginType() {
+ return pluginType;
+ }
+ }
+
+ protected <T> T callWithRuntimeAndChecking(final PluginCallback cb) throws PaymentPluginApiException {
+ try {
+ checkPluginIsRunning();
+
+ switch(cb.getPluginType()) {
+ case NOTIFICATION:
+ checkValidNotificationPlugin();
+ break;
+ case PAYMENT:
+ checkValidPaymentPlugin();
+ break;
+ default:
+ break;
+ }
+
+ final Ruby runtime = getRuntime();
+ return cb.doCall(runtime);
+ } catch (RuntimeException e) {
+ log.warn("RuntimeException in jruby plugin ", e);
+ throw e;
+ }
+ }
}
diff --git a/util/src/test/java/com/ning/billing/mock/api/MockExtBusEvent.java b/util/src/test/java/com/ning/billing/mock/api/MockExtBusEvent.java
new file mode 100644
index 0000000..688c90a
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/mock/api/MockExtBusEvent.java
@@ -0,0 +1,66 @@
+package com.ning.billing.mock.api;
+
+import java.util.UUID;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.beatrix.bus.api.ExtBusEvent;
+import com.ning.billing.beatrix.bus.api.ExtBusEventType;
+
+/**
+ * Used for Jruby plugin that import util test package for default implementation of interfaces in api.
+ * So despite the appearences, this class is used.
+ */
+public class MockExtBusEvent implements ExtBusEvent {
+
+ private final ExtBusEventType eventType;
+ private final ObjectType objectType;
+ private final UUID objectId;
+ private final UUID accountId;
+ private final UUID tenantId;
+
+
+ public MockExtBusEvent(final ExtBusEventType eventType,
+ final ObjectType objectType,
+ final UUID objectId,
+ final UUID accountId,
+ final UUID tenantId) {
+ this.eventType = eventType;
+ this.objectId = objectId;
+ this.objectType = objectType;
+ this.accountId = accountId;
+ this.tenantId = tenantId;
+ }
+
+ @Override
+ public ExtBusEventType getEventType() {
+ return eventType;
+ }
+
+ @Override
+ public ObjectType getObjectType() {
+ return objectType;
+ }
+
+ @Override
+ public UUID getObjectId() {
+ return objectId;
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ @Override
+ public UUID getTenantId() {
+ return tenantId;
+ }
+
+ @Override
+ public String toString() {
+ return "MockExtBusEvent [eventType=" + eventType + ", objectType="
+ + objectType + ", objectId=" + objectId + ", accountId="
+ + accountId + ", tenantId=" + tenantId + "]";
+ }
+
+}
diff --git a/util/src/test/java/com/ning/billing/util/clock/TestClockMock.java b/util/src/test/java/com/ning/billing/util/clock/TestClockMock.java
index ad5e9db..b080f69 100644
--- a/util/src/test/java/com/ning/billing/util/clock/TestClockMock.java
+++ b/util/src/test/java/com/ning/billing/util/clock/TestClockMock.java
@@ -38,7 +38,7 @@ public class TestClockMock extends UtilTestSuiteNoDB {
final DateTime startingTime = new DateTime(DateTimeZone.UTC);
// Lame, but required due to the truncation magic
- Awaitility.await().atMost(999, MILLISECONDS).until(new Callable<Boolean>() {
+ Awaitility.await().atMost(1001, MILLISECONDS).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return clock.getUTCNow().isAfter(startingTime);