killbill-memoizeit

Details

diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 06eb9a3..db7a2ba 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -22,6 +22,7 @@
         <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
         <outputRelativeToContentRoot value="true" />
         <processorPath useClasspath="true" />
+        <module name="currency" />
         <module name="killbill-account" />
         <module name="killbill-beatrix" />
         <module name="killbill-catalog" />
@@ -48,6 +49,7 @@
       </profile>
     </annotationProcessing>
     <bytecodeTargetLevel>
+      <module name="currency" target="1.6" />
       <module name="killbill" target="1.6" />
       <module name="killbill-account" target="1.6" />
       <module name="killbill-beatrix" target="1.6" />
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 437fcd7..88e6931 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -6,6 +6,7 @@
     <file url="file://$PROJECT_DIR$/api" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/beatrix" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/catalog" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/currency" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/entitlement" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/invoice" charset="UTF-8" />
     <file url="file://$PROJECT_DIR$/jaxrs" charset="UTF-8" />
diff --git a/.idea/modules.xml b/.idea/modules.xml
index d5ca1f3..03d8206 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,6 +2,7 @@
 <project version="4">
   <component name="ProjectModuleManager">
     <modules>
+      <module fileurl="file://$PROJECT_DIR$/currency/currency.iml" filepath="$PROJECT_DIR$/currency/currency.iml" />
       <module fileurl="file://$PROJECT_DIR$/killbill.iml" filepath="$PROJECT_DIR$/killbill.iml" />
       <module fileurl="file://$PROJECT_DIR$/account/killbill-account.iml" filepath="$PROJECT_DIR$/account/killbill-account.iml" />
       <module fileurl="file://$PROJECT_DIR$/beatrix/killbill-beatrix.iml" filepath="$PROJECT_DIR$/beatrix/killbill-beatrix.iml" />

beatrix/pom.xml 4(+4 -0)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 7b100f1..e92f541 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -70,6 +70,10 @@
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-currency</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
             <artifactId>killbill-entitlement</artifactId>
         </dependency>
         <dependency>
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
index 044cfb7..cfbe80d 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.net.URL;
 import java.util.Set;
 
+import com.ning.billing.currency.glue.CurrencyModule;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import org.skife.config.ConfigSource;
 
@@ -119,6 +120,7 @@ public class BeatrixIntegrationModule extends AbstractModule {
         install(new DefaultJunctionModule(configSource));
         install(new IntegrationTestOverdueModule(configSource));
         install(new AuditModule());
+        install(new CurrencyModule(configSource));
         install(new UsageModule(configSource));
         install(new TenantModule(configSource));
         install(new ExportModule());
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyCurrencyPlugin.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyCurrencyPlugin.java
new file mode 100644
index 0000000..abe691b
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestJrubyCurrencyPlugin.java
@@ -0,0 +1,101 @@
+/*
+ * 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.beatrix.integration.osgi;
+
+import java.math.BigDecimal;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ning.billing.beatrix.osgi.SetupBundleWithAssertion;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.currency.plugin.api.CurrencyPluginApi;
+import com.ning.billing.currency.plugin.api.Rate;
+import com.ning.billing.osgi.api.OSGIServiceRegistration;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class TestJrubyCurrencyPlugin extends TestOSGIBase {
+
+    private final String BUNDLE_TEST_RESOURCE_PREFIX = "killbill-currency-plugin";
+    private final String BUNDLE_TEST_RESOURCE = BUNDLE_TEST_RESOURCE_PREFIX + ".tar.gz";
+
+
+    @Inject
+    private OSGIServiceRegistration<CurrencyPluginApi> currencyPluginApiOSGIServiceRegistration;
+
+    @BeforeClass(groups = "slow")
+    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 testCurrencyApis() throws Exception {
+
+        CurrencyPluginApi api = getTestPluginCurrencyApi();
+
+        final Set<Currency> currencies = api.getBaseCurrencies();
+        assertEquals(currencies.size(), 1);
+        assertEquals(currencies.iterator().next(), Currency.USD);
+
+        final DateTime res = api.getLatestConversionDate(Currency.USD);
+        assertNotNull(res);
+
+        final Set<Rate> rates = api.getCurrentRates(Currency.USD);
+        assertEquals(rates.size(), 1);
+        final Rate theRate = rates.iterator().next();
+        assertEquals(theRate.getBaseCurrency(), Currency.USD);
+        assertEquals(theRate.getCurrency(), Currency.BRL);
+        Assert.assertTrue(theRate.getValue().compareTo(new BigDecimal("12.3")) == 0);
+
+    }
+
+    private CurrencyPluginApi getTestPluginCurrencyApi() {
+        int retry = 5;
+
+        // It is expected to have a nul result if the initialization of Killbill went faster than the registration of the plugin services
+        CurrencyPluginApi result = null;
+        do {
+            result = currencyPluginApiOSGIServiceRegistration.getServiceForName(BUNDLE_TEST_RESOURCE_PREFIX);
+            if (result == null) {
+                try {
+                    log.info("Waiting for Killbill initialization to complete time = " + clock.getUTCNow());
+                    Thread.sleep(1000);
+                } catch (InterruptedException ignore) {
+                }
+            }
+        } while (result == null && retry-- > 0);
+        Assert.assertNotNull(result);
+        return result;
+    }
+
+}
diff --git a/beatrix/src/test/resources/killbill-currency-plugin.tar.gz b/beatrix/src/test/resources/killbill-currency-plugin.tar.gz
new file mode 100644
index 0000000..5366262
Binary files /dev/null and b/beatrix/src/test/resources/killbill-currency-plugin.tar.gz differ

currency/pom.xml 23(+10 -13)

diff --git a/currency/pom.xml b/currency/pom.xml
index 840cc47..40c5153 100644
--- a/currency/pom.xml
+++ b/currency/pom.xml
@@ -14,10 +14,7 @@
   ~ License for the specific language governing permissions and limitations
   ~ under the License.
   -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <artifactId>killbill</artifactId>
@@ -26,7 +23,7 @@
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>currency</artifactId>
+    <artifactId>killbill-currency</artifactId>
     <packaging>jar</packaging>
     <name>killbill-currency</name>
 
@@ -66,6 +63,14 @@
             <artifactId>killbill-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-internal-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.ning.billing.plugin</groupId>
             <artifactId>killbill-plugin-api-currency</artifactId>
         </dependency>
@@ -77,14 +82,6 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.ning.billing</groupId>
-            <artifactId>killbill-internal-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.ning.billing</groupId>
-            <artifactId>killbill-util</artifactId>
-        </dependency>
 
         <!--
         <dependency>

osgi/pom.xml 15(+15 -0)

diff --git a/osgi/pom.xml b/osgi/pom.xml
index b35b6e5..4cdd8fe 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -73,6 +73,21 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing.plugin</groupId>
+            <artifactId>killbill-plugin-api-currency</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing.plugin</groupId>
+            <artifactId>killbill-plugin-api-notification</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing.plugin</groupId>
+            <artifactId>killbill-plugin-api-payment</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
diff --git a/osgi/src/main/java/com/ning/billing/osgi/KillbillActivator.java b/osgi/src/main/java/com/ning/billing/osgi/KillbillActivator.java
index ed3e179..595f960 100644
--- a/osgi/src/main/java/com/ning/billing/osgi/KillbillActivator.java
+++ b/osgi/src/main/java/com/ning/billing/osgi/KillbillActivator.java
@@ -37,6 +37,7 @@ import org.osgi.service.http.HttpService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.ning.billing.currency.plugin.api.CurrencyPluginApi;
 import com.ning.billing.osgi.api.OSGIKillbill;
 import com.ning.billing.osgi.api.OSGIPluginProperties;
 import com.ning.billing.osgi.api.OSGIServiceDescriptor;
@@ -71,13 +72,14 @@ public class KillbillActivator implements BundleActivator, ServiceListener {
                              final HttpService defaultHttpService,
                              final KillbillEventObservable observable,
                              final OSGIServiceRegistration<Servlet> servletRouter,
-                             final OSGIServiceRegistration<PaymentPluginApi> paymentProviderPluginRegistry) {
+                             final OSGIServiceRegistration<PaymentPluginApi> paymentProviderPluginRegistry,
+                             final OSGIServiceRegistration<CurrencyPluginApi> currencyProviderPluginRegistry) {
         this.osgiKillbill = osgiKillbill;
         this.defaultHttpService = defaultHttpService;
         this.dataSource = dataSource;
         this.observable = observable;
         this.registrar = new OSGIKillbillRegistrar();
-        this.allRegistrationHandlers = ImmutableList.<OSGIServiceRegistration>of(servletRouter, paymentProviderPluginRegistry);
+        this.allRegistrationHandlers = ImmutableList.<OSGIServiceRegistration>of(servletRouter, paymentProviderPluginRegistry, currencyProviderPluginRegistry);
     }
 
     @Override
diff --git a/osgi-bundles/bundles/jruby/pom.xml b/osgi-bundles/bundles/jruby/pom.xml
index 5238ff1..03a1a71 100644
--- a/osgi-bundles/bundles/jruby/pom.xml
+++ b/osgi-bundles/bundles/jruby/pom.xml
@@ -47,6 +47,10 @@
             <artifactId>killbill-plugin-api-payment</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing.plugin</groupId>
+            <artifactId>killbill-plugin-api-currency</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-osgi-bundles-lib-killbill</artifactId>
         </dependency>
@@ -144,6 +148,7 @@
                             com.ning.billing.overdue;
                             com.ning.billing.payment.api;
                             com.ning.billing.payment.plugin.api;
+                            com.ning.billing.currency.plugin.api;
                             com.ning.billing.tenant.api;
                             com.ning.billing.usage.api;
                             com.ning.billing.util.api;
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 8b2a2ef..38fc7cb 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
@@ -47,6 +47,7 @@ public class JRubyActivator extends KillbillActivatorBase {
 
     private static final String KILLBILL_PLUGIN_JPAYMENT = "Killbill::Plugin::Api::PaymentPluginApi";
     private static final String KILLBILL_PLUGIN_JNOTIFICATION = "Killbill::Plugin::Api::NotificationPluginApi";
+    private static final String KILLBILL_PLUGIN_JCURRENCY = "Killbill::Plugin::Api::CurrencyPluginApi";
 
     public void start(final BundleContext context) throws Exception {
         super.start(context);
@@ -68,6 +69,9 @@ public class JRubyActivator extends KillbillActivatorBase {
                 } else if (PluginType.PAYMENT.equals(rubyConfig.getPluginType())) {
                     plugin = new JRubyPaymentPlugin(rubyConfig, context, logService);
                     pluginMain = KILLBILL_PLUGIN_JPAYMENT;
+                } else if (PluginType.CURRENCY.equals(rubyConfig.getPluginType())) {
+                    plugin = new JRubyCurrencyPlugin(rubyConfig, context, logService);
+                    pluginMain = KILLBILL_PLUGIN_JCURRENCY;
                 } else {
                     throw new IllegalStateException("Unsupported plugin type " + rubyConfig.getPluginType());
                 }
diff --git a/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyCurrencyPlugin.java b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyCurrencyPlugin.java
new file mode 100644
index 0000000..3f19e8f
--- /dev/null
+++ b/osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyCurrencyPlugin.java
@@ -0,0 +1,133 @@
+/*
+ * 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.osgi.bundles.jruby;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.joda.time.DateTime;
+import org.jruby.Ruby;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.currency.plugin.api.CurrencyPluginApi;
+import com.ning.billing.currency.plugin.api.Rate;
+import com.ning.billing.osgi.api.OSGIPluginProperties;
+import com.ning.billing.osgi.api.config.PluginRubyConfig;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
+
+public class JRubyCurrencyPlugin extends JRubyPlugin implements CurrencyPluginApi {
+
+    private volatile ServiceRegistration<CurrencyPluginApi> currencyPluginRegistration;
+
+    public JRubyCurrencyPlugin(final PluginRubyConfig config, final BundleContext bundleContext, final LogService logger) {
+        super(config, bundleContext, logger);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void startPlugin(final BundleContext context) {
+        super.startPlugin(context);
+
+        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put("name", pluginMainClass);
+        props.put(OSGIPluginProperties.PLUGIN_NAME_PROP, pluginGemName);
+        currencyPluginRegistration = (ServiceRegistration<CurrencyPluginApi>) context.registerService(CurrencyPluginApi.class.getName(), this, props);
+    }
+
+    @Override
+    public void stopPlugin(final BundleContext context) {
+        if (currencyPluginRegistration != null) {
+            currencyPluginRegistration.unregister();
+        }
+        super.stopPlugin(context);
+    }
+
+    @Override
+    public Set<Currency> getBaseCurrencies() {
+        try {
+            return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.CURRENCY) {
+                @Override
+                public Set<Currency> doCall(final Ruby runtime) throws PaymentPluginApiException {
+                    return ((CurrencyPluginApi) pluginInstance).getBaseCurrencies();
+                }
+            });
+        } catch (PaymentPluginApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public DateTime getLatestConversionDate(final Currency currency) {
+        try {
+            return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.CURRENCY) {
+                @Override
+                public DateTime doCall(final Ruby runtime) throws PaymentPluginApiException {
+                    return ((CurrencyPluginApi) pluginInstance).getLatestConversionDate(currency);
+                }
+            });
+        } catch (PaymentPluginApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public SortedSet<DateTime> getConversionDates(final Currency currency) {
+        try {
+            return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.CURRENCY) {
+                @Override
+                public SortedSet<DateTime> doCall(final Ruby runtime) throws PaymentPluginApiException {
+                    return ((CurrencyPluginApi) pluginInstance).getConversionDates(currency);
+                }
+            });
+        } catch (PaymentPluginApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public Set<Rate> getCurrentRates(final Currency currency) {
+        try {
+            return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.CURRENCY) {
+                @Override
+                public Set<Rate> doCall(final Ruby runtime) throws PaymentPluginApiException {
+                    return ((CurrencyPluginApi) pluginInstance).getCurrentRates(currency);
+                }
+            });
+        } catch (PaymentPluginApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public Set<Rate> getRates(final Currency currency, final DateTime time) {
+        try {
+            return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.CURRENCY) {
+                @Override
+                public Set<Rate> doCall(final Ruby runtime) throws PaymentPluginApiException {
+                    return ((CurrencyPluginApi) pluginInstance).getRates(currency, time);
+                }
+            });
+        } catch (PaymentPluginApiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
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 f3ab64c..68195ff 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
@@ -40,7 +40,7 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.entity.Pagination;
 
-public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi {
+public  class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi {
 
     private volatile ServiceRegistration<PaymentPluginApi> paymentInfoPluginRegistration;
 
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 050a469..87cf97c 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
@@ -47,6 +47,7 @@ public abstract class JRubyPlugin {
     private static final String KILLBILL_PLUGIN_BASE = "Killbill::Plugin::PluginBase";
     private static final String KILLBILL_PLUGIN_NOTIFICATION = "Killbill::Plugin::Notification";
     private static final String KILLBILL_PLUGIN_PAYMENT = "Killbill::Plugin::Payment";
+    private static final String KILLBILL_PLUGIN_CURRENCY = "Killbill::Plugin::Currency";
 
     // Magic ruby variables
     private static final String KILLBILL_SERVICES = "java_apis";
@@ -171,6 +172,14 @@ public abstract class JRubyPlugin {
         }
     }
 
+    private void checkValidCurrencyPlugin() throws IllegalArgumentException {
+        try {
+            container.runScriptlet(checkInstanceOfPlugin(KILLBILL_PLUGIN_CURRENCY));
+        } catch (EvalFailedException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
     private String checkInstanceOfPlugin(final String baseClass) {
         final StringBuilder builder = new StringBuilder(getRequireLine());
         builder.append("raise ArgumentError.new('Invalid plugin: ")
@@ -239,6 +248,7 @@ public abstract class JRubyPlugin {
     public enum VALIDATION_PLUGIN_TYPE {
         NOTIFICATION,
         PAYMENT,
+        CURRENCY,
         NONE
     }
 
@@ -269,6 +279,9 @@ public abstract class JRubyPlugin {
                     case PAYMENT:
                         checkValidPaymentPlugin();
                         break;
+                    case CURRENCY:
+                        checkValidCurrencyPlugin();
+                        break;
                     default:
                         break;
                 }
diff --git a/osgi-bundles/tests/beatrix/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java b/osgi-bundles/tests/beatrix/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
index c4ef01b..b0fd9ff 100644
--- a/osgi-bundles/tests/beatrix/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
+++ b/osgi-bundles/tests/beatrix/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
@@ -160,6 +160,7 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
         };
     }
 
+
     @Override
     public void resetPaymentMethods(final UUID kbAccountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
     }

pom.xml 3(+2 -1)

diff --git a/pom.xml b/pom.xml
index 1f51d19..7485ef7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.5.1</version>
+        <version>0.4.19-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.6.18-SNAPSHOT</version>
@@ -45,6 +45,7 @@
         <module>tenant</module>
         <module>osgi</module>
         <module>osgi-bundles</module>
+        <module>currency</module>
     </modules>
     <scm>
         <connection>scm:git:git://github.com/killbill/killbill.git</connection>

server/pom.xml 4(+4 -0)

diff --git a/server/pom.xml b/server/pom.xml
index 026cfce..79db5eb 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -99,6 +99,10 @@
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-currency</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
             <artifactId>killbill-invoice</artifactId>
         </dependency>
         <dependency>
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index 7dab34b..8c30cba 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -21,6 +21,7 @@ import javax.sql.DataSource;
 
 import com.ning.billing.clock.Clock;
 import com.ning.billing.clock.ClockMock;
+import com.ning.billing.currency.glue.CurrencyModule;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import org.skife.config.ConfigSource;
 import org.skife.config.SimplePropertyConfigSource;
@@ -158,6 +159,7 @@ public class KillbillServerModule extends AbstractModule {
         install(new BeatrixModule(configSource));
         install(new DefaultJunctionModule(configSource));
         install(new DefaultOverdueModule(configSource));
+        install(new CurrencyModule(configSource));
         install(new TenantModule(configSource));
         install(new ExportModule());
         install(new TagStoreModule());
diff --git a/util/src/main/java/com/ning/billing/util/config/CurrencyConfig.java b/util/src/main/java/com/ning/billing/util/config/CurrencyConfig.java
index 359b5cf..90053ed 100644
--- a/util/src/main/java/com/ning/billing/util/config/CurrencyConfig.java
+++ b/util/src/main/java/com/ning/billing/util/config/CurrencyConfig.java
@@ -23,6 +23,7 @@ import org.skife.config.Description;
 public interface CurrencyConfig extends KillbillConfig {
 
     @Config("killbill.currency.provider.default")
+    @Default("killbill-currency-plugin")
     @Description("Default currency provider to use")
     public String getDefaultCurrencyProvider();
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/OSGIConfig.java b/util/src/main/java/com/ning/billing/util/config/OSGIConfig.java
index f9fb161..ae17e54 100644
--- a/util/src/main/java/com/ning/billing/util/config/OSGIConfig.java
+++ b/util/src/main/java/com/ning/billing/util/config/OSGIConfig.java
@@ -65,6 +65,7 @@ public interface OSGIConfig extends KillbillConfig {
              "com.ning.billing.util.callcontext," +
              "com.ning.billing.util.customfield," +
              "com.ning.billing.notification.plugin," +
+             "com.ning.billing.currency.plugin.api," +
              "com.ning.billing.util.email," +
              "com.ning.billing.util.entity," +
              "com.ning.billing.util.tag," +