killbill-memoizeit
Changes
.idea/codeStyleSettings.xml 202(+202 -0)
.idea/dictionaries/pierre.xml 10(+9 -1)
.idea/inspectionProfiles/Project_Default.xml 12(+12 -0)
.idea/libraries/Maven__com_ning_billing_killbill_entitlement_test_jar_tests_0_3_6_SNAPSHOT.xml 15(+0 -15)
.idea/libraries/Maven__com_ning_billing_killbill_junction_test_jar_tests_0_3_6_SNAPSHOT.xml 13(+0 -13)
.idea/libraries/Maven__com_ning_billing_killbill_payment_test_jar_tests_0_3_6_SNAPSHOT.xml 13(+0 -13)
.idea/libraries/Maven__com_ning_billing_plugin_killbill_plugin_api_notification_0_3_1_SNAPSHOT.xml 13(+0 -13)
.idea/libraries/Maven__com_ning_billing_plugin_killbill_plugin_api_payment_0_3_1_SNAPSHOT.xml 13(+0 -13)
account/killbill-account.iml 24(+16 -8)
account/pom.xml 7(+6 -1)
api/killbill-internal-api.iml 8(+6 -2)
api/pom.xml 2(+1 -1)
beatrix/killbill-beatrix.iml 49(+34 -15)
beatrix/pom.xml 8(+6 -2)
beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestBasicOSGIWithTestBundle.java 13(+7 -6)
bin/start-server 2(+1 -1)
catalog/killbill-catalog.iml 24(+16 -8)
catalog/pom.xml 2(+1 -1)
entitlement/killbill-entitlement.iml 42(+32 -10)
entitlement/pom.xml 7(+6 -1)
invoice/killbill-invoice.iml 34(+25 -9)
invoice/pom.xml 7(+6 -1)
jaxrs/killbill-jaxrs.iml 30(+22 -8)
jaxrs/pom.xml 2(+1 -1)
junction/killbill-junction.iml 43(+33 -10)
junction/pom.xml 7(+6 -1)
NEWS 16(+16 -0)
osgi/killbill-osgi.iml 30(+22 -8)
osgi/pom.xml 2(+1 -1)
osgi-bundles/bundles/jruby/pom.xml 2(+1 -1)
osgi-bundles/bundles/jruby/src/main/java/com/ning/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java 11(+7 -4)
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
osgi-bundles/bundles/pom.xml 2(+1 -1)
osgi-bundles/defaultbundles/pom.xml 6(+1 -5)
osgi-bundles/libs/killbill/pom.xml 2(+1 -1)
osgi-bundles/libs/pom.xml 2(+1 -1)
osgi-bundles/libs/slf4j-osgi/pom.xml 2(+1 -1)
osgi-bundles/pom.xml 2(+1 -1)
osgi-bundles/tests/beatrix/pom.xml 2(+1 -1)
osgi-bundles/tests/beatrix/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java 13(+8 -5)
osgi-bundles/tests/payment/pom.xml 2(+1 -1)
osgi-bundles/tests/payment/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java 4(+2 -2)
osgi-bundles/tests/pom.xml 2(+1 -1)
overdue/killbill-overdue.iml 42(+32 -10)
overdue/pom.xml 8(+6 -2)
overdue/src/test/java/com/ning/billing/ovedue/notification/TestDefaultOverdueCheckPoster.java 2(+1 -1)
payment/killbill-payment.iml 42(+30 -12)
payment/pom.xml 7(+6 -1)
payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java 13(+11 -2)
payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java 19(+16 -3)
pom.xml 4(+2 -2)
README.md 63(+1 -62)
server/killbill-server.iml 49(+35 -14)
server/pom.xml 7(+6 -1)
server/src/main/resources/shiro.ini 29(+29 -0)
server/src/test/resources/shiro.ini 27(+10 -17)
subscription/killbill-subscription.iml 42(+32 -10)
subscription/pom.xml 7(+6 -1)
tenant/killbill-tenant.iml 34(+24 -10)
tenant/pom.xml 7(+6 -1)
usage/killbill-usage.iml 35(+27 -8)
usage/pom.xml 7(+6 -1)
util/killbill-util.iml 33(+25 -8)
util/pom.xml 29(+27 -2)
util/src/main/java/com/ning/billing/util/security/AopAllianceMethodInterceptorAdapter.java 41(+17 -24)
util/src/main/java/com/ning/billing/util/security/AopAllianceMethodInvocationAdapter.java 51(+51 -0)
util/src/main/java/com/ning/billing/util/security/PermissionAnnotationMethodInterceptor.java 17(+12 -5)
util/src/main/java/com/ning/billing/util/security/shiro/realm/KillBillJndiLdapRealm.java 222(+222 -0)
util/src/main/java/com/ning/billing/util/security/shiro/realm/SkipSSLCheckSocketFactory.java 78(+78 -0)
util/src/main/resources/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg 51(+51 -0)
util/src/test/java/com/ning/billing/DBTestingHelper.java 240(+121 -119)
util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java 4(+2 -2)
util/src/test/java/com/ning/billing/util/security/shiro/realm/TestKillBillJndiLdapRealm.java 89(+89 -0)
util/src/test/java/com/ning/billing/util/security/TestPermissionAnnotationMethodInterceptor.java 146(+146 -0)
util/src/test/resources/shiro.ini 21(+2 -19)
Details
.idea/codeStyleSettings.xml 202(+202 -0)
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 0391fca..d2196b4 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -28,6 +28,7 @@
</value>
</option>
<XML>
+ <option name="XML_ATTRIBUTE_WRAP" value="0" />
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
@@ -42,12 +43,213 @@
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_METHOD_BRACKETS" value="true" />
+ <option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
+ <arrangement>
+ <groups>
+ <group>
+ <type>GETTERS_AND_SETTERS</type>
+ <order>KEEP</order>
+ </group>
+ </groups>
+ <rules>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PUBLIC</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PROTECTED</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PRIVATE</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PUBLIC</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PROTECTED</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PRIVATE</MODIFIER>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PUBLIC</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PROTECTED</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PRIVATE</MODIFIER>
+ <MODIFIER>FINAL</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PUBLIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PROTECTED</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PACKAGE_PRIVATE</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>FIELD</TYPE>
+ <MODIFIER>PRIVATE</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>FIELD</TYPE>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>CONSTRUCTOR</TYPE>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>METHOD</TYPE>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>METHOD</TYPE>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>ENUM</TYPE>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>INTERFACE</TYPE>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <AND>
+ <TYPE>CLASS</TYPE>
+ <MODIFIER>STATIC</MODIFIER>
+ </AND>
+ </match>
+ </rule>
+ <rule>
+ <match>
+ <TYPE>CLASS</TYPE>
+ </match>
+ </rule>
+ </rules>
+ </arrangement>
</codeStyleSettings>
</value>
</option>
.idea/dictionaries/pierre.xml 10(+9 -1)
diff --git a/.idea/dictionaries/pierre.xml b/.idea/dictionaries/pierre.xml
index 118b145..e586f6b 100644
--- a/.idea/dictionaries/pierre.xml
+++ b/.idea/dictionaries/pierre.xml
@@ -1,3 +1,11 @@
<component name="ProjectDictionaryState">
- <dictionary name="pierre" />
+ <dictionary name="pierre">
+ <words>
+ <w>aoped</w>
+ <w>jdbc</w>
+ <w>killbill</w>
+ <w>shiro</w>
+ <w>stephane</w>
+ </words>
+ </dictionary>
</component>
\ No newline at end of file
.idea/inspectionProfiles/Project_Default.xml 12(+12 -0)
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 95037c1..e0ce11c 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -2,6 +2,7 @@
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
+ <inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConfusingOctalEscape" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ControlFlowStatementWithoutBraces" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CyclicClassDependency" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -34,5 +35,16 @@
<inspection_tool class="UnnecessaryConstantArrayCreationExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfJDBCDriverClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfSunClasses" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="groupsTestNG" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="groups">
+ <value>
+ <list size="3">
+ <item index="0" class="java.lang.String" itemvalue="slow" />
+ <item index="1" class="java.lang.String" itemvalue="fast" />
+ <item index="2" class="java.lang.String" itemvalue="mysql" />
+ </list>
+ </value>
+ </option>
+ </inspection_tool>
</profile>
</component>
\ No newline at end of file
account/killbill-account.iml 24(+16 -8)
diff --git a/account/killbill-account.iml b/account/killbill-account.iml
index 38da507..fc0f3d0 100644
--- a/account/killbill-account.iml
+++ b/account/killbill-account.iml
@@ -20,10 +20,10 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -32,13 +32,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -46,9 +47,16 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
account/pom.xml 7(+6 -1)
diff --git a/account/pom.xml b/account/pom.xml
index d497f5b..90a7a80 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-account</artifactId>
@@ -83,6 +83,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index a7c1714..96d6191 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -64,7 +64,7 @@ public class DefaultAccountUserApi implements AccountUserApi {
}
final AccountModelDao account = new AccountModelDao(data);
- accountDao.create(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
+ accountDao.create(account, internalCallContextFactory.createInternalCallContext(context));
return new DefaultAccount(account);
}
@@ -90,6 +90,17 @@ public class DefaultAccountUserApi implements AccountUserApi {
}
@Override
+ public List<Account> searchAccounts(final String searchKey, final TenantContext context) {
+ final List<AccountModelDao> accountModelDaos = accountDao.searchAccounts(searchKey, internalCallContextFactory.createInternalTenantContext(context));
+ return ImmutableList.<Account>copyOf(Collections2.transform(accountModelDaos, new Function<AccountModelDao, Account>() {
+ @Override
+ public Account apply(final AccountModelDao input) {
+ return new DefaultAccount(input);
+ }
+ }));
+ }
+
+ @Override
public List<Account> getAccounts(final TenantContext context) {
final List<AccountModelDao> accountModelDaos = accountDao.get(internalCallContextFactory.createInternalTenantContext(context));
return ImmutableList.<Account>copyOf(Collections2.transform(accountModelDaos, new Function<AccountModelDao, Account>() {
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index 9f11a5e..f390c11 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -29,6 +29,8 @@ public interface AccountDao extends EntityDao<AccountModelDao, Account, AccountA
public AccountModelDao getAccountByKey(String key, InternalTenantContext context);
+ public List<AccountModelDao> searchAccounts(String searchKey, InternalTenantContext context);
+
/**
* @throws AccountApiException when externalKey is null
*/
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index f49f454..01aa04e 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -16,12 +16,14 @@
package com.ning.billing.account.dao;
+import java.util.List;
import java.util.UUID;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.Define;
import com.ning.billing.account.api.Account;
import com.ning.billing.util.audit.ChangeType;
@@ -39,6 +41,10 @@ public interface AccountSqlDao extends EntitySqlDao<AccountModelDao, Account> {
@BindBean final InternalTenantContext context);
@SqlQuery
+ public List<AccountModelDao> searchAccounts(@Define("searchKey") final String searchKey,
+ @BindBean final InternalTenantContext context);
+
+ @SqlQuery
public UUID getIdFromKey(@Bind("externalKey") final String key,
@BindBean final InternalTenantContext context);
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index 76aa8cc..d3f77ed 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -104,6 +104,16 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
}
@Override
+ public List<AccountModelDao> searchAccounts(final String searchKey, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<AccountModelDao>>() {
+ @Override
+ public List<AccountModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(AccountSqlDao.class).searchAccounts(searchKey, context);
+ }
+ });
+ }
+
+ @Override
public UUID getIdFromKey(final String externalKey, final InternalTenantContext context) throws AccountApiException {
if (externalKey == null) {
throw new AccountApiException(ErrorCode.ACCOUNT_CANNOT_MAP_NULL_KEY, "");
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
index 5ed297b..630f1dc 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
@@ -80,14 +80,30 @@ updatePaymentMethod() ::= <<
WHERE id = :id <AND_CHECK_TENANT()>;
>>
-
-
getAccountByKey() ::= <<
select <allTableFields()>
from accounts
where external_key = :externalKey <AND_CHECK_TENANT()>;
>>
+searchAccounts(searchKey) ::= <<
+select <allTableFields()>
+from accounts
+where name like ('%<searchKey>%') <AND_CHECK_TENANT()>
+union
+select <allTableFields()>
+from accounts
+where email like ('%<searchKey>%') <AND_CHECK_TENANT()>
+union
+select <allTableFields()>
+from accounts
+where external_key like ('%<searchKey>%') <AND_CHECK_TENANT()>
+union
+select <allTableFields()>
+from accounts
+where company_name like ('%<searchKey>%') <AND_CHECK_TENANT()>
+;
+>>
getIdFromKey() ::= <<
SELECT id
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index 8d10192..e4e3aa3 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -16,6 +16,7 @@
package com.ning.billing.account.dao;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -102,6 +103,20 @@ public class MockAccountDao extends MockEntityDaoBase<AccountModelDao, Account,
}
@Override
+ public List<AccountModelDao> searchAccounts(final String searchKey, final InternalTenantContext context) {
+ final List<AccountModelDao> results = new LinkedList<AccountModelDao>();
+ for (final AccountModelDao account : get(context)) {
+ if ((account.getName() != null && account.getName().contains(searchKey)) ||
+ (account.getEmail() != null && account.getEmail().contains(searchKey)) ||
+ (account.getExternalKey() != null && account.getExternalKey().contains(searchKey)) ||
+ (account.getCompanyName() != null && account.getCompanyName().contains(searchKey))) {
+ results.add(account);
+ }
+ }
+ return results;
+ }
+
+ @Override
public UUID getIdFromKey(final String externalKey, final InternalTenantContext context) {
final AccountModelDao account = getAccountByKey(externalKey, context);
return account == null ? null : account.getId();
api/killbill-internal-api.iml 8(+6 -2)
diff --git a/api/killbill-internal-api.iml b/api/killbill-internal-api.iml
index e8866bf..8c2260d 100644
--- a/api/killbill-internal-api.iml
+++ b/api/killbill-internal-api.iml
@@ -9,11 +9,15 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
api/pom.xml 2(+1 -1)
diff --git a/api/pom.xml b/api/pom.xml
index 4c505f5..6c5aab6 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-internal-api</artifactId>
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueState.java b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
index 51ef0e2..b0682b1 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueState.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
@@ -18,9 +18,6 @@ package com.ning.billing.overdue;
import org.joda.time.Period;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.entitlement.api.Blockable;
-
public interface OverdueState {
@@ -32,7 +29,7 @@ public interface OverdueState {
public boolean disableEntitlementAndChangesBlocked();
- public OverdueCancellationPolicicy getSubscriptionCancellationPolicy();
+ public OverdueCancellationPolicy getSubscriptionCancellationPolicy();
public boolean blockChanges();
beatrix/killbill-beatrix.iml 49(+34 -15)
diff --git a/beatrix/killbill-beatrix.iml b/beatrix/killbill-beatrix.iml
index a1331a9..103ce23 100644
--- a/beatrix/killbill-beatrix.iml
+++ b/beatrix/killbill-beatrix.iml
@@ -12,6 +12,19 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.4.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.0" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.4.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.4.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.4.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
@@ -25,27 +38,28 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-account" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="module" module-name="killbill-util" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-joda:2.0.1" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -53,16 +67,22 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-account" scope="TEST" />
<orderEntry type="module" module-name="killbill-catalog" />
<orderEntry type="module" module-name="killbill-entitlement" />
<orderEntry type="module" module-name="killbill-invoice" />
<orderEntry type="module" module-name="killbill-invoice" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-junction" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
<orderEntry type="module" module-name="killbill-junction" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-osgi" scope="TEST" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" scope="TEST" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
@@ -71,23 +91,22 @@
<orderEntry type="library" scope="TEST" name="Maven: org.apache.felix:org.apache.felix.framework:4.0.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.felix:org.osgi.core:1.0.1" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-jruby" scope="TEST" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-concurrent:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-concurrent:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jruby:jruby-complete:1.7.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.osgi:org.osgi.core:4.3.1" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-test-beatrix" scope="TEST" />
<orderEntry type="module" module-name="killbill-osgi-bundles-test-payment" scope="TEST" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-overdue" scope="TEST" />
<orderEntry type="module" module-name="killbill-payment" />
<orderEntry type="module" module-name="killbill-payment" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-subscription" />
<orderEntry type="module" module-name="killbill-tenant" />
- <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.1" level="project" />
- <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
<orderEntry type="module" module-name="killbill-usage" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
beatrix/pom.xml 8(+6 -2)
diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index d0fa645..25b132e 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-beatrix</artifactId>
@@ -161,13 +161,17 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
-
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/extbus/BeatrixListener.java b/beatrix/src/main/java/com/ning/billing/beatrix/extbus/BeatrixListener.java
index cdcd618..7946dd4 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/extbus/BeatrixListener.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/extbus/BeatrixListener.java
@@ -38,6 +38,7 @@ import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.events.AccountChangeInternalEvent;
import com.ning.billing.util.events.AccountCreationInternalEvent;
import com.ning.billing.util.events.BusInternalEvent;
@@ -72,17 +73,19 @@ public class
private final PersistentBus externalBus;
private final InternalCallContextFactory internalCallContextFactory;
private final AccountInternalApi accountApi;
-
+ private final NonEntityDao nonEntityDao;
protected final ObjectMapper objectMapper;
@Inject
public BeatrixListener(@Named(BeatrixModule.EXTERNAL_BUS) final PersistentBus externalBus,
final InternalCallContextFactory internalCallContextFactory,
- final AccountInternalApi accountApi) {
+ final AccountInternalApi accountApi,
+ final NonEntityDao nonEntityDao) {
this.externalBus = externalBus;
this.internalCallContextFactory = internalCallContextFactory;
this.accountApi = accountApi;
+ this.nonEntityDao = nonEntityDao;
this.objectMapper = new ObjectMapper();
objectMapper.registerModule(new JodaModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
@@ -237,7 +240,7 @@ public class
default:
}
final UUID accountId = getAccountIdFromRecordId(event.getBusEventType(), objectId, context.getAccountRecordId(), context);
- final UUID tenantId = context.toTenantContext().getTenantId();
+ final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
return eventBusType != null ?
new DefaultBusExternalEvent(objectId, objectType, eventBusType, accountId, tenantId, context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()) :
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
index b4dbe24..04e324b 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
@@ -142,7 +142,7 @@ public class DefaultLifecycle implements Lifecycle {
// Used to disable valid injection failure from unit tests
protected void logWarn(final String msg, final Exception e) {
- log.warn(msg);
+ log.warn(msg, e);
}
private Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> findAllHandlers(final KillbillService service) {
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestBasicOSGIWithTestBundle.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestBasicOSGIWithTestBundle.java
index 744af92..56287f9 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestBasicOSGIWithTestBundle.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/osgi/TestBasicOSGIWithTestBundle.java
@@ -37,10 +37,11 @@ import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import com.ning.billing.DBTestingHelper;
import com.ning.billing.account.api.Account;
import com.ning.billing.beatrix.osgi.SetupBundleWithAssertion;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.dbi.DBTestingHelper;
+import com.ning.billing.commons.embeddeddb.EmbeddedDB;
import com.ning.billing.osgi.api.OSGIServiceRegistration;
import com.ning.billing.osgi.glue.OSGIDataSourceConfig;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
@@ -67,10 +68,10 @@ public class TestBasicOSGIWithTestBundle extends TestOSGIBase {
@BeforeClass(groups = "slow")
public void beforeClass() throws Exception {
-
- final String jdbcConnection = getDBTestingHelper().getJdbcConnectionString();
- final String userName = DBTestingHelper.USERNAME;
- final String userPwd = DBTestingHelper.PASSWORD;
+ // Can't use the injected helper as Guice hasn't injected anything yet
+ final String jdbcConnection = DBTestingHelper.get().getJdbcConnectionString();
+ final String userName = DBTestingHelper.get().getUsername();
+ final String userPwd = DBTestingHelper.get().getPassword();
System.setProperty(OSGIDataSourceConfig.DATA_SOURCE_PROP_PREFIX + "jdbc.url", jdbcConnection);
System.setProperty(OSGIDataSourceConfig.DATA_SOURCE_PROP_PREFIX + "jdbc.user", userName);
@@ -90,7 +91,7 @@ public class TestBasicOSGIWithTestBundle extends TestOSGIBase {
public void testBundleTest() throws Exception {
// At this point test bundle should have been started already
- final TestActivatorWithAssertion assertTor = new TestActivatorWithAssertion(getDBI());
+ final TestActivatorWithAssertion assertTor = new TestActivatorWithAssertion(dbi);
assertTor.assertPluginInitialized();
// Create an account and expect test bundle listen to KB events and write the external name in its table
bin/start-server 2(+1 -1)
diff --git a/bin/start-server b/bin/start-server
index f6132f6..72e86b4 100755
--- a/bin/start-server
+++ b/bin/start-server
@@ -23,7 +23,7 @@ HERE=`cd \`dirname $0\`; pwd`
TOP=$HERE/..
SERVER=$TOP/server
-PROPERTIES="$SERVER/src/main/resources/killbill-server.properties"
+PROPERTIES=${PROPERTIES-"$SERVER/src/main/resources/killbill-server.properties"}
DEBUG_OPTS_ECLIPSE=" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=12345 "
DEBUG_OPTS_ECLIPSE_WAIT=" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=12345 "
catalog/killbill-catalog.iml 24(+16 -8)
diff --git a/catalog/killbill-catalog.iml b/catalog/killbill-catalog.iml
index 71e5645..a097881 100644
--- a/catalog/killbill-catalog.iml
+++ b/catalog/killbill-catalog.iml
@@ -12,16 +12,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -32,14 +33,15 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -47,9 +49,15 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:slf4j-simple:1.7.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.3.1" level="project" />
catalog/pom.xml 2(+1 -1)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index 8f9798b..d1ff1c5 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-catalog</artifactId>
entitlement/killbill-entitlement.iml 42(+32 -10)
diff --git a/entitlement/killbill-entitlement.iml b/entitlement/killbill-entitlement.iml
index 6c97505..74e5c95 100644
--- a/entitlement/killbill-entitlement.iml
+++ b/entitlement/killbill-entitlement.iml
@@ -12,6 +12,20 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
@@ -27,10 +41,10 @@
<orderEntry type="module" module-name="killbill-account" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -39,13 +53,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -53,14 +68,21 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" />
<orderEntry type="module" module-name="killbill-subscription" scope="TEST" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
entitlement/pom.xml 7(+6 -1)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 0bc0275..0f93295 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-entitlement</artifactId>
@@ -110,6 +110,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
invoice/killbill-invoice.iml 34(+25 -9)
diff --git a/invoice/killbill-invoice.iml b/invoice/killbill-invoice.iml
index 6290738..8673066 100644
--- a/invoice/killbill-invoice.iml
+++ b/invoice/killbill-invoice.iml
@@ -12,6 +12,14 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
@@ -24,11 +32,11 @@
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:1.2" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -39,13 +47,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -53,11 +62,18 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
invoice/pom.xml 7(+6 -1)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 3fe0ba3..f67e327 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-invoice</artifactId>
@@ -96,6 +96,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index 5ad6816..ff16d36 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -34,12 +34,16 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ning.billing.ErrorCode;
+import com.ning.billing.ObjectType;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.bus.api.PersistentBus;
import com.ning.billing.bus.api.PersistentBus.EventBusException;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.subscription.api.user.SubscriptionBaseApiException;
+import com.ning.billing.clock.Clock;
+import com.ning.billing.commons.locker.GlobalLock;
+import com.ning.billing.commons.locker.GlobalLocker;
+import com.ning.billing.commons.locker.LockFailedException;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceItem;
@@ -57,20 +61,20 @@ import com.ning.billing.invoice.generator.InvoiceGenerator;
import com.ning.billing.invoice.model.DefaultInvoice;
import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.subscription.api.user.SubscriptionBaseApiException;
import com.ning.billing.util.callcontext.InternalCallContext;
-import com.ning.billing.clock.Clock;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.events.BusInternalEvent;
import com.ning.billing.util.events.EffectiveSubscriptionInternalEvent;
import com.ning.billing.util.events.InvoiceAdjustmentInternalEvent;
import com.ning.billing.util.events.InvoiceInternalEvent;
-import com.ning.billing.util.globallocker.GlobalLock;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.GlobalLocker.LockerType;
-import com.ning.billing.util.globallocker.LockFailedException;
+import com.ning.billing.util.globallocker.LockerType;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
-import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.ning.billing.util.svcapi.junction.BillingEventSet;
import com.ning.billing.util.svcapi.junction.BillingInternalApi;
+import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.ning.billing.util.timezone.DateAndTimeZoneContext;
import com.google.common.annotations.VisibleForTesting;
@@ -89,6 +93,7 @@ public class InvoiceDispatcher {
private final AccountInternalApi accountApi;
private final SubscriptionBaseInternalApi subscriptionApi;
private final InvoiceDao invoiceDao;
+ private final NonEntityDao nonEntityDao;
private final InvoiceNotifier invoiceNotifier;
private final GlobalLocker locker;
private final PersistentBus eventBus;
@@ -99,6 +104,7 @@ public class InvoiceDispatcher {
final BillingInternalApi billingApi,
final SubscriptionBaseInternalApi SubscriptionApi,
final InvoiceDao invoiceDao,
+ final NonEntityDao nonEntityDao,
final InvoiceNotifier invoiceNotifier,
final GlobalLocker locker,
final PersistentBus eventBus,
@@ -108,6 +114,7 @@ public class InvoiceDispatcher {
this.subscriptionApi = SubscriptionApi;
this.accountApi = accountApi;
this.invoiceDao = invoiceDao;
+ this.nonEntityDao = nonEntityDao;
this.invoiceNotifier = invoiceNotifier;
this.locker = locker;
this.eventBus = eventBus;
@@ -139,7 +146,7 @@ public class InvoiceDispatcher {
final boolean dryRun, final InternalCallContext context) throws InvoiceApiException {
GlobalLock lock = null;
try {
- lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, accountId.toString(), NB_LOCK_TRY);
+ lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), accountId.toString(), NB_LOCK_TRY);
return processAccountWithLock(accountId, targetDate, dryRun, context);
} catch (LockFailedException e) {
@@ -192,7 +199,7 @@ public class InvoiceDispatcher {
}
} else {
log.info("Generated invoice {} with {} items for accountId {} and targetDate {} (targetDateTime {})", new Object[]{invoice.getId(), invoice.getNumberOfItems(),
- accountId, targetDate, targetDateTime});
+ accountId, targetDate, targetDateTime});
if (!dryRun) {
// Extract the set of invoiceId for which we see items that don't belong to current generated invoice
@@ -254,7 +261,7 @@ public class InvoiceDispatcher {
if (account.isNotifiedForInvoices() && invoice != null && !dryRun) {
// Need to re-hydrate the invoice object to get the invoice number (record id)
// API_FIX InvoiceNotifier public API?
- invoiceNotifier.notify(account, new DefaultInvoice(invoiceDao.getById(invoice.getId(), context)), context.toTenantContext());
+ invoiceNotifier.notify(account, new DefaultInvoice(invoiceDao.getById(invoice.getId(), context)), buildTenantContext(context));
}
return invoice;
@@ -264,6 +271,9 @@ public class InvoiceDispatcher {
}
}
+ private TenantContext buildTenantContext(final InternalTenantContext context) {
+ return context.toTenantContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT));
+ }
@VisibleForTesting
Map<UUID, DateTime> createNextFutureNotificationDate(final List<InvoiceItemModelDao> invoiceItems, final DateAndTimeZoneContext dateAndTimeZoneContext) {
@@ -273,6 +283,7 @@ public class InvoiceDispatcher {
// at which we should be called back for next invoice.
//
for (final InvoiceItemModelDao item : invoiceItems) {
+
if (item.getType() == InvoiceItemType.RECURRING) {
if ((item.getEndDate() != null) &&
(item.getAmount() == null ||
diff --git a/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteNoDB.java b/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteNoDB.java
index 9e4cfe7..179118a 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteNoDB.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteNoDB.java
@@ -27,6 +27,7 @@ import org.testng.annotations.BeforeMethod;
import com.ning.billing.GuicyKillbillTestSuiteNoDB;
import com.ning.billing.bus.api.PersistentBus;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.invoice.api.InvoiceMigrationApi;
import com.ning.billing.invoice.api.InvoicePaymentApi;
import com.ning.billing.invoice.api.InvoiceUserApi;
@@ -37,7 +38,6 @@ import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.clock.Clock;
-import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java b/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
index 061c9b2..aff1faf 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
@@ -28,6 +28,7 @@ import org.testng.annotations.BeforeMethod;
import com.ning.billing.GuicyKillbillTestSuiteWithEmbeddedDB;
import com.ning.billing.bus.api.PersistentBus;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.invoice.api.DefaultInvoiceService;
import com.ning.billing.invoice.api.InvoiceMigrationApi;
import com.ning.billing.invoice.api.InvoicePaymentApi;
@@ -42,7 +43,7 @@ import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.clock.Clock;
-import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
@@ -84,6 +85,8 @@ public abstract class InvoiceTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
@Inject
protected InvoiceDao invoiceDao;
@Inject
+ protected NonEntityDao nonEntityDao;
+ @Inject
protected TagUserApi tagUserApi;
@Inject
protected GlobalLocker locker;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index 105904c..0342859 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -89,7 +89,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- invoiceNotifier, locker, busService.getBus(),
+ nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
Invoice invoice = dispatcher.processAccount(accountId, target, true, internalCallContext);
@@ -143,7 +143,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- invoiceNotifier, locker, busService.getBus(),
+ nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
final Invoice invoice = dispatcher.processAccount(account.getId(), new DateTime("2012-07-30T00:00:00.000Z"), false, internalCallContext);
@@ -203,7 +203,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- invoiceNotifier, locker, busService.getBus(),
+ nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
final DateTime expectedBefore = clock.getUTCNow();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceHelper.java
index aac0a3d..76242b6 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceHelper.java
@@ -38,6 +38,7 @@ import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.subscription.api.SubscriptionBaseTransitionType;
import com.ning.billing.subscription.api.SubscriptionBase;
import com.ning.billing.invoice.api.Invoice;
@@ -59,8 +60,8 @@ import com.ning.billing.subscription.api.user.SubscriptionBaseApiException;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
-import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.ning.billing.util.svcapi.junction.BillingEvent;
@@ -132,9 +133,10 @@ public class TestInvoiceHelper {
private final SubscriptionBaseInternalApi subscriptionApi;
private final BusService busService;
private final InvoiceDao invoiceDao;
- private final GlobalLocker locker;
+ private final GlobalLocker locker;
private final Clock clock;
private final InternalCallContext internalCallContext;
+ private final NonEntityDao nonEntityDao;
// Low level SqlDao used by the tests to directly insert rows
private final InvoicePaymentSqlDao invoicePaymentSqlDao;
@@ -145,7 +147,7 @@ public class TestInvoiceHelper {
@Inject
public TestInvoiceHelper(final InvoiceGenerator generator, final IDBI dbi,
final BillingInternalApi billingApi, final AccountInternalApi accountApi, final SubscriptionBaseInternalApi subscriptionApi, final BusService busService,
- final InvoiceDao invoiceDao, final GlobalLocker locker, final Clock clock, final InternalCallContext internalCallContext) {
+ final InvoiceDao invoiceDao, final GlobalLocker locker, final Clock clock, final NonEntityDao nonEntityDao, final InternalCallContext internalCallContext) {
this.generator = generator;
this.billingApi = billingApi;
this.accountApi = accountApi;
@@ -154,6 +156,7 @@ public class TestInvoiceHelper {
this.invoiceDao = invoiceDao;
this.locker = locker;
this.clock = clock;
+ this.nonEntityDao = nonEntityDao;
this.internalCallContext = internalCallContext;
this.invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
this.invoicePaymentSqlDao = dbi.onDemand(InvoicePaymentSqlDao.class);
@@ -177,7 +180,7 @@ public class TestInvoiceHelper {
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi,
- invoiceDao, invoiceNotifier, locker, busService.getBus(),
+ invoiceDao, nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
Invoice invoice = dispatcher.processAccount(account.getId(), targetDate, true, internalCallContext);
jaxrs/killbill-jaxrs.iml 30(+22 -8)
diff --git a/jaxrs/killbill-jaxrs.iml b/jaxrs/killbill-jaxrs.iml
index 89a28ef..9d9bcec 100644
--- a/jaxrs/killbill-jaxrs.iml
+++ b/jaxrs/killbill-jaxrs.iml
@@ -11,12 +11,19 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -29,16 +36,17 @@
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -46,9 +54,15 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
jaxrs/pom.xml 2(+1 -1)
diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 390922b..02d85b7 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-jaxrs</artifactId>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java
index d5520e6..11ed283 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java
@@ -17,120 +17,150 @@
package com.ning.billing.jaxrs.json;
import java.math.BigDecimal;
-import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CurrencyValueNull;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.Price;
import com.ning.billing.catalog.api.Product;
import com.ning.billing.catalog.api.StaticCatalog;
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class CatalogJsonSimple {
private final String name;
- private final ProductJson[] products;
+ private final List<ProductJson> products;
- public CatalogJsonSimple(StaticCatalog catalog) throws CatalogApiException {
- name = catalog.getCatalogName();
+ @JsonCreator
+ public CatalogJsonSimple(@JsonProperty("name") final String name,
+ @JsonProperty("products") final List<ProductJson> products) {
+ this.name = name;
+ this.products = products;
+ }
- Map<String, ProductJson> productMap = new HashMap<String, CatalogJsonSimple.ProductJson>();
- Plan[] plans = catalog.getCurrentPlans();
- for (Plan plan : plans) {
+ public CatalogJsonSimple(final StaticCatalog catalog) throws CatalogApiException {
+ name = catalog.getCatalogName();
- Product product = plan.getProduct();
- ProductJson jProduct = productMap.get(product.getName());
- if (jProduct == null) {
- jProduct = new ProductJson(product.getCategory().toString(),
- product.getName(),
- toProductNames(product.getIncluded()), toProductNames(product.getAvailable()));
- productMap.put(product.getName(), jProduct);
+ final Plan[] plans = catalog.getCurrentPlans();
+ final Map<String, ProductJson> productMap = new HashMap<String, ProductJson>();
+ for (final Plan plan : plans) {
+ // Build the product associated with this plan
+ final Product product = plan.getProduct();
+ ProductJson productJson = productMap.get(product.getName());
+ if (productJson == null) {
+ productJson = new ProductJson(product.getCategory().toString(),
+ product.getName(),
+ toProductNames(product.getIncluded()),
+ toProductNames(product.getAvailable()));
+ productMap.put(product.getName(), productJson);
}
- int i = 0;
- PhaseJson[] phases = new PhaseJson[plan.getAllPhases().length];
- for (PlanPhase phase : plan.getAllPhases()) {
-
- Map<String, BigDecimal> prices = new HashMap<String, BigDecimal>();
+ // Build the phases associated with this plan
+ final List<PhaseJson> phases = new LinkedList<PhaseJson>();
+ for (final PlanPhase phase : plan.getAllPhases()) {
+ final List<PriceJson> prices = new LinkedList<PriceJson>();
if (phase.getRecurringPrice() != null) {
- for (Price cur : phase.getRecurringPrice().getPrices()) {
- prices.put(cur.getCurrency().toString(), cur.getValue());
+ for (final Price price : phase.getRecurringPrice().getPrices()) {
+ prices.add(new PriceJson(price));
}
}
- PhaseJson jPhase = new PhaseJson(phase.getPhaseType().toString(), prices);
- phases[i++] = jPhase;
+
+ final PhaseJson phaseJson = new PhaseJson(phase.getPhaseType().toString(), prices);
+ phases.add(phaseJson);
}
- PlanJson jPlan = new PlanJson(plan.getName(), phases);
- jProduct.addPlan(jPlan);
+
+ final PlanJson planJson = new PlanJson(plan.getName(), phases);
+ productJson.getPlans().add(planJson);
}
- products = productMap.values().toArray(new ProductJson[productMap.values().size()]);
+
+ products = ImmutableList.<ProductJson>copyOf(productMap.values());
}
- private Collection<String> toProductNames(Product[] in) {
- return Collections2.transform(Lists.newArrayList(in), new Function<Product, String>() {
- @Override
- public String apply(Product input) {
- return input.getName();
- }
- });
+ private List<String> toProductNames(final Product[] in) {
+ return Lists.transform(ImmutableList.<Product>copyOf(in),
+ new Function<Product, String>() {
+ @Override
+ public String apply(final Product input) {
+ return input.getName();
+ }
+ });
}
- @JsonCreator
- public CatalogJsonSimple(@JsonProperty("name") final String name,
- @JsonProperty("products") ProductJson[] products) {
- this.name = name;
- this.products = products;
+ public List<ProductJson> getProducts() {
+ return products;
}
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("CatalogJsonSimple{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", products=").append(products);
+ sb.append('}');
+ return sb.toString();
+ }
- public ProductJson[] getProducts() {
- return products;
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final CatalogJsonSimple that = (CatalogJsonSimple) o;
+
+ if (name != null ? !name.equals(that.name) : that.name != null) {
+ return false;
+ }
+ if (products != null ? !products.equals(that.products) : that.products != null) {
+ return false;
+ }
+
+ return true;
}
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (products != null ? products.hashCode() : 0);
+ return result;
+ }
- @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public static class ProductJson {
private final String type;
private final String name;
- private final String[] included;
- private final String[] available;
private final List<PlanJson> plans;
-
+ private final List<String> included;
+ private final List<String> available;
@JsonCreator
- public ProductJson(@JsonProperty("type") String type,
- @JsonProperty("name") String name,
- @JsonProperty("plans") List<PlanJson> plans,
- @JsonProperty("included") Collection<String> included,
- @JsonProperty("available") Collection<String> available) {
- super();
+ public ProductJson(@JsonProperty("type") final String type,
+ @JsonProperty("name") final String name,
+ @JsonProperty("plans") final List<PlanJson> plans,
+ @JsonProperty("included") final List<String> included,
+ @JsonProperty("available") final List<String> available) {
this.type = type;
this.name = name;
- this.included = included.toArray(new String[included.size()]);
- this.available = available.toArray(new String[available.size()]);
this.plans = plans;
+ this.included = included;
+ this.available = available;
}
- public ProductJson(String type, String name, Collection<String> included, Collection<String> available) {
- this(type, name, new LinkedList<CatalogJsonSimple.PlanJson>(), included, available);
- }
-
- public void addPlan(PlanJson plan) {
- plans.add(plan);
+ public ProductJson(final String type, final String name, final List<String> included, final List<String> available) {
+ this(type, name, new LinkedList<PlanJson>(), included, available);
}
public String getType() {
@@ -145,25 +175,75 @@ public class CatalogJsonSimple {
return plans;
}
- public String[] getIncluded() {
+ public List<String> getIncluded() {
return included;
}
- public String[] getAvailable() {
+ public List<String> getAvailable() {
return available;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("ProductJson{");
+ sb.append("type='").append(type).append('\'');
+ sb.append(", name='").append(name).append('\'');
+ sb.append(", plans=").append(plans);
+ sb.append(", included=").append(included);
+ sb.append(", available=").append(available);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final ProductJson that = (ProductJson) o;
+
+ if (available != null ? !available.equals(that.available) : that.available != null) {
+ return false;
+ }
+ if (included != null ? !included.equals(that.included) : that.included != null) {
+ return false;
+ }
+ if (name != null ? !name.equals(that.name) : that.name != null) {
+ return false;
+ }
+ if (plans != null ? !plans.equals(that.plans) : that.plans != null) {
+ return false;
+ }
+ if (type != null ? !type.equals(that.type) : that.type != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (plans != null ? plans.hashCode() : 0);
+ result = 31 * result + (included != null ? included.hashCode() : 0);
+ result = 31 * result + (available != null ? available.hashCode() : 0);
+ return result;
+ }
}
- @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public static class PlanJson {
private final String name;
- private final PhaseJson[] phases;
+ private final List<PhaseJson> phases;
@JsonCreator
- public PlanJson(@JsonProperty("name") String name,
- @JsonProperty("phases") PhaseJson[] phases) {
- super();
+ public PlanJson(@JsonProperty("name") final String name,
+ @JsonProperty("phases") final List<PhaseJson> phases) {
this.name = name;
this.phases = phases;
}
@@ -172,21 +252,56 @@ public class CatalogJsonSimple {
return name;
}
- public PhaseJson[] getPhases() {
+ public List<PhaseJson> getPhases() {
return phases;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PlanJson{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", phases=").append(phases);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PlanJson planJson = (PlanJson) o;
+
+ if (name != null ? !name.equals(planJson.name) : planJson.name != null) {
+ return false;
+ }
+ if (phases != null ? !phases.equals(planJson.phases) : planJson.phases != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (phases != null ? phases.hashCode() : 0);
+ return result;
+ }
}
- @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public static class PhaseJson {
private final String type;
- private final Map<String, BigDecimal> prices;
+ private final List<PriceJson> prices;
@JsonCreator
- public PhaseJson(@JsonProperty("type") String type,
- @JsonProperty("prices") Map<String, BigDecimal> prices) {
- super();
+ public PhaseJson(@JsonProperty("type") final String type,
+ @JsonProperty("prices") final List<PriceJson> prices) {
this.type = type;
this.prices = prices;
}
@@ -194,9 +309,107 @@ public class CatalogJsonSimple {
public String getType() {
return type;
}
-
- public Map<String, BigDecimal> getPrices() {
+ public List<PriceJson> getPrices() {
return prices;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PhaseJson{");
+ sb.append("type='").append(type).append('\'');
+ sb.append(", prices=").append(prices);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PhaseJson phaseJson = (PhaseJson) o;
+
+ if (prices != null ? !prices.equals(phaseJson.prices) : phaseJson.prices != null) {
+ return false;
+ }
+ if (type != null ? !type.equals(phaseJson.type) : phaseJson.type != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (prices != null ? prices.hashCode() : 0);
+ return result;
+ }
+ }
+
+ public static class PriceJson {
+
+ private final String currency;
+ private final BigDecimal value;
+
+ @JsonCreator
+ public PriceJson(@JsonProperty("currency") final String currency,
+ @JsonProperty("value") final BigDecimal value) {
+ this.currency = currency;
+ this.value = value;
+ }
+
+ public PriceJson(final Price price) throws CurrencyValueNull {
+ this(price.getCurrency().toString(), price.getValue());
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public BigDecimal getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PriceJson{");
+ sb.append("currency='").append(currency).append('\'');
+ sb.append(", value=").append(value);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PriceJson priceJson = (PriceJson) o;
+
+ if (currency != null ? !currency.equals(priceJson.currency) : priceJson.currency != null) {
+ return false;
+ }
+ if (value != null ? !value.equals(priceJson.value) : priceJson.value != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = currency != null ? currency.hashCode() : 0;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ return result;
+ }
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
index ebc4c8a..5321232 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
@@ -123,6 +123,11 @@ public class PaymentMethodJson {
public PaymentMethodPlugin getPluginDetail() {
return new PaymentMethodPlugin() {
@Override
+ public UUID getKbPaymentMethodId() {
+ return paymentMethodId == null ? null : UUID.fromString(paymentMethodId);
+ }
+
+ @Override
public boolean isDefaultPaymentMethod() {
// N/A
return false;
@@ -242,6 +247,58 @@ public class PaymentMethodJson {
return pluginInfo;
}
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PaymentMethodJson{");
+ sb.append("paymentMethodId='").append(paymentMethodId).append('\'');
+ sb.append(", accountId='").append(accountId).append('\'');
+ sb.append(", isDefault=").append(isDefault);
+ sb.append(", pluginName='").append(pluginName).append('\'');
+ sb.append(", pluginInfo=").append(pluginInfo);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PaymentMethodJson that = (PaymentMethodJson) o;
+
+ if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+ return false;
+ }
+ if (isDefault != null ? !isDefault.equals(that.isDefault) : that.isDefault != null) {
+ return false;
+ }
+ if (paymentMethodId != null ? !paymentMethodId.equals(that.paymentMethodId) : that.paymentMethodId != null) {
+ return false;
+ }
+ if (pluginInfo != null ? !pluginInfo.equals(that.pluginInfo) : that.pluginInfo != null) {
+ return false;
+ }
+ if (pluginName != null ? !pluginName.equals(that.pluginName) : that.pluginName != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = paymentMethodId != null ? paymentMethodId.hashCode() : 0;
+ result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+ result = 31 * result + (isDefault != null ? isDefault.hashCode() : 0);
+ result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
+ result = 31 * result + (pluginInfo != null ? pluginInfo.hashCode() : 0);
+ return result;
+ }
+
public static class PaymentMethodPluginDetailJson {
private final String externalPaymentId;
@@ -352,6 +409,108 @@ public class PaymentMethodJson {
public List<PaymentMethodProperties> getProperties() {
return properties;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PaymentMethodPluginDetailJson{");
+ sb.append("externalPaymentId='").append(externalPaymentId).append('\'');
+ sb.append(", isDefaultPaymentMethod=").append(isDefaultPaymentMethod);
+ sb.append(", type='").append(type).append('\'');
+ sb.append(", ccName='").append(ccName).append('\'');
+ sb.append(", ccType='").append(ccType).append('\'');
+ sb.append(", ccExpirationMonth='").append(ccExpirationMonth).append('\'');
+ sb.append(", ccExpirationYear='").append(ccExpirationYear).append('\'');
+ sb.append(", ccLast4='").append(ccLast4).append('\'');
+ sb.append(", address1='").append(address1).append('\'');
+ sb.append(", address2='").append(address2).append('\'');
+ sb.append(", city='").append(city).append('\'');
+ sb.append(", state='").append(state).append('\'');
+ sb.append(", zip='").append(zip).append('\'');
+ sb.append(", country='").append(country).append('\'');
+ sb.append(", properties=").append(properties);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PaymentMethodPluginDetailJson that = (PaymentMethodPluginDetailJson) o;
+
+ if (address1 != null ? !address1.equals(that.address1) : that.address1 != null) {
+ return false;
+ }
+ if (address2 != null ? !address2.equals(that.address2) : that.address2 != null) {
+ return false;
+ }
+ if (ccExpirationMonth != null ? !ccExpirationMonth.equals(that.ccExpirationMonth) : that.ccExpirationMonth != null) {
+ return false;
+ }
+ if (ccExpirationYear != null ? !ccExpirationYear.equals(that.ccExpirationYear) : that.ccExpirationYear != null) {
+ return false;
+ }
+ if (ccLast4 != null ? !ccLast4.equals(that.ccLast4) : that.ccLast4 != null) {
+ return false;
+ }
+ if (ccName != null ? !ccName.equals(that.ccName) : that.ccName != null) {
+ return false;
+ }
+ if (ccType != null ? !ccType.equals(that.ccType) : that.ccType != null) {
+ return false;
+ }
+ if (city != null ? !city.equals(that.city) : that.city != null) {
+ return false;
+ }
+ if (country != null ? !country.equals(that.country) : that.country != null) {
+ return false;
+ }
+ if (externalPaymentId != null ? !externalPaymentId.equals(that.externalPaymentId) : that.externalPaymentId != null) {
+ return false;
+ }
+ if (isDefaultPaymentMethod != null ? !isDefaultPaymentMethod.equals(that.isDefaultPaymentMethod) : that.isDefaultPaymentMethod != null) {
+ return false;
+ }
+ if (properties != null ? !properties.equals(that.properties) : that.properties != null) {
+ return false;
+ }
+ if (state != null ? !state.equals(that.state) : that.state != null) {
+ return false;
+ }
+ if (type != null ? !type.equals(that.type) : that.type != null) {
+ return false;
+ }
+ if (zip != null ? !zip.equals(that.zip) : that.zip != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = externalPaymentId != null ? externalPaymentId.hashCode() : 0;
+ result = 31 * result + (isDefaultPaymentMethod != null ? isDefaultPaymentMethod.hashCode() : 0);
+ result = 31 * result + (type != null ? type.hashCode() : 0);
+ result = 31 * result + (ccName != null ? ccName.hashCode() : 0);
+ result = 31 * result + (ccType != null ? ccType.hashCode() : 0);
+ result = 31 * result + (ccExpirationMonth != null ? ccExpirationMonth.hashCode() : 0);
+ result = 31 * result + (ccExpirationYear != null ? ccExpirationYear.hashCode() : 0);
+ result = 31 * result + (ccLast4 != null ? ccLast4.hashCode() : 0);
+ result = 31 * result + (address1 != null ? address1.hashCode() : 0);
+ result = 31 * result + (address2 != null ? address2.hashCode() : 0);
+ result = 31 * result + (city != null ? city.hashCode() : 0);
+ result = 31 * result + (state != null ? state.hashCode() : 0);
+ result = 31 * result + (zip != null ? zip.hashCode() : 0);
+ result = 31 * result + (country != null ? country.hashCode() : 0);
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ return result;
+ }
}
public static final class PaymentMethodProperties {
@@ -381,5 +540,47 @@ public class PaymentMethodJson {
public Boolean getIsUpdatable() {
return isUpdatable;
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PaymentMethodProperties{");
+ sb.append("key='").append(key).append('\'');
+ sb.append(", value='").append(value).append('\'');
+ sb.append(", isUpdatable=").append(isUpdatable);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PaymentMethodProperties that = (PaymentMethodProperties) o;
+
+ if (isUpdatable != null ? !isUpdatable.equals(that.isUpdatable) : that.isUpdatable != null) {
+ return false;
+ }
+ if (key != null ? !key.equals(that.key) : that.key != null) {
+ return false;
+ }
+ if (value != null ? !value.equals(that.value) : that.value != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = key != null ? key.hashCode() : 0;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ result = 31 * result + (isUpdatable != null ? isUpdatable.hashCode() : 0);
+ return result;
+ }
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PlanDetailJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PlanDetailJson.java
index 71bbd64..74ec110 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PlanDetailJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PlanDetailJson.java
@@ -16,9 +16,21 @@
package com.ning.billing.jaxrs.json;
+import java.math.BigDecimal;
+import java.util.List;
+
import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.InternationalPrice;
+import com.ning.billing.catalog.api.CurrencyValueNull;
import com.ning.billing.catalog.api.Listing;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.Price;
+import com.ning.billing.jaxrs.json.CatalogJsonSimple.PriceJson;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -29,14 +41,14 @@ public class PlanDetailJson {
final String planName;
final BillingPeriod billingPeriod;
final String priceListName;
- final InternationalPrice finalPhasePrice;
+ final List<PriceJson> finalPhasePrice;
@JsonCreator
public PlanDetailJson(@JsonProperty("product") final String productName,
@JsonProperty("plan") final String planName,
@JsonProperty("final_phase_billing_period") final BillingPeriod billingPeriod,
@JsonProperty("priceList") final String priceListName,
- @JsonProperty("final_phase_recurring_price") final InternationalPrice finalPhasePrice) {
+ @JsonProperty("final_phase_recurring_price") final List<PriceJson> finalPhasePrice) {
this.productName = productName;
this.planName = planName;
this.billingPeriod = billingPeriod;
@@ -45,8 +57,33 @@ public class PlanDetailJson {
}
public PlanDetailJson(final Listing listing) {
- this(listing.getPlan().getProduct().getName(), listing.getPlan().getName(), listing.getPlan().getBillingPeriod(),
- listing.getPriceList().getName(), listing.getPlan().getFinalPhase().getRecurringPrice());
+ final Plan plan = listing.getPlan();
+ if (plan == null) {
+ this.productName = null;
+ this.planName = null;
+ this.billingPeriod = null;
+ this.finalPhasePrice = ImmutableList.<PriceJson>of();
+ } else {
+ this.productName = plan.getProduct() == null ? null : plan.getProduct().getName();
+ this.planName = plan.getName();
+ this.billingPeriod = plan.getBillingPeriod();
+ if (plan.getFinalPhase() == null || plan.getFinalPhase().getRecurringPrice() == null || plan.getFinalPhase().getRecurringPrice().getPrices() == null) {
+ this.finalPhasePrice = ImmutableList.<PriceJson>of();
+ } else {
+ this.finalPhasePrice = Lists.transform(ImmutableList.<Price>copyOf(plan.getFinalPhase().getRecurringPrice().getPrices()),
+ new Function<Price, PriceJson>() {
+ @Override
+ public PriceJson apply(final Price price) {
+ try {
+ return new PriceJson(price);
+ } catch (CurrencyValueNull e) {
+ return new PriceJson(price.getCurrency().toString(), BigDecimal.ZERO);
+ }
+ }
+ });
+ }
+ }
+ this.priceListName = listing.getPriceList() == null ? null : listing.getPriceList().getName();
}
public String getProductName() {
@@ -65,11 +102,23 @@ public class PlanDetailJson {
return priceListName;
}
- public InternationalPrice getFinalPhasePrice() {
+ public List<PriceJson> getFinalPhasePrice() {
return finalPhasePrice;
}
@Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PlanDetailJson{");
+ sb.append("productName='").append(productName).append('\'');
+ sb.append(", planName='").append(planName).append('\'');
+ sb.append(", billingPeriod=").append(billingPeriod);
+ sb.append(", priceListName='").append(priceListName).append('\'');
+ sb.append(", finalPhasePrice=").append(finalPhasePrice);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java
index fd2abb3..2c82fa6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ExceptionMapperBase.java
@@ -73,6 +73,19 @@ public abstract class ExceptionMapperBase {
.build();
}
+ protected Response buildAuthorizationErrorResponse(final Exception e, final UriInfo uriInfo) {
+ // Log the full stacktrace
+ log.warn("Authorization error", e);
+ return buildAuthorizationErrorResponse(exceptionToString(e), uriInfo);
+ }
+
+ private Response buildAuthorizationErrorResponse(final String error, final UriInfo uriInfo) {
+ return Response.status(Status.UNAUTHORIZED) // TODO Forbidden?
+ .entity(error)
+ .type(MediaType.TEXT_PLAIN_TYPE)
+ .build();
+ }
+
protected Response buildInternalErrorResponse(final Exception e, final UriInfo uriInfo) {
// Log the full stacktrace
log.warn("Internal error", e);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ShiroExceptionMapper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ShiroExceptionMapper.java
new file mode 100644
index 0000000..4558b1c
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/mappers/ShiroExceptionMapper.java
@@ -0,0 +1,42 @@
+/*
+ * 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.jaxrs.mappers;
+
+import javax.inject.Singleton;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.shiro.ShiroException;
+
+@Singleton
+@Provider
+public class ShiroExceptionMapper extends ExceptionMapperBase implements ExceptionMapper<ShiroException> {
+
+ private final UriInfo uriInfo;
+
+ public ShiroExceptionMapper(@Context final UriInfo uriInfo) {
+ this.uriInfo = uriInfo;
+ }
+
+ @Override
+ public Response toResponse(final ShiroException exception) {
+ return buildAuthorizationErrorResponse(exception, uriInfo);
+ }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 09ca97f..eebe22b 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -96,6 +97,7 @@ import com.ning.billing.util.tag.ControlTagType;
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -147,7 +149,26 @@ public class AccountResource extends JaxRsResourceBase {
@javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
final TenantContext tenantContext = context.createContext(request);
final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), tenantContext);
- return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
+ final AccountJson accountJson = getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
+ return Response.status(Status.OK).entity(accountJson).build();
+ }
+
+ @GET
+ @Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response searchAccounts(@PathParam("searchKey") final String searchKey,
+ @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
+ @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+ final TenantContext tenantContext = context.createContext(request);
+ final List<Account> accounts = accountUserApi.searchAccounts(searchKey, tenantContext);
+ final List<AccountJson> accountsJson = ImmutableList.<AccountJson>copyOf(Collections2.transform(accounts, new Function<Account, AccountJson>() {
+ @Override
+ public AccountJson apply(final Account account) {
+ return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
+ }
+ }));
+ return Response.status(Status.OK).entity(accountsJson).build();
}
@@ -186,22 +207,22 @@ public class AccountResource extends JaxRsResourceBase {
@javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
final TenantContext tenantContext = context.createContext(request);
final Account account = accountUserApi.getAccountByKey(externalKey, tenantContext);
- return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
+ final AccountJson accountJson = getAccount(account, accountWithBalance, accountWithBalanceAndCBA, tenantContext);
+ return Response.status(Status.OK).entity(accountJson).build();
}
- private Response getAccount(final Account account, final Boolean accountWithBalance, final Boolean accountWithBalanceAndCBA, final TenantContext tenantContext) {
+ private AccountJson getAccount(final Account account, final Boolean accountWithBalance, final Boolean accountWithBalanceAndCBA, final TenantContext tenantContext) {
final AccountJson json;
if (accountWithBalanceAndCBA) {
final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId(), tenantContext);
final BigDecimal accountCBA = invoiceApi.getAccountCBA(account.getId(), tenantContext);
- json = new AccountJsonWithBalanceAndCBA(account, accountBalance, accountCBA);
+ return new AccountJsonWithBalanceAndCBA(account, accountBalance, accountCBA);
} else if (accountWithBalance) {
final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId(), tenantContext);
- json = new AccountJsonWithBalance(account, accountBalance);
+ return new AccountJsonWithBalance(account, accountBalance);
} else {
- json = new AccountJson(account);
+ return new AccountJson(account);
}
- return Response.status(Status.OK).entity(json).build();
}
@POST
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 0f18465..c3648e6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -153,6 +153,21 @@ public class InvoiceResource extends JaxRsResourceBase {
}
@GET
+ @Path("/{invoiceNumber:" + NUMBER_PATTERN + "}/")
+ @Produces(APPLICATION_JSON)
+ public Response getInvoiceByNumber(@PathParam("invoiceNumber") final Integer invoiceNumber,
+ @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+ final Invoice invoice = invoiceApi.getInvoiceByNumber(invoiceNumber, context.createContext(request));
+ if (invoice == null) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceNumber);
+ } else {
+ final InvoiceJsonSimple json = withItems ? new InvoiceJsonWithItems(invoice) : new InvoiceJsonSimple(invoice);
+ return Response.status(Status.OK).entity(json).build();
+ }
+ }
+
+ @GET
@Path("/{invoiceId:" + UUID_PATTERN + "}/html")
@Produces(TEXT_HTML)
public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId,
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index 87e1ed0..b4e021d 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -26,6 +26,13 @@ public interface JaxrsResource {
public static final String TIMELINE = "timeline";
public static final String REGISTER_NOTIFICATION_CALLBACK = "registerNotificationCallback";
+ public static final String SEARCH = "search";
+
+ /*
+ * Multi-Tenancy headers
+ */
+ public static String HDR_API_KEY = "X-Killbill-ApiKey";
+ public static String HDR_API_SECRET = "X-Killbill-ApiSecret";
/*
* Metadata Additional headers
@@ -39,6 +46,8 @@ public interface JaxrsResource {
*/
public static String STRING_PATTERN = "[\\w-]+";
public static String UUID_PATTERN = "\\w+-\\w+-\\w+-\\w+-\\w+";
+ public static String NUMBER_PATTERN = "[0-9]+";
+ public static String ANYTHING_PATTERN = ".*";
/*
* Query parameters
@@ -65,6 +74,7 @@ public interface JaxrsResource {
public static final String QUERY_TAGS = "tagList";
public static final String QUERY_CUSTOM_FIELDS = "customFieldList";
+ public static final String QUERY_PAYMENT_METHOD_PLUGIN_NAME = "pluginName";
public static final String QUERY_PAYMENT_METHOD_PLUGIN_INFO = "withPluginInfo";
public static final String QUERY_PAYMENT_METHOD_IS_DEFAULT = "isDefault";
@@ -86,6 +96,9 @@ public interface JaxrsResource {
public static final String BUNDLES = "bundles";
public static final String BUNDLES_PATH = PREFIX + "/" + BUNDLES;
+ public static final String SECURITY = "security";
+ public static final String SECURITY_PATH = PREFIX + "/" + SECURITY;
+
public static final String SUBSCRIPTIONS = "subscriptions";
public static final String SUBSCRIPTIONS_PATH = PREFIX + "/" + SUBSCRIPTIONS;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
index 5b32b46..1218a08 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
@@ -16,6 +16,9 @@
package com.ning.billing.jaxrs.resources;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
@@ -47,6 +50,9 @@ import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TenantContext;
+import com.google.common.base.Function;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -86,6 +92,40 @@ public class PaymentMethodResource extends JaxRsResourceBase {
return Response.status(Status.OK).entity(json).build();
}
+ @GET
+ @Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response searchPaymentMethods(@PathParam("searchKey") final String searchKey,
+ @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_NAME) final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ final TenantContext tenantContext = context.createContext(request);
+
+ // Search the plugin(s)
+ final List<PaymentMethod> paymentMethods;
+ if (Strings.isNullOrEmpty(pluginName)) {
+ paymentMethods = paymentApi.searchPaymentMethods(searchKey, tenantContext);
+ } else {
+ paymentMethods = paymentApi.searchPaymentMethods(searchKey, pluginName, tenantContext);
+ }
+
+ // Lookup the associated account(s)
+ final Map<UUID, Account> accounts = new HashMap<UUID, Account>();
+ for (final PaymentMethod paymentMethod : paymentMethods) {
+ if (accounts.get(paymentMethod.getAccountId()) == null) {
+ final Account account = accountUserApi.getAccountById(paymentMethod.getAccountId(), tenantContext);
+ accounts.put(paymentMethod.getAccountId(), account);
+ }
+ }
+
+ final List<PaymentMethodJson> json = Lists.transform(paymentMethods, new Function<PaymentMethod, PaymentMethodJson>() {
+ @Override
+ public PaymentMethodJson apply(final PaymentMethod paymentMethod) {
+ return PaymentMethodJson.toPaymentMethodJson(accounts.get(paymentMethod.getAccountId()), paymentMethod);
+ }
+ });
+ return Response.status(Status.OK).entity(json).build();
+ }
+
@DELETE
@Produces(APPLICATION_JSON)
@Path("/{paymentMethodId:" + UUID_PATTERN + "}")
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SecurityResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SecurityResource.java
new file mode 100644
index 0000000..133d632
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SecurityResource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.jaxrs.resources;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Singleton;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.clock.Clock;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.api.SecurityApi;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+@Singleton
+@Path(JaxrsResource.SECURITY_PATH)
+public class SecurityResource extends JaxRsResourceBase {
+
+ private final SecurityApi securityApi;
+
+ @Inject
+ public SecurityResource(final SecurityApi securityApi,
+ final JaxrsUriBuilder uriBuilder,
+ final TagUserApi tagUserApi,
+ final CustomFieldUserApi customFieldUserApi,
+ final AuditUserApi auditUserApi,
+ final AccountUserApi accountUserApi,
+ final Clock clock,
+ final Context context) {
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, clock, context);
+ this.securityApi = securityApi;
+ }
+
+ @GET
+ @Path("/permissions")
+ @Produces(APPLICATION_JSON)
+ public Response getCurrentUserPermissions(@javax.ws.rs.core.Context final HttpServletRequest request) {
+ final Set<Permission> permissions = securityApi.getCurrentUserPermissions(context.createContext(request));
+ final List<String> json = ImmutableList.<String>copyOf(Iterables.<Permission, String>transform(permissions, Functions.toStringFunction()));
+ return Response.status(Status.OK).entity(json).build();
+ }
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
index 18b95b7..6776382 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
@@ -67,6 +67,7 @@ public class Context {
}
private Tenant getTenantFromRequest(final ServletRequest request) {
+ // See com.ning.billing.server.security.TenantFilter
final Object tenantObject = request.getAttribute("killbill_tenant");
if (tenantObject == null) {
return null;
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestPlanDetailJason.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestPlanDetailJason.java
index 003b541..b273e71 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestPlanDetailJason.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestPlanDetailJason.java
@@ -84,6 +84,6 @@ public class TestPlanDetailJason extends JaxrsTestSuiteNoDB {
Assert.assertEquals(planDetailJason.getPlanName(), plan.getName());
Assert.assertEquals(planDetailJason.getBillingPeriod(), plan.getBillingPeriod());
Assert.assertEquals(planDetailJason.getPriceListName(), priceList.getName());
- Assert.assertEquals(planDetailJason.getFinalPhasePrice(), plan.getFinalPhase().getRecurringPrice());
+ Assert.assertEquals(planDetailJason.getFinalPhasePrice().size(), 0);
}
}
junction/killbill-junction.iml 43(+33 -10)
diff --git a/junction/killbill-junction.iml b/junction/killbill-junction.iml
index 85454cf..1cf83d7 100644
--- a/junction/killbill-junction.iml
+++ b/junction/killbill-junction.iml
@@ -12,19 +12,34 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-entitlement:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-entitlement:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -35,13 +50,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -49,14 +65,21 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" />
<orderEntry type="module" module-name="killbill-entitlement" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-entitlement:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-entitlement:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-account" scope="TEST" />
<orderEntry type="module" module-name="killbill-entitlement" scope="TEST" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
junction/pom.xml 7(+6 -1)
diff --git a/junction/pom.xml b/junction/pom.xml
index d97a14c..4d8e3a8 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-junction</artifactId>
@@ -101,6 +101,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
NEWS 16(+16 -0)
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..b8792f2
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,16 @@
+0.5.0
+ Initial implementation of RBAC
+ - default credentials: admin/password
+ Remove analytics plugin from defaultbundles package
+ Switch to killbill-commons for locker and db testing helper
+ Lower the default number of hash iterations for the apiSecret to 200,000 down from 500,000
+ - you can override it via -Dkillbill.server.multitenant.hash_iterations
+
+0.4.0
+ Search APIs
+ Log errors during lifecycle
+ Fix Catalog endpoints
+
+0.3.6
+ Add all ISO currencies to the catalog
+ jaxrs: return properly formatted JSON in case of exception
osgi/killbill-osgi.iml 30(+22 -8)
diff --git a/osgi/killbill-osgi.iml b/osgi/killbill-osgi.iml
index 1db52ef..29927c0 100644
--- a/osgi/killbill-osgi.iml
+++ b/osgi/killbill-osgi.iml
@@ -11,6 +11,13 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
@@ -20,11 +27,11 @@
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:1.2" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" />
@@ -39,14 +46,15 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -54,9 +62,15 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.framework:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.felix:org.osgi.core:1.0.1" level="project" />
osgi/pom.xml 2(+1 -1)
diff --git a/osgi/pom.xml b/osgi/pom.xml
index b3107d6..513b9b9 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi</artifactId>
diff --git a/osgi-bundles/bundles/jruby/killbill-osgi-bundles-jruby.iml b/osgi-bundles/bundles/jruby/killbill-osgi-bundles-jruby.iml
index 516cb6d..b979d01 100644
--- a/osgi-bundles/bundles/jruby/killbill-osgi-bundles-jruby.iml
+++ b/osgi-bundles/bundles/jruby/killbill-osgi-bundles-jruby.iml
@@ -9,17 +9,23 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:14.0.1" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.3.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:osgi-over-slf4j:1.7.5" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.jruby:jruby-complete:1.7.1" level="project" />
osgi-bundles/bundles/jruby/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/bundles/jruby/pom.xml b/osgi-bundles/bundles/jruby/pom.xml
index 188db3e..d304a37 100644
--- a/osgi-bundles/bundles/jruby/pom.xml
+++ b/osgi-bundles/bundles/jruby/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill-osgi-bundles</artifactId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-jruby</artifactId>
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 4b6a0fa..4868c1f 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
@@ -168,8 +168,13 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
}
@Override
- public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ public List<PaymentMethodPlugin> searchPaymentMethods(final String searchKey, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
+ @Override
+ public List<PaymentMethodPlugin> doCall(final Ruby runtime) throws PaymentPluginApiException {
+ return ((PaymentPluginApi) pluginInstance).searchPaymentMethods(searchKey, tenantContext);
+ }
+ });
}
@Override
@@ -183,6 +188,4 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
}
});
}
-
-
}
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/bundles/logger/pom.xml b/osgi-bundles/bundles/logger/pom.xml
index 041a2c3..ffad240 100644
--- a/osgi-bundles/bundles/logger/pom.xml
+++ b/osgi-bundles/bundles/logger/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-logger</artifactId>
osgi-bundles/bundles/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/bundles/pom.xml b/osgi-bundles/bundles/pom.xml
index 5003802..c671ce3 100644
--- a/osgi-bundles/bundles/pom.xml
+++ b/osgi-bundles/bundles/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-all-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles</artifactId>
diff --git a/osgi-bundles/bundles/webconsolebranding/pom.xml b/osgi-bundles/bundles/webconsolebranding/pom.xml
index 0d21c3b..01ae167 100644
--- a/osgi-bundles/bundles/webconsolebranding/pom.xml
+++ b/osgi-bundles/bundles/webconsolebranding/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-webconsolebranding</artifactId>
diff --git a/osgi-bundles/defaultbundles/killbill-osgi-bundles-defaultbundles.iml b/osgi-bundles/defaultbundles/killbill-osgi-bundles-defaultbundles.iml
index 0912444..fbcbe1a 100644
--- a/osgi-bundles/defaultbundles/killbill-osgi-bundles-defaultbundles.iml
+++ b/osgi-bundles/defaultbundles/killbill-osgi-bundles-defaultbundles.iml
@@ -9,18 +9,24 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.ning.billing:killbill-osgi-bundles-analytics:0.3.3" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-jruby" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.3.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:osgi-over-slf4j:1.7.5" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-concurrent:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="library" name="Maven: org.jruby:jruby-complete:1.7.1" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.core:4.3.1" level="project" />
osgi-bundles/defaultbundles/pom.xml 6(+1 -5)
diff --git a/osgi-bundles/defaultbundles/pom.xml b/osgi-bundles/defaultbundles/pom.xml
index ce105e5..3864299 100644
--- a/osgi-bundles/defaultbundles/pom.xml
+++ b/osgi-bundles/defaultbundles/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-all-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-defaultbundles</artifactId>
@@ -28,10 +28,6 @@
<dependencies>
<dependency>
<groupId>com.ning.billing</groupId>
- <artifactId>killbill-osgi-bundles-analytics</artifactId>
- </dependency>
- <dependency>
- <groupId>com.ning.billing</groupId>
<artifactId>killbill-osgi-bundles-jruby</artifactId>
</dependency>
<dependency>
diff --git a/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml b/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
index 37ec4d4..cafae6a 100644
--- a/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
+++ b/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
@@ -12,11 +12,14 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
- <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: joda-time:joda-time:2.0" level="project" />
- <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.3.1" level="project" />
osgi-bundles/libs/killbill/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/libs/killbill/pom.xml b/osgi-bundles/libs/killbill/pom.xml
index 2c4bdd3..fc619f1 100644
--- a/osgi-bundles/libs/killbill/pom.xml
+++ b/osgi-bundles/libs/killbill/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-lib-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-lib-killbill</artifactId>
osgi-bundles/libs/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/libs/pom.xml b/osgi-bundles/libs/pom.xml
index a28aa3c..5eee1fc 100644
--- a/osgi-bundles/libs/pom.xml
+++ b/osgi-bundles/libs/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-all-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-lib-bundles</artifactId>
osgi-bundles/libs/slf4j-osgi/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/libs/slf4j-osgi/pom.xml b/osgi-bundles/libs/slf4j-osgi/pom.xml
index 4592356..416d38c 100644
--- a/osgi-bundles/libs/slf4j-osgi/pom.xml
+++ b/osgi-bundles/libs/slf4j-osgi/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-lib-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-lib-slf4j-osgi</artifactId>
osgi-bundles/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/pom.xml b/osgi-bundles/pom.xml
index 6c32cbe..3fd20ee 100644
--- a/osgi-bundles/pom.xml
+++ b/osgi-bundles/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-all-bundles</artifactId>
diff --git a/osgi-bundles/tests/beatrix/killbill-osgi-bundles-test-beatrix.iml b/osgi-bundles/tests/beatrix/killbill-osgi-bundles-test-beatrix.iml
index 1e18463..fbc7ff4 100644
--- a/osgi-bundles/tests/beatrix/killbill-osgi-bundles-test-beatrix.iml
+++ b/osgi-bundles/tests/beatrix/killbill-osgi-bundles-test-beatrix.iml
@@ -12,15 +12,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.3.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:osgi-over-slf4j:1.7.5" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.core:4.3.1" level="project" />
osgi-bundles/tests/beatrix/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/tests/beatrix/pom.xml b/osgi-bundles/tests/beatrix/pom.xml
index a34398b..886e5e2 100644
--- a/osgi-bundles/tests/beatrix/pom.xml
+++ b/osgi-bundles/tests/beatrix/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-test-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-test-beatrix</artifactId>
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 365b7c4..600f5af 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
@@ -53,22 +53,27 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
public BigDecimal getAmount() {
return amount;
}
+
@Override
public DateTime getCreatedDate() {
return new DateTime();
}
+
@Override
public DateTime getEffectiveDate() {
return new DateTime();
}
+
@Override
public PaymentPluginStatus getStatus() {
return PaymentPluginStatus.PROCESSED;
}
+
@Override
public String getGatewayError() {
return null;
}
+
@Override
public String getGatewayErrorCode() {
return null;
@@ -120,17 +125,15 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
@Override
public List<PaymentMethodInfoPlugin> getPaymentMethods(final UUID kbAccountId, final boolean refreshFromGateway, final CallContext context) throws PaymentPluginApiException {
- return null;
+ return Collections.emptyList();
}
@Override
- public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ public List<PaymentMethodPlugin> searchPaymentMethods(final String searchKey, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return Collections.emptyList();
}
@Override
public void resetPaymentMethods(final UUID kbAccountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
}
-
-
}
diff --git a/osgi-bundles/tests/payment/killbill-osgi-bundles-test-payment.iml b/osgi-bundles/tests/payment/killbill-osgi-bundles-test-payment.iml
index e636e87..74a9686 100644
--- a/osgi-bundles/tests/payment/killbill-osgi-bundles-test-payment.iml
+++ b/osgi-bundles/tests/payment/killbill-osgi-bundles-test-payment.iml
@@ -11,7 +11,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-osgi-bundles-lib-killbill" />
@@ -19,7 +29,7 @@
<orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.3.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:osgi-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" production-on-test="" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.1.0" level="project" />
@@ -29,16 +39,17 @@
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -46,6 +57,16 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
<orderEntry type="library" name="Maven: org.osgi:org.osgi.core:4.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.3.1" level="project" />
osgi-bundles/tests/payment/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/tests/payment/pom.xml b/osgi-bundles/tests/payment/pom.xml
index 21ec519..41d43cd 100644
--- a/osgi-bundles/tests/payment/pom.xml
+++ b/osgi-bundles/tests/payment/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-test-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-bundles-test-payment</artifactId>
diff --git a/osgi-bundles/tests/payment/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java b/osgi-bundles/tests/payment/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
index 9c52b38..804e548 100644
--- a/osgi-bundles/tests/payment/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
+++ b/osgi-bundles/tests/payment/src/test/java/com/ning/billing/osgi/bundles/test/TestPaymentPluginApi.java
@@ -190,12 +190,12 @@ public class TestPaymentPluginApi implements PaymentPluginApiWithTestControl {
@Override
public List<PaymentMethodInfoPlugin> getPaymentMethods(final UUID kbAccountId, final boolean refreshFromGateway, final CallContext context) throws PaymentPluginApiException {
- return null;
+ return Collections.emptyList();
}
@Override
public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return Collections.emptyList();
}
@Override
osgi-bundles/tests/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/tests/pom.xml b/osgi-bundles/tests/pom.xml
index f605491..0a5fa9b 100644
--- a/osgi-bundles/tests/pom.xml
+++ b/osgi-bundles/tests/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-osgi-all-bundles</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-osgi-test-bundles</artifactId>
overdue/killbill-overdue.iml 42(+32 -10)
diff --git a/overdue/killbill-overdue.iml b/overdue/killbill-overdue.iml
index 9388421..af3075d 100644
--- a/overdue/killbill-overdue.iml
+++ b/overdue/killbill-overdue.iml
@@ -11,6 +11,20 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
@@ -22,13 +36,13 @@
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:1.2" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -39,13 +53,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -53,11 +68,18 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
overdue/pom.xml 8(+6 -2)
diff --git a/overdue/pom.xml b/overdue/pom.xml
index 3b501aa..b6b6095 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-overdue</artifactId>
@@ -91,9 +91,13 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
-
<dependency>
<groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index 21a489f..394a851 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -41,7 +41,7 @@ import com.ning.billing.entitlement.api.EntitlementApi;
import com.ning.billing.entitlement.api.EntitlementApiException;
import com.ning.billing.ovedue.notification.OverdueCheckPoster;
import com.ning.billing.overdue.OverdueApiException;
-import com.ning.billing.overdue.OverdueCancellationPolicicy;
+import com.ning.billing.overdue.OverdueCancellationPolicy;
import com.ning.billing.overdue.OverdueService;
import com.ning.billing.overdue.OverdueState;
import com.ning.billing.overdue.config.api.BillingState;
@@ -202,7 +202,7 @@ public class OverdueStateApplicator {
}
private void cancelSubscriptionsIfRequired(final Account account, final OverdueState nextOverdueState, final InternalCallContext context) throws OverdueException {
- if (nextOverdueState.getSubscriptionCancellationPolicy() == OverdueCancellationPolicicy.NONE) {
+ if (nextOverdueState.getSubscriptionCancellationPolicy() == OverdueCancellationPolicy.NONE) {
return;
}
try {
@@ -229,7 +229,8 @@ public class OverdueStateApplicator {
@SuppressWarnings("unchecked")
private void computeEntitlementsToCancel(final Account blockable, final List<Entitlement> result, final InternalTenantContext context) throws EntitlementApiException {
- result.addAll(entitlementApi.getAllEntitlementsForAccountId(blockable.getId(), context.toTenantContext()));
+ // STEPH_ENT fix internal API.
+ result.addAll(entitlementApi.getAllEntitlementsForAccountId(blockable.getId(), context.toTenantContext(null)));
}
private void sendEmailIfRequired(final BillingState billingState, final Account account,
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
index fb6b78b..b69b6f4 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
@@ -28,7 +28,7 @@ import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.TimeUnit;
import com.ning.billing.overdue.EmailNotification;
import com.ning.billing.overdue.OverdueApiException;
-import com.ning.billing.overdue.OverdueCancellationPolicicy;
+import com.ning.billing.overdue.OverdueCancellationPolicy;
import com.ning.billing.overdue.OverdueState;
import com.ning.billing.util.config.catalog.ValidatingConfig;
import com.ning.billing.util.config.catalog.ValidationError;
@@ -56,7 +56,7 @@ public class DefaultOverdueState extends ValidatingConfig<OverdueConfig> impleme
private Boolean disableEntitlement = false;
@XmlElement(required = false, name = "subscriptionCancellationPolicy")
- private OverdueCancellationPolicicy subscriptionCancellationPolicy = OverdueCancellationPolicicy.NONE;
+ private OverdueCancellationPolicy subscriptionCancellationPolicy = OverdueCancellationPolicy.NONE;
@XmlElement(required = false, name = "isClearState")
private Boolean isClearState = false;
@@ -95,7 +95,7 @@ public class DefaultOverdueState extends ValidatingConfig<OverdueConfig> impleme
}
@Override
- public OverdueCancellationPolicicy getSubscriptionCancellationPolicy() {
+ public OverdueCancellationPolicy getSubscriptionCancellationPolicy() {
return subscriptionCancellationPolicy;
}
@@ -132,7 +132,7 @@ public class DefaultOverdueState extends ValidatingConfig<OverdueConfig> impleme
return this;
}
- public DefaultOverdueState setSubscriptionCancellationPolicy(final OverdueCancellationPolicicy policy) {
+ public DefaultOverdueState setSubscriptionCancellationPolicy(final OverdueCancellationPolicy policy) {
this.subscriptionCancellationPolicy = policy;
return this;
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
index fcc4ea7..7b9fe94 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -71,7 +71,8 @@ public class OverdueWrapperFactory {
public OverdueWrapper createOverdueWrapperFor(final UUID id, final InternalTenantContext context) throws OverdueException {
try {
- Account account = accountUserApi.getAccountById(id, context.toTenantContext());
+ // STEPH_ENT
+ Account account = accountUserApi.getAccountById(id, context.toTenantContext(null));
return new OverdueWrapper(account, api, getOverdueStateSetBundle(),
clock, billingStateCalculator, overdueStateApplicator);
diff --git a/overdue/src/test/java/com/ning/billing/ovedue/notification/TestDefaultOverdueCheckPoster.java b/overdue/src/test/java/com/ning/billing/ovedue/notification/TestDefaultOverdueCheckPoster.java
index 3bf770f..e44cd73 100644
--- a/overdue/src/test/java/com/ning/billing/ovedue/notification/TestDefaultOverdueCheckPoster.java
+++ b/overdue/src/test/java/com/ning/billing/ovedue/notification/TestDefaultOverdueCheckPoster.java
@@ -52,7 +52,7 @@ public class TestDefaultOverdueCheckPoster extends OverdueTestSuiteWithEmbeddedD
@BeforeMethod(groups = "slow")
public void beforeMethod() throws Exception {
super.beforeMethod();
- entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(getDBI(), clock, cacheControllerDispatcher, nonEntityDao);
+ entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao);
overdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
payment/killbill-payment.iml 42(+30 -12)
diff --git a/payment/killbill-payment.iml b/payment/killbill-payment.iml
index d8fcd04..97fa80c 100644
--- a/payment/killbill-payment.iml
+++ b/payment/killbill-payment.iml
@@ -12,6 +12,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
@@ -25,14 +36,14 @@
<orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:1.2" level="project" />
<orderEntry type="module" module-name="killbill-account" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-account:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -41,13 +52,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -55,15 +67,21 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-invoice" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-invoice:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-junction" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-junction:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
payment/pom.xml 7(+6 -1)
diff --git a/payment/pom.xml b/payment/pom.xml
index 5aa5233..3309a7b 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-payment</artifactId>
@@ -104,6 +104,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 394c848..943f9d6 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -173,6 +173,16 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
+ public List<PaymentMethod> searchPaymentMethods(final String searchKey, final TenantContext context) {
+ return methodProcessor.searchPaymentMethods(searchKey, internalCallContextFactory.createInternalTenantContext(context));
+ }
+
+ @Override
+ public List<PaymentMethod> searchPaymentMethods(final String searchKey, final String pluginName, final TenantContext context) throws PaymentApiException {
+ return methodProcessor.searchPaymentMethods(searchKey, pluginName, internalCallContextFactory.createInternalTenantContext(context));
+ }
+
+ @Override
public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff, final CallContext context)
throws PaymentApiException {
methodProcessor.deletedPaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff, internalCallContextFactory.createInternalCallContext(account.getId(), context));
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
index 2318459..c72e410 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
@@ -18,6 +18,7 @@ package com.ning.billing.payment.core;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@@ -32,6 +33,7 @@ import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.bus.api.PersistentBus;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.osgi.api.OSGIServiceRegistration;
import com.ning.billing.payment.api.DefaultPaymentMethod;
import com.ning.billing.payment.api.PaymentApiException;
@@ -48,7 +50,7 @@ import com.ning.billing.payment.provider.DefaultPaymentMethodInfoPlugin;
import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
-import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcapi.tag.TagInternalApi;
@@ -71,10 +73,11 @@ public class PaymentMethodProcessor extends ProcessorBase {
final InvoiceInternalApi invoiceApi,
final PersistentBus eventBus,
final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
final TagInternalApi tagUserApi,
final GlobalLocker locker,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
- super(pluginRegistry, accountInternalApi, eventBus, paymentDao, tagUserApi, locker, executor, invoiceApi);
+ super(pluginRegistry, accountInternalApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
}
public Set<String> getAvailablePlugins() {
@@ -138,7 +141,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
if (withPluginInfo) {
try {
final PaymentPluginApi pluginApi = getPaymentPluginApi(paymentMethodModelDao.getPluginName());
- paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), context.toTenantContext());
+ paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), buildTenantContext(context));
} catch (PaymentPluginApiException e) {
log.warn("Error retrieving payment method " + paymentMethodModelDao.getId() + " from plugin " + paymentMethodModelDao.getPluginName(), e);
throw new PaymentApiException(ErrorCode.PAYMENT_GET_PAYMENT_METHODS, paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId());
@@ -150,6 +153,45 @@ public class PaymentMethodProcessor extends ProcessorBase {
return new DefaultPaymentMethod(paymentMethodModelDao, paymentMethodPlugin);
}
+ public List<PaymentMethod> searchPaymentMethods(final String searchKey, final InternalTenantContext internalTenantContext) {
+ final List<PaymentMethod> results = new LinkedList<PaymentMethod>();
+
+ // Search in all plugins
+ for (final String pluginName : getAvailablePlugins()) {
+ try {
+ results.addAll(searchPaymentMethods(searchKey, pluginName, internalTenantContext));
+ } catch (PaymentApiException e) {
+ log.warn("Error while searching plugin " + pluginName, e);
+ // Non-fatal, continue to search other plugins
+ }
+ }
+
+ return results;
+ }
+
+ public List<PaymentMethod> searchPaymentMethods(final String searchKey, final String pluginName, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+ final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
+ final List<PaymentMethodPlugin> paymentMethods;
+ try {
+ paymentMethods = pluginApi.searchPaymentMethods(searchKey, buildTenantContext(internalTenantContext));
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_SEARCH_PAYMENT_METHODS, pluginName, searchKey);
+ }
+
+ final List<PaymentMethod> results = new LinkedList<PaymentMethod>();
+ for (final PaymentMethodPlugin paymentMethodPlugin : paymentMethods) {
+ final PaymentMethodModelDao paymentMethodModelDao = paymentDao.getPaymentMethodIncludedDeleted(paymentMethodPlugin.getKbPaymentMethodId(), internalTenantContext);
+ if (paymentMethodModelDao == null) {
+ log.warn("Unable to find payment method id " + paymentMethodPlugin.getKbPaymentMethodId() + " present in plugin " + pluginName);
+ continue;
+ }
+
+ results.add(new DefaultPaymentMethod(paymentMethodModelDao, paymentMethodPlugin));
+ }
+
+ return results;
+ }
+
public PaymentMethod getExternalPaymentMethod(final Account account, final InternalTenantContext context) throws PaymentApiException {
final List<PaymentMethod> paymentMethods = getPaymentMethods(account, false, context);
for (final PaymentMethod paymentMethod : paymentMethods) {
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index 5d79fb9..81ea1b5 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -20,10 +20,12 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.inject.name.Named;
import com.ning.billing.ErrorCode;
+import com.ning.billing.ObjectType;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.bus.api.PersistentBus;
import com.ning.billing.clock.Clock;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.osgi.api.OSGIServiceRegistration;
@@ -47,10 +49,11 @@ import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRet
import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
import com.ning.billing.util.config.PaymentConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.events.BusInternalEvent;
import com.ning.billing.util.events.PaymentErrorInternalEvent;
-import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcapi.tag.TagInternalApi;
@@ -99,12 +102,13 @@ public class PaymentProcessor extends ProcessorBase {
final PluginFailureRetryServiceScheduler pluginFailureRetryService,
final AutoPayRetryServiceScheduler autoPayoffRetryService,
final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
final PersistentBus eventBus,
final Clock clock,
final GlobalLocker locker,
final PaymentConfig paymentConfig,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
- super(pluginRegistry, accountUserApi, eventBus, paymentDao, tagUserApi, locker, executor, invoiceApi);
+ super(pluginRegistry, accountUserApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
this.paymentMethodProcessor = paymentMethodProcessor;
this.failedPaymentRetryService = failedPaymentRetryService;
this.pluginFailureRetryService = pluginFailureRetryService;
@@ -125,7 +129,7 @@ public class PaymentProcessor extends ProcessorBase {
PaymentInfoPlugin pluginInfo = null;
if (plugin != null) {
try {
- pluginInfo = plugin.getPaymentInfo(model.getAccountId(), paymentId, context.toTenantContext());
+ pluginInfo = plugin.getPaymentInfo(model.getAccountId(), paymentId, buildTenantContext(context));
} catch (PaymentPluginApiException e) {
throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_GET_PAYMENT_INFO, paymentId, e.toString());
}
@@ -133,7 +137,6 @@ public class PaymentProcessor extends ProcessorBase {
return fromPaymentModelDao(model, pluginInfo, context);
}
-
public List<Payment> getInvoicePayments(final UUID invoiceId, final InternalTenantContext context) {
return getPayments(paymentDao.getPaymentsForInvoice(invoiceId, context), context);
}
diff --git a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
index 3f5ea77..2b67354 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
@@ -31,6 +31,9 @@ import com.ning.billing.ObjectType;
import com.ning.billing.account.api.Account;
import com.ning.billing.bus.api.PersistentBus;
import com.ning.billing.bus.api.PersistentBus.EventBusException;
+import com.ning.billing.commons.locker.GlobalLock;
+import com.ning.billing.commons.locker.GlobalLocker;
+import com.ning.billing.commons.locker.LockFailedException;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.osgi.api.OSGIServiceRegistration;
@@ -41,11 +44,10 @@ import com.ning.billing.payment.plugin.api.PaymentPluginApi;
import com.ning.billing.util.api.TagApiException;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.events.BusInternalEvent;
-import com.ning.billing.util.globallocker.GlobalLock;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.GlobalLocker.LockerType;
-import com.ning.billing.util.globallocker.LockFailedException;
+import com.ning.billing.util.globallocker.LockerType;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcapi.tag.TagInternalApi;
@@ -65,6 +67,7 @@ public abstract class ProcessorBase {
protected final GlobalLocker locker;
protected final ExecutorService executor;
protected final PaymentDao paymentDao;
+ protected final NonEntityDao nonEntityDao;
protected final TagInternalApi tagInternalApi;
private static final Logger log = LoggerFactory.getLogger(ProcessorBase.class);
@@ -74,6 +77,7 @@ public abstract class ProcessorBase {
final AccountInternalApi accountInternalApi,
final PersistentBus eventBus,
final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
final TagInternalApi tagInternalApi,
final GlobalLocker locker,
final ExecutorService executor, final InvoiceInternalApi invoiceApi) {
@@ -81,6 +85,7 @@ public abstract class ProcessorBase {
this.accountInternalApi = accountInternalApi;
this.eventBus = eventBus;
this.paymentDao = paymentDao;
+ this.nonEntityDao = nonEntityDao;
this.locker = locker;
this.executor = executor;
this.tagInternalApi = tagInternalApi;
@@ -150,6 +155,10 @@ public abstract class ProcessorBase {
return invoice;
}
+ protected TenantContext buildTenantContext(final InternalTenantContext context) {
+ return context.toTenantContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT));
+ }
+
public interface WithAccountLockCallback<T> {
public T doOperation() throws PaymentApiException;
@@ -181,7 +190,7 @@ public abstract class ProcessorBase {
throws PaymentApiException {
GlobalLock lock = null;
try {
- lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, accountExternalKey, NB_LOCK_TRY);
+ lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), accountExternalKey, NB_LOCK_TRY);
return callback.doOperation();
} catch (LockFailedException e) {
final String format = String.format("Failed to lock account %s", accountExternalKey);
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index 2a47887..413a9c5 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -36,6 +36,7 @@ import com.ning.billing.ObjectType;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.bus.api.PersistentBus;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.osgi.api.OSGIServiceRegistration;
@@ -55,7 +56,7 @@ import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcapi.tag.TagInternalApi;
@@ -83,9 +84,10 @@ public class RefundProcessor extends ProcessorBase {
final InternalCallContextFactory internalCallContextFactory,
final TagInternalApi tagUserApi,
final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
final GlobalLocker locker,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
- super(pluginRegistry, accountApi, eventBus, paymentDao, tagUserApi, locker, executor, invoiceApi);
+ super(pluginRegistry, accountApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
this.internalCallContextFactory = internalCallContextFactory;
}
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
index 89fc2d1..d431522 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
@@ -24,24 +24,33 @@ import com.ning.billing.payment.api.PaymentMethodPlugin;
public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
+ private final UUID kbPaymentMethodId;
private final String externalId;
private final boolean isDefault;
private List<PaymentMethodKVInfo> props;
- public DefaultNoOpPaymentMethodPlugin(final PaymentMethodPlugin src) {
+ public DefaultNoOpPaymentMethodPlugin(final UUID kbPaymentMethodId, final PaymentMethodPlugin src) {
+ this.kbPaymentMethodId = kbPaymentMethodId;
this.externalId = UUID.randomUUID().toString();
this.isDefault = src.isDefaultPaymentMethod();
this.props = src.getProperties();
}
- public DefaultNoOpPaymentMethodPlugin(final String externalId, final boolean isDefault,
+ public DefaultNoOpPaymentMethodPlugin(final String externalId,
+ final boolean isDefault,
final List<PaymentMethodKVInfo> props) {
+ this.kbPaymentMethodId = null;
this.externalId = externalId;
this.isDefault = isDefault;
this.props = props;
}
@Override
+ public UUID getKbPaymentMethodId() {
+ return kbPaymentMethodId;
+ }
+
+ @Override
public String getExternalPaymentMethodId() {
return externalId;
}
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
index 7d23d9e..449324a 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
@@ -37,7 +37,9 @@ import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TenantContext;
import com.ning.billing.clock.Clock;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
@@ -108,7 +110,7 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
@Override
public void addPaymentMethod(final UUID kbAccountId, final UUID kbPaymentMethodId, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault, final CallContext context) throws PaymentPluginApiException {
- final PaymentMethodPlugin realWithID = new DefaultNoOpPaymentMethodPlugin(paymentMethodProps);
+ final PaymentMethodPlugin realWithID = new DefaultNoOpPaymentMethodPlugin(kbPaymentMethodId, paymentMethodProps);
List<PaymentMethodPlugin> pms = paymentMethods.get(kbPaymentMethodId.toString());
if (pms == null) {
pms = new LinkedList<PaymentMethodPlugin>();
@@ -155,8 +157,19 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
- public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ public List<PaymentMethodPlugin> searchPaymentMethods(final String searchKey, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return ImmutableList.<PaymentMethodPlugin>copyOf(Iterables.<PaymentMethodPlugin>filter(Iterables.<PaymentMethodPlugin>concat(paymentMethods.values()), new Predicate<PaymentMethodPlugin>() {
+ @Override
+ public boolean apply(final PaymentMethodPlugin input) {
+ return (input.getAddress1() != null && input.getAddress1().contains(searchKey)) ||
+ (input.getAddress2() != null && input.getAddress2().contains(searchKey)) ||
+ (input.getCCLast4() != null && input.getCCLast4().contains(searchKey)) ||
+ (input.getCCName() != null && input.getCCName().contains(searchKey)) ||
+ (input.getCity() != null && input.getCity().contains(searchKey)) ||
+ (input.getState() != null && input.getState().contains(searchKey)) ||
+ (input.getCountry() != null && input.getCountry().contains(searchKey));
+ }
+ }));
}
@Override
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/ExternalPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/ExternalPaymentProviderPlugin.java
index c8ed58a..b1b6915 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/ExternalPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/ExternalPaymentProviderPlugin.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.UUID;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.clock.Clock;
import com.ning.billing.payment.api.PaymentMethodKVInfo;
import com.ning.billing.payment.api.PaymentMethodPlugin;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
@@ -33,8 +34,8 @@ import com.ning.billing.payment.plugin.api.RefundInfoPlugin;
import com.ning.billing.payment.plugin.api.RefundPluginStatus;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TenantContext;
-import com.ning.billing.clock.Clock;
+import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
/**
@@ -84,7 +85,7 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
@Override
public PaymentMethodPlugin getPaymentMethodDetail(final UUID kbAccountId, final UUID kbPaymentMethodId, final TenantContext context) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentMethodPlugin("unknow", false, Collections.<PaymentMethodKVInfo>emptyList());
+ return new DefaultNoOpPaymentMethodPlugin("unknown", false, Collections.<PaymentMethodKVInfo>emptyList());
}
@Override
@@ -93,12 +94,12 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
@Override
public List<PaymentMethodInfoPlugin> getPaymentMethods(final UUID kbAccountId, final boolean refreshFromGateway, final CallContext context) throws PaymentPluginApiException {
- return null;
+ return ImmutableList.<PaymentMethodInfoPlugin>of();
}
@Override
public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return ImmutableList.<PaymentMethodPlugin>of();
}
@Override
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPlugin.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPlugin.java
index d0ae14b..76d28e1 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPlugin.java
@@ -17,20 +17,28 @@
package com.ning.billing.payment.api;
import java.util.List;
+import java.util.UUID;
public class TestPaymentMethodPlugin extends TestPaymentMethodPluginBase implements PaymentMethodPlugin {
+ private final UUID kbPaymentMethodId;
private final String externalPaymentMethodId;
private final boolean isDefaultPaymentMethod;
private final List<PaymentMethodKVInfo> properties;
- public TestPaymentMethodPlugin(final PaymentMethodPlugin src, final String externalPaymentId) {
+ public TestPaymentMethodPlugin(final UUID kbPaymentMethodId, final PaymentMethodPlugin src, final String externalPaymentId) {
+ this.kbPaymentMethodId = kbPaymentMethodId;
this.externalPaymentMethodId = externalPaymentId;
this.isDefaultPaymentMethod = src.isDefaultPaymentMethod();
this.properties = src.getProperties();
}
@Override
+ public UUID getKbPaymentMethodId() {
+ return kbPaymentMethodId;
+ }
+
+ @Override
public String getExternalPaymentMethodId() {
return externalPaymentMethodId;
}
@@ -44,5 +52,4 @@ public class TestPaymentMethodPlugin extends TestPaymentMethodPluginBase impleme
public List<PaymentMethodKVInfo> getProperties() {
return properties;
}
-
}
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
index 2da363f..3768b18 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -25,20 +25,22 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.payment.api.TestPaymentMethodPlugin;
+import com.ning.billing.clock.Clock;
import com.ning.billing.payment.api.PaymentMethodPlugin;
+import com.ning.billing.payment.api.TestPaymentMethodPlugin;
import com.ning.billing.payment.plugin.api.NoOpPaymentPluginApi;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
-import com.ning.billing.payment.plugin.api.PaymentPluginStatus;
import com.ning.billing.payment.plugin.api.PaymentMethodInfoPlugin;
import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
+import com.ning.billing.payment.plugin.api.PaymentPluginStatus;
import com.ning.billing.payment.plugin.api.RefundInfoPlugin;
import com.ning.billing.payment.plugin.api.RefundPluginStatus;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TenantContext;
-import com.ning.billing.clock.Clock;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
@@ -116,7 +118,7 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
@Override
public void addPaymentMethod(final UUID kbAccountId, final UUID kbPaymentMethodId, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault, final CallContext context) throws PaymentPluginApiException {
// externalPaymentMethodId is set to a random value
- final PaymentMethodPlugin realWithID = new TestPaymentMethodPlugin(paymentMethodProps, UUID.randomUUID().toString());
+ final PaymentMethodPlugin realWithID = new TestPaymentMethodPlugin(kbPaymentMethodId, paymentMethodProps, UUID.randomUUID().toString());
paymentMethods.put(kbPaymentMethodId.toString(), realWithID);
final PaymentMethodInfoPlugin realInfoWithID = new DefaultPaymentMethodInfoPlugin(kbAccountId, kbPaymentMethodId, setDefault, UUID.randomUUID().toString());
@@ -144,8 +146,19 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
- public List<PaymentMethodPlugin> searchPaymentMethods(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ public List<PaymentMethodPlugin> searchPaymentMethods(final String searchKey, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return ImmutableList.<PaymentMethodPlugin>copyOf(Iterables.<PaymentMethodPlugin>filter(paymentMethods.values(), new Predicate<PaymentMethodPlugin>() {
+ @Override
+ public boolean apply(final PaymentMethodPlugin input) {
+ return (input.getAddress1() != null && input.getAddress1().contains(searchKey)) ||
+ (input.getAddress2() != null && input.getAddress2().contains(searchKey)) ||
+ (input.getCCLast4() != null && input.getCCLast4().contains(searchKey)) ||
+ (input.getCCName() != null && input.getCCName().contains(searchKey)) ||
+ (input.getCity() != null && input.getCity().contains(searchKey)) ||
+ (input.getState() != null && input.getState().contains(searchKey)) ||
+ (input.getCountry() != null && input.getCountry().contains(searchKey));
+ }
+ }));
}
@Override
pom.xml 4(+2 -2)
diff --git a/pom.xml b/pom.xml
index 3b542b3..ffc3084 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,10 +19,10 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.5-SNAPSHOT</version>
+ <version>0.4.0-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>killbill</name>
<description>Library for managing recurring subscriptions and the associated billing</description>
README.md 63(+1 -62)
diff --git a/README.md b/README.md
index e965ce1..442e402 100644
--- a/README.md
+++ b/README.md
@@ -1,65 +1,4 @@
[](https://travis-ci.org/killbill/killbill)
Killbill is an open source subscription management/billing system.
-You can find the documentation [here](http://ning.github.com/killbill/).
-
-Setting up your own tenant
---------------------------
-
-Killbill supports multiple tenants running on the same server. Each tenant needs to identify itself when using the /1.0
-API via HTTP Basic authentication.
-
-For example, trying to access all tag definitions without being authenticated would throw a 400 error:
-
- ~> curl -v http://127.0.0.1:8080/1.0/kb/tagDefinitions
- * About to connect() to 127.0.0.1 port 8080 (#0)
- * Trying 127.0.0.1... connected
- * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
- > GET /1.0/kb/tagDefinitions HTTP/1.1
- > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
- > Host: 127.0.0.1:8080
- > Accept: */*
- >
- < HTTP/1.1 401 Unauthorized
- < WWW-Authenticate: BASIC realm="application"
- < Content-Length: 0
- < Server: Jetty(8.1.2.v20120308)
- <
- * Connection #0 to host 127.0.0.1 left intact
- * Closing connection #0
-
-
-Before you can use the /1.0 API, you need to create your own tenant. To do so, post your username (`apiKey`) and password
-(`apiSecret`) to the `/1.0/kb/tenants` endpoint (the header `X-Killbill-CreatedBy` is used for auditing purposes).
-For example, to create the a tenant with the credentials bob/lazar:
-
- ~> curl -v -XPOST \
- -H'Content-Type: application/json' \
- -H'X-Killbill-CreatedBy: admin' \
- -d'{"apiKey": "bob", "apiSecret": "lazar"}' \
- http://127.0.0.1:8080/1.0/kb/tenants
- * About to connect() to 127.0.0.1 port 8080 (#0)
- * Trying 127.0.0.1... connected
- * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
- > POST /1.0/kb/tenants HTTP/1.1
- > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
- > Host: 127.0.0.1:8080
- > Accept: */*
- > Content-Type: application/json
- > X-Killbill-CreatedBy: admin
- > Content-Length: 39
- >
- < HTTP/1.1 201 Created
- < Location: http://127.0.0.1:8080/1.0/kb/tenants/f07bc7d5-00e8-48bd-8b43-ef8537219171
- < Content-Type: application/json
- < Transfer-Encoding: chunked
- < Server: Jetty(8.1.2.v20120308)
- <
- * Connection #0 to host 127.0.0.1 left intact
- * Closing connection #0
- {"uri":"/1.0/kb/tenants/f07bc7d5-00e8-48bd-8b43-ef8537219171"}
-
-
-You can now access the API using basic auth, e.g.:
-
- ~> curl -v http://127.0.0.1:8080/1.0/kb/tagDefinitions -ubob:lazar
+You can find the documentation [here](http://kill-bill.org).
server/killbill-server.iml 49(+35 -14)
diff --git a/server/killbill-server.iml b/server/killbill-server.iml
index 57c99eb..6d9a7bc 100644
--- a/server/killbill-server.iml
+++ b/server/killbill-server.iml
@@ -12,6 +12,23 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-beatrix:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-beatrix:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: ch.qos.logback:logback-classic:1.0.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: ch.qos.logback:logback-core:1.0.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
@@ -28,10 +45,10 @@
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="module" module-name="killbill-util" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.1.0" level="project" />
@@ -39,13 +56,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -53,6 +71,11 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-beatrix" />
<orderEntry type="module" module-name="killbill-catalog" />
<orderEntry type="module" module-name="killbill-entitlement" />
@@ -62,12 +85,10 @@
<orderEntry type="module" module-name="killbill-payment" />
<orderEntry type="module" module-name="killbill-subscription" />
<orderEntry type="module" module-name="killbill-tenant" />
- <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.1" level="project" />
- <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
<orderEntry type="module" module-name="killbill-usage" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.1" level="project" />
<orderEntry type="module" module-name="killbill-beatrix" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-beatrix:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-beatrix:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-jaxrs" />
<orderEntry type="library" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
<orderEntry type="module" module-name="killbill-osgi" />
@@ -79,10 +100,11 @@
<orderEntry type="library" name="Maven: org.apache.felix:org.osgi.core:1.0.1" level="project" />
<orderEntry type="module" module-name="killbill-overdue" />
<orderEntry type="module" module-name="killbill-payment" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-payment:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" name="Maven: com.ning.jetty:ning-service-skeleton-base:0.1.7" level="project" />
<orderEntry type="library" name="Maven: com.ning:metrics.eventtracker-smile:4.1.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.0.1" level="project" />
@@ -104,7 +126,6 @@
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.0.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.0.0" level="project" />
- <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.5" level="project" />
<orderEntry type="library" name="Maven: com.ning.jetty:ning-service-skeleton-eventtracker:0.1.7" level="project" />
<orderEntry type="library" name="Maven: com.ning.jetty:ning-service-skeleton-utils:0.1.7" level="project" />
@@ -119,7 +140,7 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
- <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.2.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty:jetty-deploy:8.1.11.v20130520" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty:jetty-webapp:8.1.11.v20130520" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.eclipse.jetty:jetty-xml:8.1.11.v20130520" level="project" />
server/pom.xml 7(+6 -1)
diff --git a/server/pom.xml b/server/pom.xml
index dda7b64..931c4e6 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-server</artifactId>
@@ -153,6 +153,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index 6337238..4ac7aa2 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -19,6 +19,7 @@ package com.ning.billing.server.listeners;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
+import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.slf4j.Logger;
@@ -53,8 +54,8 @@ public class KillbillGuiceListener extends SetupServer {
private BusService killbillBusService;
private KillbillEventHandler killbilleventHandler;
- protected Module getModule() {
- return new KillbillServerModule();
+ protected Module getModule(final ServletContext servletContext) {
+ return new KillbillServerModule(servletContext);
}
private void registerMBeansForCache(final CacheManager cacheManager) {
@@ -66,7 +67,7 @@ public class KillbillGuiceListener extends SetupServer {
@Override
public void contextInitialized(final ServletContextEvent event) {
- final boolean multitenant = Boolean.parseBoolean(System.getProperty(KILLBILL_MULTITENANT_PROPERTY, "false"));
+ final boolean multitenant = Boolean.parseBoolean(System.getProperty(KILLBILL_MULTITENANT_PROPERTY, "true"));
final ServerModuleBuilder builder = new ServerModuleBuilder()
.addConfig(KillbillServerConfig.class)
@@ -74,7 +75,7 @@ public class KillbillGuiceListener extends SetupServer {
.addJMXExport(KillbillHealthcheck.class)
.addJMXExport(NotificationQueueService.class)
.addJMXExport(PersistentBus.class)
- .addModule(getModule())
+ .addModule(getModule(event.getServletContext()))
// Don't filter all requests through Jersey, only the JAX-RS APIs (otherwise,
// things like static resources, favicon, etc. are 404'ed)
.setJerseyUriPattern("(" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*")
diff --git a/server/src/main/java/com/ning/billing/server/modules/DataSourceProvider.java b/server/src/main/java/com/ning/billing/server/modules/DataSourceProvider.java
new file mode 100644
index 0000000..9e9547a
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/modules/DataSourceProvider.java
@@ -0,0 +1,126 @@
+/*
+ * 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.server.modules;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.sql.DataSource;
+
+import org.skife.config.TimeSpan;
+
+import com.ning.jetty.jdbi.config.DaoConfig;
+
+import com.jolbox.bonecp.BoneCPConfig;
+import com.jolbox.bonecp.BoneCPDataSource;
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+
+public class DataSourceProvider implements Provider<DataSource> {
+
+ private final DaoConfig config;
+
+ @Inject
+ public DataSourceProvider(final DaoConfig config) {
+ this.config = config;
+ }
+
+ @Override
+ public DataSource get() {
+ return getDataSource();
+ }
+
+ private DataSource getDataSource() {
+ final DataSource ds;
+
+ // TODO PIERRE DaoConfig is in the skeleton
+ final String dataSource = System.getProperty("com.ning.jetty.jdbi.datasource", "c3p0");
+ if (dataSource.equals("c3p0")) {
+ ds = getC3P0DataSource();
+ } else if (dataSource.equals("bonecp")) {
+ ds = getBoneCPDatSource();
+ } else {
+ throw new IllegalArgumentException("DataSource " + dataSource + " unsupported");
+ }
+
+ return ds;
+ }
+
+ private DataSource getBoneCPDatSource() {
+ final BoneCPConfig dbConfig = new BoneCPConfig();
+ dbConfig.setJdbcUrl(config.getJdbcUrl());
+ dbConfig.setUsername(config.getUsername());
+ dbConfig.setPassword(config.getPassword());
+ dbConfig.setMinConnectionsPerPartition(config.getMinIdle());
+ dbConfig.setMaxConnectionsPerPartition(config.getMaxActive());
+ dbConfig.setConnectionTimeout(config.getConnectionTimeout().getPeriod(), config.getConnectionTimeout().getUnit());
+ dbConfig.setIdleMaxAge(config.getIdleMaxAge().getPeriod(), config.getIdleMaxAge().getUnit());
+ dbConfig.setMaxConnectionAge(config.getMaxConnectionAge().getPeriod(), config.getMaxConnectionAge().getUnit());
+ dbConfig.setIdleConnectionTestPeriod(config.getIdleConnectionTestPeriod().getPeriod(), config.getIdleConnectionTestPeriod().getUnit());
+ dbConfig.setPartitionCount(1);
+ dbConfig.setDisableJMX(false);
+
+ return new BoneCPDataSource(dbConfig);
+ }
+
+ private DataSource getC3P0DataSource() {
+ final ComboPooledDataSource cpds = new ComboPooledDataSource();
+ cpds.setJdbcUrl(config.getJdbcUrl());
+ cpds.setUser(config.getUsername());
+ cpds.setPassword(config.getPassword());
+ // http://www.mchange.com/projects/c3p0/#minPoolSize
+ // Minimum number of Connections a pool will maintain at any given time.
+ cpds.setMinPoolSize(config.getMinIdle());
+ // http://www.mchange.com/projects/c3p0/#maxPoolSize
+ // Maximum number of Connections a pool will maintain at any given time.
+ cpds.setMaxPoolSize(config.getMaxActive());
+ // http://www.mchange.com/projects/c3p0/#checkoutTimeout
+ // The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or
+ // acquired when the pool is exhausted. Zero means wait indefinitely. Setting any positive value will cause the getConnection()
+ // call to time-out and break with an SQLException after the specified number of milliseconds.
+ cpds.setCheckoutTimeout(toMilliSeconds(config.getConnectionTimeout()));
+ // http://www.mchange.com/projects/c3p0/#maxIdleTime
+ // Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire.
+ cpds.setMaxIdleTime(toSeconds(config.getIdleMaxAge()));
+ // http://www.mchange.com/projects/c3p0/#maxConnectionAge
+ // Seconds, effectively a time to live. A Connection older than maxConnectionAge will be destroyed and purged from the pool.
+ // This differs from maxIdleTime in that it refers to absolute age. Even a Connection which has not been much idle will be purged
+ // from the pool if it exceeds maxConnectionAge. Zero means no maximum absolute age is enforced.
+ cpds.setMaxConnectionAge(toSeconds(config.getMaxConnectionAge()));
+ // http://www.mchange.com/projects/c3p0/#idleConnectionTestPeriod
+ // If this is a number greater than 0, c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds.
+ cpds.setIdleConnectionTestPeriod(toSeconds(config.getIdleConnectionTestPeriod()));
+
+ return cpds;
+ }
+
+ private int toSeconds(final TimeSpan timeSpan) {
+ return toSeconds(timeSpan.getPeriod(), timeSpan.getUnit());
+ }
+
+ private int toSeconds(final long period, final TimeUnit timeUnit) {
+ return (int) TimeUnit.SECONDS.convert(period, timeUnit);
+ }
+
+ private int toMilliSeconds(final TimeSpan timeSpan) {
+ return toMilliSeconds(timeSpan.getPeriod(), timeSpan.getUnit());
+ }
+
+ private int toMilliSeconds(final long period, final TimeUnit timeUnit) {
+ return (int) TimeUnit.MILLISECONDS.convert(period, timeUnit);
+ }
+}
diff --git a/server/src/main/java/com/ning/billing/server/modules/DBIProvider.java b/server/src/main/java/com/ning/billing/server/modules/DBIProvider.java
index 66c5cdf..81d747f 100644
--- a/server/src/main/java/com/ning/billing/server/modules/DBIProvider.java
+++ b/server/src/main/java/com/ning/billing/server/modules/DBIProvider.java
@@ -20,7 +20,6 @@ import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
-import org.skife.config.TimeSpan;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.TimingCollector;
import org.skife.jdbi.v2.tweak.SQLLog;
@@ -38,9 +37,6 @@ import com.ning.jetty.jdbi.config.DaoConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
-import com.jolbox.bonecp.BoneCPConfig;
-import com.jolbox.bonecp.BoneCPDataSource;
-import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.yammer.metrics.core.MetricsRegistry;
import com.yammer.metrics.jdbi.InstrumentedTimingCollector;
import com.yammer.metrics.jdbi.strategies.BasicSqlNameStrategy;
@@ -49,12 +45,14 @@ public class DBIProvider implements Provider<DBI> {
private static final Logger logger = LoggerFactory.getLogger(DBIProvider.class);
+ private final DataSource ds;
private final MetricsRegistry metricsRegistry;
private final DaoConfig config;
private SQLLog sqlLog;
@Inject
- public DBIProvider(final MetricsRegistry metricsRegistry, final DaoConfig config) {
+ public DBIProvider(final DataSource ds, final MetricsRegistry metricsRegistry, final DaoConfig config) {
+ this.ds = ds;
this.metricsRegistry = metricsRegistry;
this.config = config;
}
@@ -66,8 +64,6 @@ public class DBIProvider implements Provider<DBI> {
@Override
public DBI get() {
- final DataSource ds = getDataSource();
-
final DBI dbi = new DBI(ds);
dbi.registerArgumentFactory(new UUIDArgumentFactory());
dbi.registerArgumentFactory(new DateTimeZoneArgumentFactory());
@@ -95,84 +91,4 @@ public class DBIProvider implements Provider<DBI> {
return dbi;
}
-
- private DataSource getDataSource() {
- final DataSource ds;
-
- // TODO PIERRE DaoConfig is in the skeleton
- final String dataSource = System.getProperty("com.ning.jetty.jdbi.datasource", "c3p0");
- if (dataSource.equals("c3p0")) {
- ds = getC3P0DataSource();
- } else if (dataSource.equals("bonecp")) {
- ds = getBoneCPDatSource();
- } else {
- throw new IllegalArgumentException("DataSource " + dataSource + " unsupported");
- }
-
- return ds;
- }
-
- private DataSource getBoneCPDatSource() {
- final BoneCPConfig dbConfig = new BoneCPConfig();
- dbConfig.setJdbcUrl(config.getJdbcUrl());
- dbConfig.setUsername(config.getUsername());
- dbConfig.setPassword(config.getPassword());
- dbConfig.setMinConnectionsPerPartition(config.getMinIdle());
- dbConfig.setMaxConnectionsPerPartition(config.getMaxActive());
- dbConfig.setConnectionTimeout(config.getConnectionTimeout().getPeriod(), config.getConnectionTimeout().getUnit());
- dbConfig.setIdleMaxAge(config.getIdleMaxAge().getPeriod(), config.getIdleMaxAge().getUnit());
- dbConfig.setMaxConnectionAge(config.getMaxConnectionAge().getPeriod(), config.getMaxConnectionAge().getUnit());
- dbConfig.setIdleConnectionTestPeriod(config.getIdleConnectionTestPeriod().getPeriod(), config.getIdleConnectionTestPeriod().getUnit());
- dbConfig.setPartitionCount(1);
- dbConfig.setDisableJMX(false);
-
- return new BoneCPDataSource(dbConfig);
- }
-
- private DataSource getC3P0DataSource() {
- final ComboPooledDataSource cpds = new ComboPooledDataSource();
- cpds.setJdbcUrl(config.getJdbcUrl());
- cpds.setUser(config.getUsername());
- cpds.setPassword(config.getPassword());
- // http://www.mchange.com/projects/c3p0/#minPoolSize
- // Minimum number of Connections a pool will maintain at any given time.
- cpds.setMinPoolSize(config.getMinIdle());
- // http://www.mchange.com/projects/c3p0/#maxPoolSize
- // Maximum number of Connections a pool will maintain at any given time.
- cpds.setMaxPoolSize(config.getMaxActive());
- // http://www.mchange.com/projects/c3p0/#checkoutTimeout
- // The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or
- // acquired when the pool is exhausted. Zero means wait indefinitely. Setting any positive value will cause the getConnection()
- // call to time-out and break with an SQLException after the specified number of milliseconds.
- cpds.setCheckoutTimeout(toMilliSeconds(config.getConnectionTimeout()));
- // http://www.mchange.com/projects/c3p0/#maxIdleTime
- // Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire.
- cpds.setMaxIdleTime(toSeconds(config.getIdleMaxAge()));
- // http://www.mchange.com/projects/c3p0/#maxConnectionAge
- // Seconds, effectively a time to live. A Connection older than maxConnectionAge will be destroyed and purged from the pool.
- // This differs from maxIdleTime in that it refers to absolute age. Even a Connection which has not been much idle will be purged
- // from the pool if it exceeds maxConnectionAge. Zero means no maximum absolute age is enforced.
- cpds.setMaxConnectionAge(toSeconds(config.getMaxConnectionAge()));
- // http://www.mchange.com/projects/c3p0/#idleConnectionTestPeriod
- // If this is a number greater than 0, c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds.
- cpds.setIdleConnectionTestPeriod(toSeconds(config.getIdleConnectionTestPeriod()));
-
- return cpds;
- }
-
- private int toSeconds(final TimeSpan timeSpan) {
- return toSeconds(timeSpan.getPeriod(), timeSpan.getUnit());
- }
-
- private int toSeconds(final long period, final TimeUnit timeUnit) {
- return (int) TimeUnit.SECONDS.convert(period, timeUnit);
- }
-
- private int toMilliSeconds(final TimeSpan timeSpan) {
- return toMilliSeconds(timeSpan.getPeriod(), timeSpan.getUnit());
- }
-
- private int toMilliSeconds(final long period, final TimeUnit timeUnit) {
- return (int) TimeUnit.MILLISECONDS.convert(period, timeUnit);
- }
}
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 a0c63e0..8113fdc 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
@@ -16,6 +16,9 @@
package com.ning.billing.server.modules;
+import javax.servlet.ServletContext;
+import javax.sql.DataSource;
+
import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
import org.skife.config.ConfigSource;
import org.skife.config.SimplePropertyConfigSource;
@@ -61,15 +64,24 @@ import com.ning.billing.util.glue.ClockModule;
import com.ning.billing.util.glue.CustomFieldModule;
import com.ning.billing.util.glue.ExportModule;
import com.ning.billing.util.glue.GlobalLockerModule;
+import com.ning.billing.util.glue.KillBillShiroAopModule;
+import com.ning.billing.util.glue.KillBillShiroModule;
import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.RecordIdModule;
+import com.ning.billing.util.glue.SecurityModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.google.inject.AbstractModule;
public class KillbillServerModule extends AbstractModule {
+ protected final ServletContext servletContext;
+
+ public KillbillServerModule(final ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
@Override
protected void configure() {
configureDao();
@@ -90,6 +102,7 @@ public class KillbillServerModule extends AbstractModule {
} catch (final Exception ignore) {
}
bind(IDBI.class).to(DBI.class).asEagerSingleton();
+ bind(DataSource.class).toProvider(DataSourceProvider.class).asEagerSingleton();
bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
}
@@ -145,6 +158,9 @@ public class KillbillServerModule extends AbstractModule {
install(new DefaultOSGIModule(configSource));
install(new UsageModule(configSource));
install(new RecordIdModule());
+ install(new KillBillShiroWebModule(servletContext));
+ install(new KillBillShiroAopModule());
+ install(new SecurityModule());
installClock();
}
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillBillShiroWebModule.java b/server/src/main/java/com/ning/billing/server/modules/KillBillShiroWebModule.java
new file mode 100644
index 0000000..0dfade8
--- /dev/null
+++ b/server/src/main/java/com/ning/billing/server/modules/KillBillShiroWebModule.java
@@ -0,0 +1,69 @@
+/*
+ * 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.server.modules;
+
+import javax.servlet.ServletContext;
+
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.guice.web.ShiroWebModule;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.util.glue.EhCacheManagerProvider;
+import com.ning.billing.util.glue.IniRealmProvider;
+import com.ning.billing.util.glue.JDBCSessionDaoProvider;
+import com.ning.billing.util.glue.KillBillShiroModule;
+import com.ning.billing.util.security.shiro.dao.JDBCSessionDao;
+import com.ning.billing.util.security.shiro.realm.KillBillJndiLdapRealm;
+
+import com.google.inject.binder.AnnotatedBindingBuilder;
+
+// For Kill Bill server only.
+// See com.ning.billing.util.glue.KillBillShiroModule for Kill Bill library.
+public class KillBillShiroWebModule extends ShiroWebModule {
+
+ public KillBillShiroWebModule(final ServletContext servletContext) {
+ super(servletContext);
+ }
+
+ @Override
+ protected void configureShiroWeb() {
+ bindRealm().toProvider(IniRealmProvider.class).asEagerSingleton();
+
+ if (KillBillShiroModule.isLDAPEnabled()) {
+ bindRealm().to(KillBillJndiLdapRealm.class).asEagerSingleton();
+ }
+
+ // Magic provider to configure the cache manager
+ bind(CacheManager.class).toProvider(EhCacheManagerProvider.class).asEagerSingleton();
+
+ if (KillBillShiroModule.isRBACEnabled()) {
+ addFilterChain(JaxrsResource.PREFIX + "/**", AUTHC_BASIC);
+ }
+ }
+
+ @Override
+ protected void bindSessionManager(final AnnotatedBindingBuilder<SessionManager> bind) {
+ // Bypass the servlet container completely for session management and delegate it to Shiro.
+ // The default session timeout is 30 minutes.
+ bind.to(DefaultWebSessionManager.class).asEagerSingleton();
+
+ // Magic provider to configure the session DAO
+ bind(JDBCSessionDao.class).toProvider(JDBCSessionDaoProvider.class).asEagerSingleton();
+ }
+}
diff --git a/server/src/main/java/com/ning/billing/server/security/TenantFilter.java b/server/src/main/java/com/ning/billing/server/security/TenantFilter.java
index 98a77aa..2eaa1a4 100644
--- a/server/src/main/java/com/ning/billing/server/security/TenantFilter.java
+++ b/server/src/main/java/com/ning/billing/server/security/TenantFilter.java
@@ -26,20 +26,28 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.subject.Subject;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
+import org.apache.shiro.realm.Realm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
import com.ning.billing.tenant.api.Tenant;
import com.ning.billing.tenant.api.TenantApiException;
import com.ning.billing.tenant.api.TenantUserApi;
+import com.google.common.collect.ImmutableList;
+
@Singleton
public class TenantFilter implements Filter {
- public static final String SUBJECT = "killbill_subject";
+ // See com.ning.billing.jaxrs.util.Context
public static final String TENANT = "killbill_tenant";
private static final Logger log = LoggerFactory.getLogger(TenantFilter.class);
@@ -47,23 +55,55 @@ public class TenantFilter implements Filter {
@Inject
private TenantUserApi tenantUserApi;
+ private final ModularRealmAuthenticator modularRealmAuthenticator;
+
+ public TenantFilter() {
+ final Realm killbillJdbcRealm = new KillbillJdbcRealm();
+
+ // We use Shiro to verify the api credentials - but the Shiro Subject is only used for RBAC
+ modularRealmAuthenticator = new ModularRealmAuthenticator();
+ modularRealmAuthenticator.setRealms(ImmutableList.<Realm>of(killbillJdbcRealm));
+ }
+
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
- final Subject subject = SecurityUtils.getSubject();
- request.setAttribute(SUBJECT, subject);
-
- final String apiKey = (String) subject.getPrincipal();
- if (apiKey == null) {
- // Resource not protected by Shiro?
+ if (shouldSkipFilter(request)) {
chain.doFilter(request, response);
return;
}
+ // Lookup tenant information in the headers
+ String apiKey = null;
+ String apiSecret = null;
+ if (request instanceof HttpServletRequest) {
+ final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ apiKey = httpServletRequest.getHeader(JaxrsResource.HDR_API_KEY);
+ apiSecret = httpServletRequest.getHeader(JaxrsResource.HDR_API_SECRET);
+ }
+
+ // Multi-tenancy is enabled if this filter is installed, we can't continue without credentials
+ if (apiKey == null || apiSecret == null) {
+ final String errorMessage = String.format("Make sure to set the %s and %s headers", JaxrsResource.HDR_API_KEY, JaxrsResource.HDR_API_SECRET);
+ sendAuthError(response, errorMessage);
+ return;
+ }
+
+ // Verify the apiKey/apiSecret combo
+ final AuthenticationToken token = new UsernamePasswordToken(apiKey, apiSecret);
try {
+ modularRealmAuthenticator.authenticate(token);
+ } catch (AuthenticationException e) {
+ final String errorMessage = e.getLocalizedMessage();
+ sendAuthError(response, errorMessage);
+ return;
+ }
+
+ try {
+ // Load the tenant in the request object (apiKey is unique across tenants)
final Tenant tenant = tenantUserApi.getTenantByApiKey(apiKey);
request.setAttribute(TENANT, tenant);
@@ -77,4 +117,26 @@ public class TenantFilter implements Filter {
@Override
public void destroy() {
}
+
+ private boolean shouldSkipFilter(final ServletRequest request) {
+ boolean shouldSkip = false;
+
+ // Chicken - egg problem
+ if (request instanceof HttpServletRequest) {
+ final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ final String path = httpServletRequest.getRequestURI();
+ if ("/1.0/kb/tenants".equals(path) && "POST".equals(httpServletRequest.getMethod())) {
+ shouldSkip = true;
+ }
+ }
+
+ return shouldSkip;
+ }
+
+ private void sendAuthError(final ServletResponse response, final String errorMessage) throws IOException {
+ if (response instanceof HttpServletResponse) {
+ final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+ httpServletResponse.sendError(401, errorMessage);
+ }
+ }
}
server/src/main/resources/shiro.ini 29(+29 -0)
diff --git a/server/src/main/resources/shiro.ini b/server/src/main/resources/shiro.ini
new file mode 100644
index 0000000..a419d0a
--- /dev/null
+++ b/server/src/main/resources/shiro.ini
@@ -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. #
+# #
+###################################################################################
+
+# [main]
+# See com.ning.billing.util.glue.KillBillShiroModule
+# Use -Dkillbill.server.rbac=false to disable RBAC
+
+# Default admin user
+# Use -Dkillbill.security.shiroResourcePath=/var/tmp/shiro.ini to specify your own config
+[users]
+admin = password, root
+
+[roles]
+root = *:*
diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml
index 13d7694..482e6c1 100644
--- a/server/src/main/webapp/WEB-INF/web.xml
+++ b/server/src/main/webapp/WEB-INF/web.xml
@@ -20,17 +20,13 @@
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
- <listener>
- <!-- Initialize Shiro WebEnvironment and put it into the ServletContext -->
- <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
- </listener>
<filter>
<!-- Filter all requests through Shiro -->
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
- <!-- The Shitor filter-mapping should come first -->
+ <!-- The Shiro filter-mapping should come first -->
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
diff --git a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
index 0f8ce60..04d8012 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
@@ -44,6 +44,7 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.jaxrs.json.AccountEmailJson;
import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.jaxrs.json.AccountTimelineJson;
+import com.ning.billing.jaxrs.json.CatalogJsonSimple;
import com.ning.billing.jaxrs.json.ChargebackJson;
import com.ning.billing.jaxrs.json.CreditJson;
import com.ning.billing.jaxrs.json.EntitlementJsonNoEvents;
@@ -56,6 +57,7 @@ import com.ning.billing.jaxrs.json.PaymentJsonWithBundleKeys;
import com.ning.billing.jaxrs.json.PaymentMethodJson;
import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
+import com.ning.billing.jaxrs.json.PlanDetailJson;
import com.ning.billing.jaxrs.json.RefundJson;
import com.ning.billing.jaxrs.json.TenantJson;
import com.ning.billing.jaxrs.resources.JaxrsResource;
@@ -64,6 +66,8 @@ import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
import com.ning.http.client.ListenableFuture;
+import com.ning.http.client.Realm;
+import com.ning.http.client.Realm.AuthScheme;
import com.ning.http.client.Response;
import com.ning.jetty.core.CoreConfig;
@@ -72,9 +76,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableMap;
+import com.google.inject.TypeLiteral;
import static com.ning.billing.jaxrs.resources.JaxrsResource.ACCOUNTS;
import static com.ning.billing.jaxrs.resources.JaxrsResource.BUNDLES;
+import static com.ning.billing.jaxrs.resources.JaxrsResource.HDR_API_KEY;
+import static com.ning.billing.jaxrs.resources.JaxrsResource.HDR_API_SECRET;
import static com.ning.billing.jaxrs.resources.JaxrsResource.QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF;
import static com.ning.billing.jaxrs.resources.JaxrsResource.SUBSCRIPTIONS;
import static org.testng.Assert.assertEquals;
@@ -84,7 +91,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
protected static final String PLUGIN_NAME = "noop";
- protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 50000;
+ protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 20;
protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
@@ -99,6 +106,16 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
protected AsyncHttpClient httpClient;
protected ObjectMapper mapper;
+ // Multi-Tenancy information, if enabled
+ protected String DEFAULT_API_KEY = UUID.randomUUID().toString();
+ protected String DEFAULT_API_SECRET = UUID.randomUUID().toString();
+ protected String apiKey = DEFAULT_API_KEY;
+ protected String apiSecret = DEFAULT_API_SECRET;
+
+ // RBAC information, if enabled
+ protected String username = null;
+ protected String password = null;
+
// Context information to be passed around
protected static final String createdBy = "Toto";
protected static final String reason = "i am god";
@@ -154,6 +171,44 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
}
//
+ // SECURITY UTILITIES
+ //
+
+ protected void loginAsAdmin() {
+ loginAs("tester", "tester");
+ }
+
+ protected void loginAs(final String username, final String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ protected void logout() {
+ this.username = null;
+ this.password = null;
+ }
+
+ protected List<String> getPermissions(@Nullable final String username, @Nullable final String password) throws Exception {
+ final String oldUsername = this.username;
+ final String oldPassword = this.password;
+
+ this.username = username;
+ this.password = password;
+
+ final Response response = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+ this.username = oldUsername;
+ this.password = oldPassword;
+
+ final String baseJson = response.getResponseBody();
+ final List<String> objFromJson = mapper.readValue(baseJson, new TypeReference<List<String>>() {});
+ Assert.assertNotNull(objFromJson);
+
+ return objFromJson;
+ }
+
+ //
// ACCOUNT UTILITIES
//
@@ -180,6 +235,18 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
return objFromJson;
}
+ protected List<AccountJson> searchAccountsByKey(final String key) throws Exception {
+ final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.SEARCH + "/" + key;
+ final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+ final String baseJson = response.getResponseBody();
+ final List<AccountJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<AccountJson>>() {});
+ Assert.assertNotNull(objFromJson);
+
+ return objFromJson;
+ }
+
protected Response getAccountByExternalKeyNoValidation(final String externalKey) {
final Map<String, String> queryParams = new HashMap<String, String>();
queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, externalKey);
@@ -372,6 +439,10 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
return doGetInvoice(invoiceId, Boolean.FALSE, InvoiceJsonSimple.class);
}
+ protected InvoiceJsonSimple getInvoice(final Integer invoiceNumber) throws IOException {
+ return getInvoice(invoiceNumber.toString());
+ }
+
protected InvoiceJsonWithItems getInvoiceWithItems(final String invoiceId) throws IOException {
return doGetInvoice(invoiceId, Boolean.TRUE, InvoiceJsonWithItems.class);
}
@@ -543,8 +614,9 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
protected PaymentMethodJson getPaymentMethodWithPluginInfo(final String paymentMethodId) throws IOException {
final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
- final Map<String, String> queryPaymentMethods = new HashMap<String, String>();
- final Response paymentMethodResponse = doGet(paymentMethodURI, queryPaymentMethods, DEFAULT_HTTP_TIMEOUT_SEC);
+ final Response paymentMethodResponse = doGet(paymentMethodURI,
+ ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_INFO, "true"),
+ DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
@@ -553,6 +625,24 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
return paymentMethodJson;
}
+ protected List<PaymentMethodJson> searchPaymentMethodsByKey(final String key) throws Exception {
+ return searchPaymentMethodsByKeyAndPlugin(key, null);
+ }
+
+ protected List<PaymentMethodJson> searchPaymentMethodsByKeyAndPlugin(final String key, @Nullable final String pluginName) throws Exception {
+ final String uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + JaxrsResource.SEARCH + "/" + key;
+ final Response response = doGet(uri,
+ pluginName == null ? DEFAULT_EMPTY_QUERY : ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_NAME, pluginName),
+ DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+ final String baseJson = response.getResponseBody();
+ final List<PaymentMethodJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
+ Assert.assertNotNull(objFromJson);
+
+ return objFromJson;
+ }
+
protected void deletePaymentMethod(final String paymentMethodId, final Boolean deleteDefault) throws IOException {
final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
@@ -838,6 +928,33 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
}
//
+ // CATALOG
+ //
+
+ public CatalogJsonSimple getSimpleCatalog() throws Exception {
+ final Response response = doGet(JaxrsResource.CATALOG_PATH + "/simpleCatalog", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ final String body = response.getResponseBody();
+ return mapper.readValue(body, CatalogJsonSimple.class);
+ }
+
+ public List<PlanDetailJson> getAvailableAddons(final String baseProductName) throws Exception {
+ final Response response = doGet(JaxrsResource.CATALOG_PATH + "/availableAddons",
+ ImmutableMap.<String, String>of("baseProductName", baseProductName),
+ DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ final String body = response.getResponseBody();
+ return mapper.readValue(body, new TypeReference<List<PlanDetailJson>>() {});
+ }
+
+ public List<PlanDetailJson> getBasePlans() throws Exception {
+ final Response response = doGet(JaxrsResource.CATALOG_PATH + "/availableBasePlans", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ final String body = response.getResponseBody();
+ return mapper.readValue(body, new TypeReference<List<PlanDetailJson>>() {});
+ }
+
+ //
// HTTP CLIENT HELPERS
//
protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
@@ -897,7 +1014,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
return executeAndWait(builder, timeoutSec, false);
}
- private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
+ protected Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
if (addContextHeader) {
builder.addHeader(JaxrsResource.HDR_CREATED_BY, createdBy);
@@ -905,6 +1022,16 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
builder.addHeader(JaxrsResource.HDR_COMMENT, comment);
}
+ if (username != null && password != null) {
+ final Realm realm = new Realm.RealmBuilder()
+ .setPrincipal(username)
+ .setPassword(password)
+ .setUsePreemptiveAuth(true)
+ .setScheme(AuthScheme.BASIC)
+ .build();
+ builder.setRealm(realm);
+ }
+
Response response = null;
try {
final ListenableFuture<Response> futureStatus =
@@ -926,7 +1053,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
return String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
}
- private BoundRequestBuilder getBuilderWithHeaderAndQuery(final String verb, final String url, final Map<String, String> queryParams) {
+ protected BoundRequestBuilder getBuilderWithHeaderAndQuery(final String verb, final String url, final Map<String, String> queryParams) {
BoundRequestBuilder builder = null;
if (verb.equals("GET")) {
builder = httpClient.prepareGet(url);
@@ -945,6 +1072,8 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
}
builder.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE);
+ builder.addHeader(HDR_API_KEY, apiKey);
+ builder.addHeader(HDR_API_SECRET, apiSecret);
for (final Entry<String, String> q : queryParams.entrySet()) {
builder.addQueryParameter(q.getKey(), q.getValue());
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index 4c90eab..239c4d3 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import javax.annotation.Nullable;
import javax.ws.rs.core.Response.Status;
import org.testng.Assert;
@@ -56,6 +57,9 @@ public class TestAccount extends TestJaxrsBase {
final AccountJson retrievedAccount = getAccountByExternalKey(input.getExternalKey());
Assert.assertTrue(retrievedAccount.equals(input));
+ // Try search endpoint
+ searchAccount(input, retrievedAccount);
+
// Update Account
final AccountJson newInput = new AccountJson(input.getAccountId(),
"zozo", 4, input.getExternalKey(), "rr@google.com", 18,
@@ -63,6 +67,9 @@ public class TestAccount extends TestJaxrsBase {
false, false);
final AccountJson updatedAccount = updateAccount(input.getAccountId(), newInput);
Assert.assertTrue(updatedAccount.equals(newInput));
+
+ // Try search endpoint
+ searchAccount(input, null);
}
@Test(groups = "slow")
@@ -250,7 +257,8 @@ public class TestAccount extends TestJaxrsBase {
@Test(groups = "slow")
public void testTags() throws Exception {
- final String accountId = UUID.randomUUID().toString();
+ final AccountJson input = createAccount();
+ final String accountId = input.getAccountId();
final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TAGS;
final String accountTagsUrl = getUrlFromUri(uri);
// Use tag definition for AUTO_PAY_OFF
@@ -280,7 +288,6 @@ public class TestAccount extends TestJaxrsBase {
@Test(groups = "slow")
public void testCustomFields() throws Exception {
-
final AccountJson accountJson = createAccount("yoyoq", "gfgrqe", "yoyoq@yahoo.com");
assertNotNull(accountJson);
@@ -299,4 +306,32 @@ public class TestAccount extends TestJaxrsBase {
response = doGetWithUrl(url, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
}
+
+ private void searchAccount(final AccountJson input, @Nullable final AccountJson output) throws Exception {
+ // Search by name
+ doSearchAccount(input.getName(), output);
+
+ // Search by email
+ doSearchAccount(input.getEmail(), output);
+
+ // Search by company name
+ doSearchAccount(input.getCompany(), output);
+
+ // Search by external key.
+ // Note: we will always find a match since we don't update it
+ final List<AccountJson> accountsByExternalKey = searchAccountsByKey(input.getExternalKey());
+ Assert.assertEquals(accountsByExternalKey.size(), 1);
+ Assert.assertEquals(accountsByExternalKey.get(0).getAccountId(), input.getAccountId());
+ Assert.assertEquals(accountsByExternalKey.get(0).getExternalKey(), input.getExternalKey());
+ }
+
+ private void doSearchAccount(final String key, @Nullable final AccountJson output) throws Exception {
+ final List<AccountJson> accountsByKey = searchAccountsByKey(key);
+ if (output == null) {
+ Assert.assertEquals(accountsByKey.size(), 0);
+ } else {
+ Assert.assertEquals(accountsByKey.size(), 1);
+ Assert.assertEquals(accountsByKey.get(0), output);
+ }
+ }
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
index 3390b7d..8291fb9 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
@@ -13,29 +13,55 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+
package com.ning.billing.jaxrs;
-import javax.ws.rs.core.Response.Status;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.ning.billing.jaxrs.json.CatalogJsonSimple;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
+import com.ning.billing.jaxrs.json.CatalogJsonSimple.PlanJson;
+import com.ning.billing.jaxrs.json.CatalogJsonSimple.ProductJson;
+import com.ning.billing.jaxrs.json.PlanDetailJson;
public class TestCatalog extends TestJaxrsBase {
- private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
-
- @Test(groups = "slow", enabled = true)
+ @Test(groups = "slow")
public void testCatalogSimple() throws Exception {
- Response response = doGet(JaxrsResource.CATALOG_PATH + "/simpleCatalog", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
- Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
- String body = response.getResponseBody();
- CatalogJsonSimple objFromJson = mapper.readValue(body, CatalogJsonSimple.class);
- log.info("Yeaahh...");
+ final Set<String> allBasePlans = new HashSet<String>();
+
+ final CatalogJsonSimple catalogJsonSimple = getSimpleCatalog();
+ for (final ProductJson productJson : catalogJsonSimple.getProducts()) {
+ if (!"BASE".equals(productJson.getType())) {
+ Assert.assertEquals(productJson.getIncluded().size(), 0);
+ Assert.assertEquals(productJson.getAvailable().size(), 0);
+ continue;
+ }
+
+ // Save all plans for later (see below)
+ for (final PlanJson planJson : productJson.getPlans()) {
+ allBasePlans.add(planJson.getName());
+ }
+
+ // Retrieve available products (addons) for that base product
+ final List<PlanDetailJson> availableAddons = getAvailableAddons(productJson.getName());
+ final Set<String> availableAddonsNames = new HashSet<String>();
+ for (final PlanDetailJson planDetailJson : availableAddons) {
+ availableAddonsNames.add(planDetailJson.getProductName());
+ }
+ Assert.assertEquals(availableAddonsNames, new HashSet<String>(productJson.getAvailable()));
+ }
+
+ // Verify base plans endpoint
+ final List<PlanDetailJson> basePlans = getBasePlans();
+ final Set<String> foundBasePlans = new HashSet<String>();
+ for (final PlanDetailJson planDetailJson : basePlans) {
+ foundBasePlans.add(planDetailJson.getPlanName());
+ }
+ Assert.assertEquals(foundBasePlans, allBasePlans);
}
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index 97d8dbc..69833e4 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -52,6 +52,10 @@ public class TestInvoice extends TestJaxrsBase {
final InvoiceJsonSimple firstInvoiceJson = getInvoice(invoiceJsonSimple.getInvoiceId());
assertEquals(firstInvoiceJson, invoiceJsonSimple);
+ // Check we can retrieve the invoice by number
+ final InvoiceJsonSimple firstInvoiceByNumberJson = getInvoice(invoiceJsonSimple.getInvoiceNumber());
+ assertEquals(firstInvoiceByNumberJson, invoiceJsonSimple);
+
// Then create a dryRun Invoice
final DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
createDryRunInvoice(accountJson.getAccountId(), futureDate);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index 31014eb..d900118 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -19,14 +19,15 @@ package com.ning.billing.jaxrs;
import java.io.IOException;
import java.net.URL;
import java.util.EventListener;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.inject.Inject;
import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
-import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
+import org.apache.shiro.web.env.EnvironmentLoaderListener;
+import org.apache.shiro.web.servlet.ShiroFilter;
import org.eclipse.jetty.servlet.FilterHolder;
import org.joda.time.LocalDate;
import org.skife.config.ConfigSource;
@@ -37,6 +38,7 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
+import com.ning.billing.DBTestingHelper;
import com.ning.billing.GuicyKillbillTestWithEmbeddedDBModule;
import com.ning.billing.KillbillConfigSource;
import com.ning.billing.account.glue.DefaultAccountModule;
@@ -44,9 +46,8 @@ import com.ning.billing.api.TestApiListener;
import com.ning.billing.beatrix.glue.BeatrixModule;
import com.ning.billing.bus.api.PersistentBus;
import com.ning.billing.catalog.glue.CatalogModule;
-import com.ning.billing.dbi.DBTestingHelper;
-import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.subscription.glue.DefaultSubscriptionModule;
+import com.ning.billing.commons.embeddeddb.EmbeddedDB;
+import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
import com.ning.billing.invoice.api.InvoiceNotifier;
import com.ning.billing.invoice.glue.DefaultInvoiceModule;
import com.ning.billing.invoice.notification.NullInvoiceNotifier;
@@ -57,7 +58,9 @@ import com.ning.billing.overdue.glue.DefaultOverdueModule;
import com.ning.billing.payment.glue.PaymentModule;
import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
import com.ning.billing.server.listeners.KillbillGuiceListener;
+import com.ning.billing.server.modules.KillBillShiroWebModule;
import com.ning.billing.server.modules.KillbillServerModule;
+import com.ning.billing.subscription.glue.DefaultSubscriptionModule;
import com.ning.billing.tenant.glue.TenantModule;
import com.ning.billing.usage.glue.UsageModule;
import com.ning.billing.util.cache.CacheControllerDispatcher;
@@ -71,9 +74,12 @@ import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.CustomFieldModule;
import com.ning.billing.util.glue.ExportModule;
+import com.ning.billing.util.glue.KillBillShiroAopModule;
+import com.ning.billing.util.glue.KillBillShiroModule;
import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.RecordIdModule;
+import com.ning.billing.util.glue.SecurityModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClientConfig;
@@ -84,6 +90,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import static org.testng.Assert.assertNotNull;
@@ -123,17 +130,17 @@ public class TestJaxrsBase extends KillbillClient {
public static class TestKillbillGuiceListener extends KillbillGuiceListener {
- private final TestKillbillServerModule module;
+ private final EmbeddedDB helper;
- public TestKillbillGuiceListener(final DBTestingHelper helper) {
+ public TestKillbillGuiceListener(final EmbeddedDB helper) {
super();
- this.module = new TestKillbillServerModule(helper);
+ this.helper = helper;
}
@Override
- protected Module getModule() {
- return module;
+ protected Module getModule(final ServletContext servletContext) {
+ return new TestKillbillServerModule(helper, servletContext);
}
}
@@ -152,10 +159,10 @@ public class TestJaxrsBase extends KillbillClient {
public static class TestKillbillServerModule extends KillbillServerModule {
- private final DBTestingHelper helper;
+ private final EmbeddedDB helper;
- public TestKillbillServerModule(final DBTestingHelper helper) {
- super();
+ public TestKillbillServerModule(final EmbeddedDB helper, final ServletContext servletContext) {
+ super(servletContext);
this.helper = helper;
}
@@ -198,7 +205,7 @@ public class TestJaxrsBase extends KillbillClient {
install(new EmailModule(configSource));
install(new CacheModule(configSource));
install(new NonEntityDaoModule());
- install(new TestGlobalLockerModule(helper));
+ install(new TestGlobalLockerModule(DBTestingHelper.get()));
install(new CustomFieldModule());
install(new TagStoreModule());
install(new AuditModule());
@@ -221,6 +228,9 @@ public class TestJaxrsBase extends KillbillClient {
install(new UsageModule(configSource));
install(new RecordIdModule());
installClock();
+ install(new KillBillShiroWebModule(servletContext));
+ install(new KillBillShiroAopModule());
+ install(new SecurityModule());
}
}
@@ -233,6 +243,11 @@ public class TestJaxrsBase extends KillbillClient {
busHandler.reset();
clock.resetDeltaFromReality();
clock.setDay(new LocalDate(2012, 8, 25));
+
+ loginAsAdmin();
+
+ // Recreate the tenant (tables have been cleaned-up)
+ createTenant(DEFAULT_API_KEY, DEFAULT_API_SECRET);
}
@AfterMethod(groups = "slow")
@@ -245,17 +260,15 @@ public class TestJaxrsBase extends KillbillClient {
public void beforeClass() throws Exception {
loadConfig();
-
listener.getInstantiatedInjector().injectMembers(this);
httpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build());
+
mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
- //mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
-
- busHandler = new TestApiListener(null, getDBTestingHelper().getDBI());
+ busHandler = new TestApiListener(null, dbi);
}
protected void loadConfig() {
@@ -264,9 +277,9 @@ public class TestJaxrsBase extends KillbillClient {
}
// For shiro (outside of Guice control)
- System.setProperty("com.ning.jetty.jdbi.url", getDBTestingHelper().getJdbcConnectionString());
- System.setProperty("com.ning.jetty.jdbi.user", MysqlTestingHelper.USERNAME);
- System.setProperty("com.ning.jetty.jdbi.password", MysqlTestingHelper.PASSWORD);
+ System.setProperty("com.ning.jetty.jdbi.url", DBTestingHelper.get().getJdbcConnectionString());
+ System.setProperty("com.ning.jetty.jdbi.user", DBTestingHelper.get().getUsername());
+ System.setProperty("com.ning.jetty.jdbi.password", DBTestingHelper.get().getPassword());
}
@BeforeSuite(groups = "slow")
@@ -275,27 +288,26 @@ public class TestJaxrsBase extends KillbillClient {
loadSystemPropertiesFromClasspath("/killbill.properties");
loadConfig();
- listener = new TestKillbillGuiceListener(getDBTestingHelper());
- server = new HttpServer();
+ listener = new TestKillbillGuiceListener(helper);
+ server = new HttpServer();
server.configure(config, getListeners(), getFilters());
-
server.start();
-
- listener.getInstantiatedInjector().injectMembers(this);
}
protected Iterable<EventListener> getListeners() {
return new Iterable<EventListener>() {
@Override
public Iterator<EventListener> iterator() {
+ // Note! This needs to be in sync with web.xml
return ImmutableList.<EventListener>of(listener).iterator();
}
};
}
protected Map<FilterHolder, String> getFilters() {
- return new HashMap<FilterHolder, String>();
+ // Note! This needs to be in sync with web.xml
+ return ImmutableMap.<FilterHolder, String>of(new FilterHolder(new ShiroFilter()), "/*");
}
@AfterSuite(groups = "slow")
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java b/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
new file mode 100644
index 0000000..4d1e2f8
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
@@ -0,0 +1,68 @@
+/*
+ * 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.jaxrs;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.PaymentMethodJson;
+
+public class TestPaymentMethod extends TestJaxrsBase {
+
+ @Test(groups = "slow")
+ public void testSearchPaymentMethods() throws Exception {
+ // Search random key
+ Assert.assertEquals(searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
+ Assert.assertEquals(searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
+
+ // Create a payment method
+ final AccountJson accountJson = createAccountWithDefaultPaymentMethod();
+ final PaymentMethodJson paymentMethodJson = getPaymentMethodWithPluginInfo(accountJson.getPaymentMethodId());
+
+ // Search random key again
+ Assert.assertEquals(searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
+ Assert.assertEquals(searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
+
+ // Make sure we can search the test plugin
+ // Values are hardcoded in TestPaymentMethodPluginBase and the search logic is in MockPaymentProviderPlugin
+ doSearch("Foo", paymentMethodJson);
+ // Last 4
+ doSearch("4365", paymentMethodJson);
+ // Name
+ doSearch("Bozo", paymentMethodJson);
+ // City
+ doSearch("SF", paymentMethodJson);
+ // State
+ doSearch("CA", paymentMethodJson);
+ // Country
+ doSearch("Zimbawe", paymentMethodJson);
+ }
+
+ private void doSearch(final String searchKey, final PaymentMethodJson paymentMethodJson) throws Exception {
+ final List<PaymentMethodJson> results1 = searchPaymentMethodsByKey(searchKey);
+ Assert.assertEquals(results1.size(), 1);
+ Assert.assertEquals(results1.get(0), paymentMethodJson);
+
+ final List<PaymentMethodJson> results2 = searchPaymentMethodsByKeyAndPlugin(searchKey, PLUGIN_NAME);
+ Assert.assertEquals(results2.size(), 1);
+ Assert.assertEquals(results2.get(0), paymentMethodJson);
+ }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java b/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
index 83ab8cf..68d5a6d 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
@@ -68,7 +68,7 @@ public class TestPushNotification extends TestJaxrsBase {
private boolean waitForCallbacksToComplete() throws InterruptedException {
- long remainingMs = 5000;
+ long remainingMs = 20000;
do {
if (callbackCompleted) {
break;
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java b/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java
new file mode 100644
index 0000000..3c820d8
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java
@@ -0,0 +1,88 @@
+/*
+ * 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.jaxrs;
+
+import java.util.HashSet;
+import java.util.List;
+
+import javax.annotation.Nullable;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.shiro.web.servlet.ShiroHttpSession;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.security.Permission;
+import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
+import com.ning.http.client.Cookie;
+import com.ning.http.client.Response;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class TestSecurity extends TestJaxrsBase {
+
+ @Test(groups = "slow")
+ public void testPermissions() throws Exception {
+ logout();
+
+ final Response anonResponse = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(anonResponse.getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+
+ // See src/test/resources/shiro.ini
+
+ final List<String> pierresPermissions = getPermissions("pierre", "password");
+ Assert.assertEquals(pierresPermissions.size(), 2);
+ Assert.assertEquals(new HashSet<String>(pierresPermissions), ImmutableSet.<String>of(Permission.INVOICE_CAN_CREDIT.toString(), Permission.INVOICE_CAN_ITEM_ADJUST.toString()));
+
+ final List<String> stephanesPermissions = getPermissions("stephane", "password");
+ Assert.assertEquals(stephanesPermissions.size(), 1);
+ Assert.assertEquals(new HashSet<String>(stephanesPermissions), ImmutableSet.<String>of(Permission.PAYMENT_CAN_REFUND.toString()));
+ }
+
+ @Test(groups = "slow")
+ public void testSession() throws Exception {
+ loginAs("pierre", "password");
+
+ final Response firstResponse = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(firstResponse.getStatusCode(), Status.OK.getStatusCode());
+ Assert.assertEquals(((List) mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<String>>() {})).size(), 2);
+
+ // Retrieve the session id
+ final Cookie session = Iterables.find(firstResponse.getCookies(),
+ new Predicate<Cookie>() {
+ @Override
+ public boolean apply(@Nullable final Cookie cookie) {
+ return ShiroHttpSession.DEFAULT_SESSION_ID_NAME.equals(cookie.getName());
+ }
+ });
+
+ // Make sure we don't use the credentials anymore
+ logout();
+
+ // Re-issue the query with the cookie
+ final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), JaxrsResource.SECURITY_PATH + "/permissions");
+ final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, DEFAULT_EMPTY_QUERY);
+ builder.addCookie(session);
+ final Response secondResponse = executeAndWait(builder, DEFAULT_HTTP_TIMEOUT_SEC, false);
+ Assert.assertEquals(secondResponse.getStatusCode(), Status.OK.getStatusCode());
+ Assert.assertEquals(((List) mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<String>>() {})).size(), 2);
+ }
+}
diff --git a/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
index ac06a5a..b193de3 100644
--- a/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
+++ b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
@@ -28,7 +28,6 @@ import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.jaxrs.TestJaxrsBase;
import com.ning.billing.tenant.api.DefaultTenant;
import com.ning.billing.tenant.dao.DefaultTenantDao;
@@ -50,16 +49,16 @@ public class TestKillbillJdbcRealm extends TestJaxrsBase {
super.beforeMethod();
// Create the tenant
- final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI(), clock, cacheControllerDispatcher, new DefaultNonEntityDao(getDBI()));
+ final DefaultTenantDao tenantDao = new DefaultTenantDao(dbi, clock, cacheControllerDispatcher, new DefaultNonEntityDao(dbi));
tenant = new DefaultTenant(UUID.randomUUID(), null, null, UUID.randomUUID().toString(),
UUID.randomUUID().toString(), UUID.randomUUID().toString());
tenantDao.create(new TenantModelDao(tenant), internalCallContext);
// Setup the security manager
final BoneCPConfig dbConfig = new BoneCPConfig();
- dbConfig.setJdbcUrl(getDBTestingHelper().getJdbcConnectionString());
- dbConfig.setUsername(MysqlTestingHelper.USERNAME);
- dbConfig.setPassword(MysqlTestingHelper.PASSWORD);
+ dbConfig.setJdbcUrl(helper.getJdbcConnectionString());
+ dbConfig.setUsername(helper.getUsername());
+ dbConfig.setPassword(helper.getPassword());
final KillbillJdbcRealm jdbcRealm;
jdbcRealm = new KillbillJdbcRealm();
diff --git a/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
index d4a0dbf..ef60130 100644
--- a/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
+++ b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
@@ -16,56 +16,30 @@
package com.ning.billing.server.security;
-import java.util.EventListener;
-import java.util.Iterator;
-import java.util.Map;
-
import javax.ws.rs.core.Response.Status;
-import org.apache.shiro.web.env.EnvironmentLoaderListener;
-import org.apache.shiro.web.servlet.ShiroFilter;
-import org.eclipse.jetty.servlet.FilterHolder;
import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.ning.billing.jaxrs.TestJaxrsBase;
import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.server.listeners.KillbillGuiceListener;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
-import com.ning.http.client.Realm;
-import com.ning.http.client.Realm.AuthScheme;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-public class TestTenantFilter extends TestJaxrsBase {
-
- @Override
- protected void loadConfig() {
- System.setProperty(KillbillGuiceListener.KILLBILL_MULTITENANT_PROPERTY, "true");
- super.loadConfig();
- }
+// Pure Multi-Tenancy test (no RBAC)
+public class TestTenantFilter extends TestJaxrsBase {
- @Override
- protected Iterable<EventListener> getListeners() {
- return new Iterable<EventListener>() {
- @Override
- public Iterator<EventListener> iterator() {
- return ImmutableList.<EventListener>of(listener, new EnvironmentLoaderListener()).iterator();
- }
- };
+ @AfterMethod(groups = "slow")
+ public void tearDown() throws Exception {
+ // Default credentials
+ loginTenant(DEFAULT_API_KEY, DEFAULT_API_SECRET);
}
- @Override
- protected Map<FilterHolder, String> getFilters() {
- return ImmutableMap.<FilterHolder, String>of(new FilterHolder(ShiroFilter.class), "/*");
- }
-
- // TODO Need to run by itself for now as the server from the test suite doesn't have the Shiro setup
- @Test(groups = "slow", enabled = false)
+ @Test(groups = "slow")
public void testTenantShouldOnlySeeOwnAccount() throws Exception {
// Try to create an account without being logged-in
+ logoutTenant();
Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
// Create the tenant
@@ -105,18 +79,12 @@ public class TestTenantFilter extends TestJaxrsBase {
}
private void loginTenant(final String apiKey, final String apiSecret) {
- final AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
- final Realm realm = new Realm.RealmBuilder()
- .setPrincipal(apiKey)
- .setPassword(apiSecret)
- .setUsePreemptiveAuth(true)
- .setScheme(AuthScheme.BASIC)
- .build();
- builder.setRealm(realm).setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build();
- httpClient = new AsyncHttpClient(builder.build());
+ this.apiKey = apiKey;
+ this.apiSecret = apiSecret;
}
private void logoutTenant() {
- httpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build());
+ apiKey = "";
+ apiSecret = "";
}
}
diff --git a/server/src/test/resources/killbill.properties b/server/src/test/resources/killbill.properties
index 6a30a5c..dd7b4f2 100644
--- a/server/src/test/resources/killbill.properties
+++ b/server/src/test/resources/killbill.properties
@@ -37,5 +37,8 @@ killbill.billing.persistent.bus.claimed=1
killbill.osgi.bundle.install.dir=/var/tmp/somethingthatdoesnotexist
+# Speed up from the (more secure) default
+killbill.server.multitenant.hash_iterations=10
+
ANTLR_USE_DIRECT_CLASS_LOADING=true
server/src/test/resources/shiro.ini 27(+10 -17)
diff --git a/server/src/test/resources/shiro.ini b/server/src/test/resources/shiro.ini
index 664ee13..4f9db89 100644
--- a/server/src/test/resources/shiro.ini
+++ b/server/src/test/resources/shiro.ini
@@ -1,6 +1,6 @@
###################################################################################
# #
-# Copyright 2010-2012 Ning, Inc. #
+# 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 #
@@ -16,22 +16,15 @@
# #
###################################################################################
-[main]
-# Bypass the servlet container completely for session management and delegate
-# it to Shiro (to be portable across servlet containers)
-# The default session timeout is 30 minutes.
-sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
-# Use the configured native session manager
-securityManager.sessionManager = $sessionManager
+[users]
+tester = tester, admin
+pierre = password, creditor
+stephane = password, refunder
-jdbcRealm=com.ning.billing.server.security.KillbillJdbcRealm
+[roles]
+admin = *:*
+creditor = invoice:credit, invoice:item_adjust
+refunder = payment:refund
[urls]
-# Special endpoints: healthcheck, tenant API.
-# TODO: don't secure them for now - eventually require admin privileges
-/1.0/healthcheck = anon
-/1.0/kb/tenants/** = anon
-# For all other resources, require basic auth
-# TODO: ssl, authcBasic
-# Commented out because that seems to break the server tests that don't require authentification
-#/1.0/kb/** = authcBasic
+/1.0/kb/** = authcBasic
subscription/killbill-subscription.iml 42(+32 -10)
diff --git a/subscription/killbill-subscription.iml b/subscription/killbill-subscription.iml
index 3208953..9f2164a 100644
--- a/subscription/killbill-subscription.iml
+++ b/subscription/killbill-subscription.iml
@@ -12,6 +12,20 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
@@ -24,12 +38,12 @@
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:1.2" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-catalog:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -40,13 +54,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -54,11 +69,18 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-catalog" scope="TEST" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
subscription/pom.xml 7(+6 -1)
diff --git a/subscription/pom.xml b/subscription/pom.xml
index 8ee1437..095314e 100644
--- a/subscription/pom.xml
+++ b/subscription/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-subscription</artifactId>
@@ -95,6 +95,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
tenant/killbill-tenant.iml 34(+24 -10)
diff --git a/tenant/killbill-tenant.iml b/tenant/killbill-tenant.iml
index 342033b..cf88d12 100644
--- a/tenant/killbill-tenant.iml
+++ b/tenant/killbill-tenant.iml
@@ -11,17 +11,25 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -32,13 +40,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -46,14 +55,19 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
- <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.1" level="project" />
- <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:slf4j-simple:1.7.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.3.1" level="project" />
tenant/pom.xml 7(+6 -1)
diff --git a/tenant/pom.xml b/tenant/pom.xml
index 66ebda4..63df7ee 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-tenant</artifactId>
@@ -74,6 +74,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
diff --git a/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java b/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java
index 31eb22d..f95478b 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/security/KillbillCredentialsMatcher.java
@@ -22,9 +22,11 @@ import org.apache.shiro.crypto.hash.Sha512Hash;
public class KillbillCredentialsMatcher {
+ public static final String KILLBILL_TENANT_HASH_ITERATIONS_PROPERTY = "killbill.server.multitenant.hash_iterations";
+
// See http://www.stormpath.com/blog/strong-password-hashing-apache-shiro and https://issues.apache.org/jira/browse/SHIRO-290
public static final String HASH_ALGORITHM_NAME = Sha512Hash.ALGORITHM_NAME;
- public static final int HASH_ITERATIONS = 500000;
+ public static final Integer HASH_ITERATIONS = Integer.parseInt(System.getProperty(KILLBILL_TENANT_HASH_ITERATIONS_PROPERTY, "200000"));
private KillbillCredentialsMatcher() {}
usage/killbill-usage.iml 35(+27 -8)
diff --git a/usage/killbill-usage.iml b/usage/killbill-usage.iml
index 866d349..2b730d2 100644
--- a/usage/killbill-usage.iml
+++ b/usage/killbill-usage.iml
@@ -11,16 +11,27 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:14.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.h2database:h2:1.3.158" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.0" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" />
@@ -31,13 +42,14 @@
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.7.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
@@ -45,9 +57,16 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
+ <orderEntry type="library" scope="PROVIDED" name="Maven: com.google.inject.extensions:guice-multibindings:3.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="module" module-name="killbill-util" scope="TEST" production-on-test="" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.3.6-SNAPSHOT" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing:killbill-util:test-jar:tests:0.5.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj-db-files:5.0.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
usage/pom.xml 7(+6 -1)
diff --git a/usage/pom.xml b/usage/pom.xml
index 86b1e69..3010a2e 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-usage</artifactId>
@@ -69,6 +69,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
util/killbill-util.iml 33(+25 -8)
diff --git a/util/killbill-util.iml b/util/killbill-util.iml
index 1d9ecaf..0782507 100644
--- a/util/killbill-util.iml
+++ b/util/killbill-util.iml
@@ -12,6 +12,16 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.1.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.1.0" level="project" />
@@ -34,19 +44,21 @@
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.3.3" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.3.3-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing:killbill-api:0.6.0-SNAPSHOT" level="project" />
<orderEntry type="module" module-name="killbill-internal-api" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-payment:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.skife.config:config-magic:0.14" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.1.7" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.1.7" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-clock:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-clock:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-embeddeddb:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-locker:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-queue:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.commons:killbill-jdbi:0.2.1" level="project" />
<orderEntry type="library" name="Maven: org.jdbi:jdbi:2.39.1" level="project" />
<orderEntry type="library" name="Maven: com.yammer.metrics:metrics-core:2.1.2" level="project" />
<orderEntry type="library" name="Maven: org.weakref:jmxutils:1.12" level="project" />
- <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.1.7" level="project" />
- <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.3.1-SNAPSHOT" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: com.ning.billing.commons:killbill-queue:test-jar:tests:0.2.1" level="project" />
+ <orderEntry type="library" name="Maven: com.ning.billing.plugin:killbill-plugin-api-notification:0.4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.samskivert:jmustache:1.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-java:5.1.22" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-mxj:5.0.12" level="project" />
@@ -57,7 +69,12 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-email:1.2" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.3" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.2.2" level="project" />
+ <orderEntry type="library" name="Maven: org.apache.shiro:shiro-guice:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.9.0" level="project" />
+ <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:slf4j-simple:1.7.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:3.8.1" level="project" />
util/pom.xml 29(+27 -2)
diff --git a/util/pom.xml b/util/pom.xml
index 2ca1b28..77e3017 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -12,7 +12,7 @@
<parent>
<artifactId>killbill</artifactId>
<groupId>com.ning.billing</groupId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-util</artifactId>
@@ -89,12 +89,20 @@
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-embeddeddb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
+ <artifactId>killbill-locker</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
</dependency>
<dependency>
<groupId>com.ning.billing.commons</groupId>
<artifactId>killbill-queue</artifactId>
- <version>${killbill-commons.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@@ -152,6 +160,18 @@
<artifactId>commons-email</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-ehcache</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-guice</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi</artifactId>
</dependency>
@@ -165,6 +185,11 @@
<artifactId>config-magic</artifactId>
</dependency>
<dependency>
+ <!-- For Shiro -->
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java
index 4d072d2..a6dbf20 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultTenantContext.java
@@ -24,10 +24,6 @@ public class DefaultTenantContext implements TenantContext {
private final UUID tenantId;
- public DefaultTenantContext() {
- this(null);
- }
-
public DefaultTenantContext(@Nullable final UUID tenantId) {
this.tenantId = tenantId;
}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java
index 5454264..7dacd5e 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalTenantContext.java
@@ -16,6 +16,8 @@
package com.ning.billing.util.callcontext;
+import java.util.UUID;
+
import javax.annotation.Nullable;
/**
@@ -35,8 +37,8 @@ public class InternalTenantContext {
this(defaultTenantRecordId, null);
}
- public TenantContext toTenantContext() {
- return new DefaultTenantContext();
+ public TenantContext toTenantContext(final UUID tenantId) {
+ return new DefaultTenantContext(tenantId);
}
public Long getAccountRecordId() {
diff --git a/util/src/main/java/com/ning/billing/util/config/SecurityConfig.java b/util/src/main/java/com/ning/billing/util/config/SecurityConfig.java
new file mode 100644
index 0000000..0af56b2
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/SecurityConfig.java
@@ -0,0 +1,84 @@
+/*
+ * 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.util.config;
+
+import org.skife.config.Config;
+import org.skife.config.Default;
+import org.skife.config.DefaultNull;
+import org.skife.config.Description;
+
+public interface SecurityConfig extends KillbillConfig {
+
+ @Config("killbill.security.shiroResourcePath")
+ @Default("classpath:shiro.ini")
+ @Description("Path to the shiro.ini file (classpath, url or file resource)")
+ public String getShiroResourcePath();
+
+ // LDAP Realm
+
+ @Config("killbill.security.ldap.userDnTemplate")
+ @DefaultNull
+ @Description("LDAP server's User DN format (e.g. uid={0},ou=users,dc=mycompany,dc=com)")
+ public String getShiroLDAPUserDnTemplate();
+
+ @Config("killbill.security.ldap.searchBase")
+ @DefaultNull
+ @Description("LDAP search base to use")
+ public String getShiroLDAPSearchBase();
+
+ @Config("killbill.security.ldap.groupSearchFilter")
+ @Default("memberOf=uid={0}")
+ @Description("LDAP search filter to use to find groups (e.g. memberOf=uid={0},ou=users,dc=mycompany,dc=com)")
+ public String getShiroLDAPGroupSearchFilter();
+
+ @Config("killbill.security.ldap.groupNameId")
+ @Default("memberOf")
+ @Description("Group name attribute ID in LDAP")
+ public String getShiroLDAPGroupNameID();
+
+ @Config("killbill.security.ldap.permissionsByGroup")
+ @Default("admin = *:*\n" +
+ "finance = invoice:*, payment:*\n" +
+ "support = entitlement:*, invoice:item_adjust")
+ @Description("LDAP permissions by LDAP group")
+ public String getShiroLDAPPermissionsByGroup();
+
+ @Config("killbill.security.ldap.url")
+ @Default("ldap://127.0.0.1:389")
+ @Description("LDAP server url")
+ public String getShiroLDAPUrl();
+
+ @Config("killbill.security.ldap.systemUsername")
+ @DefaultNull
+ @Description("LDAP username")
+ public String getShiroLDAPSystemUsername();
+
+ @Config("killbill.security.ldap.systemPassword")
+ @DefaultNull
+ @Description("LDAP password")
+ public String getShiroLDAPSystemPassword();
+
+ @Config("killbill.security.ldap.authenticationMechanism")
+ @Default("simple")
+ @Description("LDAP authentication mechanism (e.g. DIGEST-MD5)")
+ public String getShiroLDAPAuthenticationMechanism();
+
+ @Config("killbill.security.ldap.disableSSLCheck")
+ @Default("false")
+ @Description("Whether to ignore SSL certificates checks")
+ public boolean disableShiroLDAPSSLCheck();
+}
diff --git a/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java b/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java
index 232983e..5631dbc 100644
--- a/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java
@@ -103,6 +103,11 @@ public class DefaultNonEntityDao implements NonEntityDao {
return nonEntitySqlDao.getHistoryTargetRecordId(recordId, tableName.getTableName());
}
+ @Override
+ public UUID retrieveIdFromObject(final Long recordId, final ObjectType objectType) {
+ final TableName tableName = TableName.fromObjectType(objectType);
+ return nonEntitySqlDao.getIdFromObject(recordId, tableName.getTableName());
+ }
private interface OperationRetrieval<T> {
public T doRetrieve(final UUID objectId, final ObjectType objectType);
diff --git a/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java b/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java
index 26be4a4..58f7ae3 100644
--- a/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java
@@ -39,6 +39,8 @@ public interface NonEntityDao {
// This retrieves from the history table the latest record for which targetId matches the one we are passing
public Long retrieveLastHistoryRecordIdFromTransaction(final Long targetRecordId, final TableName tableName, final NonEntitySqlDao transactional);
- //This is the reverse from retrieveLastHistoryRecordIdFromTransaction; this retrieves the record_id of the object matching a given history row
+ // This is the reverse from retrieveLastHistoryRecordIdFromTransaction; this retrieves the record_id of the object matching a given history row
public Long retrieveHistoryTargetRecordId(final Long recordId, final TableName tableName);
+
+ public UUID retrieveIdFromObject(final Long recordId, final ObjectType objectType);
}
diff --git a/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java
index f0a119d..36d7811 100644
--- a/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java
@@ -16,6 +16,8 @@
package com.ning.billing.util.dao;
+import java.util.UUID;
+
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
@@ -30,6 +32,9 @@ public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe
public Long getRecordIdFromObject(@Bind("id") String id, @Define("tableName") final String tableName);
@SqlQuery
+ public UUID getIdFromObject(@Bind("recordId") Long recordId, @Define("tableName") final String tableName);
+
+ @SqlQuery
public Long getAccountRecordIdFromAccount(@Bind("id") String id);
@SqlQuery
diff --git a/util/src/main/java/com/ning/billing/util/glue/EhCacheManagerProvider.java b/util/src/main/java/com/ning/billing/util/glue/EhCacheManagerProvider.java
new file mode 100644
index 0000000..bb774d9
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/EhCacheManagerProvider.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.glue;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.apache.shiro.cache.ehcache.EhCacheManager;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.SecurityManager;
+
+import net.sf.ehcache.CacheManager;
+
+public class EhCacheManagerProvider implements Provider<EhCacheManager> {
+
+ private final SecurityManager securityManager;
+ private final CacheManager ehCacheCacheManager;
+
+ @Inject
+ public EhCacheManagerProvider(final SecurityManager securityManager, final CacheManager ehCacheCacheManager) {
+ this.securityManager = securityManager;
+ this.ehCacheCacheManager = ehCacheCacheManager;
+ }
+
+ @Override
+ public EhCacheManager get() {
+ final EhCacheManager shiroEhCacheManager = new EhCacheManager();
+ // Same EhCache manager instance as the rest of the system
+ shiroEhCacheManager.setCacheManager(ehCacheCacheManager);
+
+ if (securityManager instanceof DefaultSecurityManager) {
+ ((DefaultSecurityManager) securityManager).setCacheManager(shiroEhCacheManager);
+ }
+
+ return shiroEhCacheManager;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java b/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
index c0245ac..b32bce2 100644
--- a/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/GlobalLockerModule.java
@@ -16,8 +16,7 @@
package com.ning.billing.util.glue;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.MySqlGlobalLocker;
+import com.ning.billing.commons.locker.GlobalLocker;
import com.google.inject.AbstractModule;
@@ -25,6 +24,6 @@ public class GlobalLockerModule extends AbstractModule {
@Override
protected void configure() {
- bind(GlobalLocker.class).to(MySqlGlobalLocker.class).asEagerSingleton();
+ bind(GlobalLocker.class).toProvider(MySqlGlobalLockerProvider.class).asEagerSingleton();
}
}
diff --git a/util/src/main/java/com/ning/billing/util/glue/IniRealmProvider.java b/util/src/main/java/com/ning/billing/util/glue/IniRealmProvider.java
new file mode 100644
index 0000000..a124d6d
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/IniRealmProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util.glue;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.realm.text.IniRealm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.util.config.SecurityConfig;
+
+public class IniRealmProvider implements Provider<IniRealm> {
+
+ private static final Logger log = LoggerFactory.getLogger(IniRealmProvider.class);
+
+ private final SecurityConfig securityConfig;
+
+ @Inject
+ public IniRealmProvider(final SecurityConfig securityConfig) {
+ this.securityConfig = securityConfig;
+ }
+
+ @Override
+ public IniRealm get() {
+ try {
+ return new IniRealm(securityConfig.getShiroResourcePath());
+ } catch (ConfigurationException e) {
+ log.warn("Unable to configure RBAC", e);
+ return new IniRealm();
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/JDBCSessionDaoProvider.java b/util/src/main/java/com/ning/billing/util/glue/JDBCSessionDaoProvider.java
new file mode 100644
index 0000000..de5299a
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/JDBCSessionDaoProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util.glue;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.util.security.shiro.dao.JDBCSessionDao;
+
+public class JDBCSessionDaoProvider implements Provider<JDBCSessionDao> {
+
+ private final SessionManager sessionManager;
+ private final IDBI dbi;
+
+ @Inject
+ public JDBCSessionDaoProvider(final IDBI dbi, final SessionManager sessionManager) {
+ this.sessionManager = sessionManager;
+ this.dbi = dbi;
+ }
+
+ @Override
+ public JDBCSessionDao get() {
+ final JDBCSessionDao jdbcSessionDao = new JDBCSessionDao(dbi);
+
+ if (sessionManager instanceof DefaultSessionManager) {
+ ((DefaultSessionManager) sessionManager).setSessionDAO(jdbcSessionDao);
+ }
+
+ return jdbcSessionDao;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/KillBillShiroAopModule.java b/util/src/main/java/com/ning/billing/util/glue/KillBillShiroAopModule.java
new file mode 100644
index 0000000..d3611ae
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/KillBillShiroAopModule.java
@@ -0,0 +1,71 @@
+/*
+ * 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.util.glue;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import org.apache.shiro.aop.AnnotationMethodInterceptor;
+import org.apache.shiro.aop.AnnotationResolver;
+import org.apache.shiro.guice.aop.ShiroAopModule;
+
+import com.ning.billing.util.security.AnnotationHierarchicalResolver;
+import com.ning.billing.util.security.AopAllianceMethodInterceptorAdapter;
+import com.ning.billing.util.security.PermissionAnnotationHandler;
+import com.ning.billing.util.security.PermissionAnnotationMethodInterceptor;
+
+import com.google.inject.matcher.AbstractMatcher;
+import com.google.inject.matcher.Matchers;
+
+// Provides authentication via Shiro
+public class KillBillShiroAopModule extends ShiroAopModule {
+
+ private final AnnotationHierarchicalResolver resolver = new AnnotationHierarchicalResolver();
+
+ @Override
+ protected AnnotationResolver createAnnotationResolver() {
+ return resolver;
+ }
+
+ @Override
+ protected void configureInterceptors(final AnnotationResolver resolver) {
+ super.configureInterceptors(resolver);
+
+ if (!KillBillShiroModule.isRBACEnabled()) {
+ return;
+ }
+
+ final PermissionAnnotationHandler permissionAnnotationHandler = new PermissionAnnotationHandler();
+ // Inject the Security API
+ requestInjection(permissionAnnotationHandler);
+
+ final PermissionAnnotationMethodInterceptor methodInterceptor = new PermissionAnnotationMethodInterceptor(permissionAnnotationHandler, resolver);
+ bindShiroInterceptorWithHierarchy(methodInterceptor);
+ }
+
+ // Similar to bindShiroInterceptor but will look for annotations in the class hierarchy
+ protected final void bindShiroInterceptorWithHierarchy(final AnnotationMethodInterceptor methodInterceptor) {
+ bindInterceptor(Matchers.any(),
+ new AbstractMatcher<Method>() {
+ public boolean matches(final Method method) {
+ final Class<? extends Annotation> annotation = methodInterceptor.getHandler().getAnnotationClass();
+ return resolver.getAnnotationFromMethod(method, annotation) != null;
+ }
+ },
+ new AopAllianceMethodInterceptorAdapter(methodInterceptor));
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/KillBillShiroModule.java b/util/src/main/java/com/ning/billing/util/glue/KillBillShiroModule.java
new file mode 100644
index 0000000..ee99ac1
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/KillBillShiroModule.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.glue;
+
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.guice.ShiroModule;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionManager;
+
+import com.ning.billing.util.security.shiro.dao.JDBCSessionDao;
+import com.ning.billing.util.security.shiro.realm.KillBillJndiLdapRealm;
+
+import com.google.inject.binder.AnnotatedBindingBuilder;
+
+// For Kill Bill library only.
+// See com.ning.billing.server.modules.KillBillShiroWebModule for Kill Bill server.
+public class KillBillShiroModule extends ShiroModule {
+
+ public static final String KILLBILL_LDAP_PROPERTY = "killbill.server.ldap";
+ public static final String KILLBILL_RBAC_PROPERTY = "killbill.server.rbac";
+
+ public static boolean isLDAPEnabled() {
+ return Boolean.parseBoolean(System.getProperty(KILLBILL_LDAP_PROPERTY, "false"));
+ }
+
+ public static boolean isRBACEnabled() {
+ return Boolean.parseBoolean(System.getProperty(KILLBILL_RBAC_PROPERTY, "true"));
+ }
+
+ protected void configureShiro() {
+ bindRealm().toProvider(IniRealmProvider.class).asEagerSingleton();
+
+ if (isLDAPEnabled()) {
+ bindRealm().to(KillBillJndiLdapRealm.class).asEagerSingleton();
+ }
+ }
+
+ @Override
+ protected void bindSecurityManager(final AnnotatedBindingBuilder<? super SecurityManager> bind) {
+ super.bindSecurityManager(bind);
+
+ // Magic provider to configure the cache manager
+ bind(CacheManager.class).toProvider(EhCacheManagerProvider.class).asEagerSingleton();
+ }
+
+ @Override
+ protected void bindSessionManager(final AnnotatedBindingBuilder<SessionManager> bind) {
+ bind.to(DefaultSessionManager.class).asEagerSingleton();
+
+ // Magic provider to configure the session DAO
+ bind(JDBCSessionDao.class).toProvider(JDBCSessionDaoProvider.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/SecurityModule.java b/util/src/main/java/com/ning/billing/util/glue/SecurityModule.java
new file mode 100644
index 0000000..a8ea01a
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/SecurityModule.java
@@ -0,0 +1,61 @@
+/*
+ * 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.util.glue;
+
+import org.skife.config.ConfigSource;
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.config.SimplePropertyConfigSource;
+
+import com.ning.billing.security.api.SecurityApi;
+import com.ning.billing.util.config.SecurityConfig;
+import com.ning.billing.util.security.api.DefaultSecurityApi;
+import com.ning.billing.util.security.api.DefaultSecurityService;
+import com.ning.billing.util.security.api.SecurityService;
+
+import com.google.inject.AbstractModule;
+
+public class SecurityModule extends AbstractModule {
+
+ private final ConfigSource configSource;
+
+ public SecurityModule() {
+ this(new SimplePropertyConfigSource(System.getProperties()));
+ }
+
+ public SecurityModule(final ConfigSource configSource) {
+ this.configSource = configSource;
+ }
+
+ public void configure() {
+ installConfig();
+ installSecurityApi();
+ installSecurityService();
+ }
+
+ private void installConfig() {
+ final SecurityConfig securityConfig = new ConfigurationObjectFactory(configSource).build(SecurityConfig.class);
+ bind(SecurityConfig.class).toInstance(securityConfig);
+ }
+
+ private void installSecurityApi() {
+ bind(SecurityApi.class).to(DefaultSecurityApi.class).asEagerSingleton();
+ }
+
+ protected void installSecurityService() {
+ bind(SecurityService.class).to(DefaultSecurityService.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/AnnotationHierarchicalResolver.java b/util/src/main/java/com/ning/billing/util/security/AnnotationHierarchicalResolver.java
new file mode 100644
index 0000000..0f7b563
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/AnnotationHierarchicalResolver.java
@@ -0,0 +1,130 @@
+/*
+ * 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.util.security;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.shiro.aop.AnnotationResolver;
+import org.apache.shiro.aop.MethodInvocation;
+
+public class AnnotationHierarchicalResolver implements AnnotationResolver {
+
+ @Override
+ public Annotation getAnnotation(final MethodInvocation mi, final Class<? extends Annotation> clazz) {
+ return getAnnotationFromMethod(mi.getMethod(), clazz);
+ }
+
+ public Annotation getAnnotationFromMethod(final Method method, final Class<? extends Annotation> clazz) {
+ return findAnnotation(method, clazz);
+ }
+
+ // The following comes from spring-core (AnnotationUtils) to handle annotations on interfaces
+
+ /**
+ * Get a single {@link Annotation} of <code>annotationType</code> from the supplied {@link java.lang.reflect.Method},
+ * traversing its super methods if no annotation can be found on the given method itself.
+ * <p>Annotations on methods are not inherited by default, so we need to handle this explicitly.
+ *
+ * @param method the method to look for annotations on
+ * @param annotationType the annotation class to look for
+ * @return the annotation found, or <code>null</code> if none found
+ */
+ public static <A extends Annotation> A findAnnotation(final Method method, final Class<A> annotationType) {
+ A annotation = getAnnotation(method, annotationType);
+ Class<?> cl = method.getDeclaringClass();
+ if (annotation == null) {
+ annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
+ }
+ while (annotation == null) {
+ cl = cl.getSuperclass();
+ if (cl == null || cl == Object.class) {
+ break;
+ }
+ try {
+ final Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes());
+ annotation = getAnnotation(equivalentMethod, annotationType);
+ if (annotation == null) {
+ annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
+ }
+ } catch (NoSuchMethodException ex) {
+ // We're done...
+ }
+ }
+ return annotation;
+ }
+
+ /**
+ * Get a single {@link Annotation} of <code>annotationType</code> from the supplied {@link Method}.
+ *
+ * @param method the method to look for annotations on
+ * @param annotationType the annotation class to look for
+ * @return the annotations found
+ */
+ public static <A extends Annotation> A getAnnotation(final Method method, final Class<A> annotationType) {
+ A ann = method.getAnnotation(annotationType);
+ if (ann == null) {
+ for (final Annotation metaAnn : method.getAnnotations()) {
+ ann = metaAnn.annotationType().getAnnotation(annotationType);
+ if (ann != null) {
+ break;
+ }
+ }
+ }
+ return ann;
+ }
+
+ private static <A extends Annotation> A searchOnInterfaces(final Method method, final Class<A> annotationType, final Class<?>[] ifcs) {
+ A annotation = null;
+ for (final Class<?> iface : ifcs) {
+ if (isInterfaceWithAnnotatedMethods(iface)) {
+ try {
+ final Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
+ annotation = getAnnotation(equivalentMethod, annotationType);
+ } catch (NoSuchMethodException ex) {
+ // Skip this interface - it doesn't have the method...
+ }
+ if (annotation != null) {
+ break;
+ }
+ }
+ }
+ return annotation;
+ }
+
+ private static final Map<Class<?>, Boolean> annotatedInterfaceCache = new WeakHashMap<Class<?>, Boolean>();
+
+ private static boolean isInterfaceWithAnnotatedMethods(final Class<?> iface) {
+ synchronized (annotatedInterfaceCache) {
+ final Boolean flag = annotatedInterfaceCache.get(iface);
+ if (flag != null) {
+ return flag;
+ }
+ boolean found = false;
+ for (final Method ifcMethod : iface.getMethods()) {
+ if (ifcMethod.getAnnotations().length > 0) {
+ found = true;
+ break;
+ }
+ }
+ annotatedInterfaceCache.put(iface, found);
+ return found;
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/AopAllianceMethodInvocationAdapter.java b/util/src/main/java/com/ning/billing/util/security/AopAllianceMethodInvocationAdapter.java
new file mode 100644
index 0000000..1b93956
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/AopAllianceMethodInvocationAdapter.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.security;
+
+import java.lang.reflect.Method;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+// Taken from Shiro - the original class is private :(
+public class AopAllianceMethodInvocationAdapter implements org.apache.shiro.aop.MethodInvocation {
+
+ private final MethodInvocation mi;
+
+ public AopAllianceMethodInvocationAdapter(final MethodInvocation mi) {
+ this.mi = mi;
+ }
+
+ public Method getMethod() {
+ return mi.getMethod();
+ }
+
+ public Object[] getArguments() {
+ return mi.getArguments();
+ }
+
+ public String toString() {
+ return "Method invocation [" + mi.getMethod() + "]";
+ }
+
+ public Object proceed() throws Throwable {
+ return mi.proceed();
+ }
+
+ public Object getThis() {
+ return mi.getThis();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityApi.java b/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityApi.java
new file mode 100644
index 0000000..efddf40
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityApi.java
@@ -0,0 +1,103 @@
+/*
+ * 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.util.security.api;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.subject.Subject;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.security.Logical;
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.SecurityApiException;
+import com.ning.billing.security.api.SecurityApi;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.Lists;
+
+public class DefaultSecurityApi implements SecurityApi {
+
+ private static final String[] allPermissions = new String[Permission.values().length];
+
+ @Override
+ public Set<Permission> getCurrentUserPermissions(final TenantContext context) {
+ final Permission[] killbillPermissions = Permission.values();
+ final String[] killbillPermissionsString = getAllPermissionsAsStrings();
+
+ final Subject subject = SecurityUtils.getSubject();
+ // Bulk (optimized) call
+ final boolean[] permissions = subject.isPermitted(killbillPermissionsString);
+
+ final Set<Permission> userPermissions = new HashSet<Permission>();
+ for (int i = 0; i < permissions.length; i++) {
+ if (permissions[i]) {
+ userPermissions.add(killbillPermissions[i]);
+ }
+ }
+
+ return userPermissions;
+ }
+
+ @Override
+ public void checkCurrentUserPermissions(final List<Permission> permissions, final Logical logical, final TenantContext context) throws SecurityApiException {
+ final String[] permissionsString = Lists.<Permission, String>transform(permissions, Functions.toStringFunction()).toArray(new String[permissions.size()]);
+
+ try {
+ final Subject subject = SecurityUtils.getSubject();
+ if (permissionsString.length == 1) {
+ subject.checkPermission(permissionsString[0]);
+ } else if (Logical.AND.equals(logical)) {
+ subject.checkPermissions(permissionsString);
+ } else if (Logical.OR.equals(logical)) {
+ boolean hasAtLeastOnePermission = false;
+ for (final String permission : permissionsString) {
+ if (subject.isPermitted(permission)) {
+ hasAtLeastOnePermission = true;
+ break;
+ }
+ }
+
+ // Cause the exception if none match
+ if (!hasAtLeastOnePermission) {
+ subject.checkPermission(permissionsString[0]);
+ }
+ }
+ } catch (AuthorizationException e) {
+ throw new SecurityApiException(e, ErrorCode.SECURITY_NOT_ENOUGH_PERMISSIONS);
+ }
+ }
+
+ private String[] getAllPermissionsAsStrings() {
+ if (allPermissions[0] == null) {
+ synchronized (allPermissions) {
+ if (allPermissions[0] == null) {
+ final Permission[] killbillPermissions = Permission.values();
+ for (int i = 0; i < killbillPermissions.length; i++) {
+ allPermissions[i] = killbillPermissions[i].toString();
+ }
+ }
+ }
+ }
+
+ return allPermissions;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityService.java b/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityService.java
new file mode 100644
index 0000000..9b92a65
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/api/DefaultSecurityService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util.security.api;
+
+import javax.inject.Inject;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.SecurityManager;
+
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
+
+public class DefaultSecurityService implements SecurityService {
+
+ public static final String SECURITY_SERVICE_NAME = "security-service";
+
+ private final SecurityManager securityManager;
+
+ @Inject
+ public DefaultSecurityService(final SecurityManager securityManager) {
+ this.securityManager = securityManager;
+ }
+
+ @Override
+ public String getName() {
+ return SECURITY_SERVICE_NAME;
+ }
+
+ @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.INIT_SERVICE)
+ public void initialize() {
+ SecurityUtils.setSecurityManager(securityManager);
+ }
+
+ @LifecycleHandlerType(LifecycleLevel.STOP_SERVICE)
+ public void stop() {
+ SecurityUtils.setSecurityManager(null);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/PermissionAnnotationHandler.java b/util/src/main/java/com/ning/billing/util/security/PermissionAnnotationHandler.java
new file mode 100644
index 0000000..88551ab
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/PermissionAnnotationHandler.java
@@ -0,0 +1,67 @@
+package com.ning.billing.util.security;
+
+/*
+ * 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.
+ */
+
+import java.lang.annotation.Annotation;
+
+import javax.inject.Inject;
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
+
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.RequiresPermissions;
+import com.ning.billing.security.SecurityApiException;
+import com.ning.billing.security.api.SecurityApi;
+import com.ning.billing.util.callcontext.DefaultTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.common.collect.ImmutableList;
+
+public class PermissionAnnotationHandler extends AuthorizingAnnotationHandler {
+
+ private final TenantContext context = new DefaultTenantContext(null);
+
+ @Inject
+ SecurityApi securityApi;
+
+ public PermissionAnnotationHandler() {
+ super(RequiresPermissions.class);
+ }
+
+ public void assertAuthorized(final Annotation annotation) throws AuthorizationException {
+ if (!(annotation instanceof RequiresPermissions)) {
+ return;
+ }
+
+ final RequiresPermissions requiresPermissions = (RequiresPermissions) annotation;
+ try {
+ securityApi.checkCurrentUserPermissions(ImmutableList.<Permission>copyOf(requiresPermissions.value()), requiresPermissions.logical(), context);
+ } catch (SecurityApiException e) {
+ if (e.getCause() != null && e.getCause() instanceof AuthorizationException) {
+ throw (AuthorizationException) e.getCause();
+ } else if (e.getCause() != null) {
+ throw new AuthorizationException(e.getCause());
+ } else {
+ throw new AuthorizationException(e);
+ }
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionDao.java b/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionDao.java
new file mode 100644
index 0000000..3dbec52
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionDao.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util.security.shiro.dao;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import javax.inject.Inject;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+
+public class JDBCSessionDao extends CachingSessionDAO {
+
+ private static final Logger log = LoggerFactory.getLogger(JDBCSessionDao.class);
+
+ private JDBCSessionSqlDao jdbcSessionSqlDao;
+
+ @Inject
+ public JDBCSessionDao(final IDBI dbi) {
+ if (dbi instanceof DBI) {
+ // TODO PIERRE Move to DBIProvider, once it's in util
+ ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+ }
+ this.jdbcSessionSqlDao = dbi.onDemand(JDBCSessionSqlDao.class);
+ }
+
+ @Override
+ protected void doUpdate(final Session session) {
+ jdbcSessionSqlDao.update(new SessionModelDao(session));
+ }
+
+ @Override
+ protected void doDelete(final Session session) {
+ jdbcSessionSqlDao.delete(new SessionModelDao(session));
+ }
+
+ @Override
+ protected Serializable doCreate(final Session session) {
+ final Serializable sessionId = jdbcSessionSqlDao.inTransaction(new Transaction<Long, JDBCSessionSqlDao>() {
+ @Override
+ public Long inTransaction(final JDBCSessionSqlDao transactional, final TransactionStatus status) throws Exception {
+ transactional.create(new SessionModelDao(session));
+ return transactional.getLastInsertId();
+ }
+ });
+ assignSessionId(session, sessionId);
+ return sessionId;
+ }
+
+ @Override
+ protected Session doReadSession(final Serializable sessionId) {
+ final SessionModelDao sessionModelDao = jdbcSessionSqlDao.read(sessionId);
+ if (sessionModelDao == null) {
+ return null;
+ }
+
+ try {
+ return sessionModelDao.toSimpleSession();
+ } catch (IOException e) {
+ log.warn("Corrupted cookie", e);
+ return null;
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.java b/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
new file mode 100644
index 0000000..cdd8e0a
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
@@ -0,0 +1,46 @@
+/*
+ * 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.util.security.shiro.dao;
+
+import java.io.Serializable;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;
+
+import com.ning.billing.commons.jdbi.binder.SmartBindBean;
+
+@UseStringTemplate3StatementLocator
+public interface JDBCSessionSqlDao extends Transactional<JDBCSessionSqlDao> {
+
+ @SqlQuery
+ public SessionModelDao read(@Bind("recordId") final Serializable sessionId);
+
+ @SqlUpdate
+ public void create(@SmartBindBean final SessionModelDao sessionModelDao);
+
+ @SqlUpdate
+ public void update(@SmartBindBean final SessionModelDao sessionModelDao);
+
+ @SqlUpdate
+ public void delete(@SmartBindBean final SessionModelDao sessionModelDao);
+
+ @SqlQuery
+ public Long getLastInsertId();
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/shiro/dao/SessionModelDao.java b/util/src/main/java/com/ning/billing/util/security/shiro/dao/SessionModelDao.java
new file mode 100644
index 0000000..30602b2
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/shiro/dao/SessionModelDao.java
@@ -0,0 +1,161 @@
+/*
+ * 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.util.security.shiro.dao;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.shiro.io.DefaultSerializer;
+import org.apache.shiro.io.Serializer;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SimpleSession;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+public class SessionModelDao {
+
+ private final Serializer<Map> serializer = new DefaultSerializer<Map>();
+
+ private Long recordId;
+ private DateTime startTimestamp;
+ private DateTime lastAccessTime;
+ private long timeout;
+ private String host;
+ private byte[] sessionData;
+
+ public SessionModelDao() { /* For the DAO mapper */ }
+
+ public SessionModelDao(final Session session) {
+ this.recordId = (Long) session.getId();
+ this.startTimestamp = new DateTime(session.getStartTimestamp(), DateTimeZone.UTC);
+ this.lastAccessTime = new DateTime(session.getLastAccessTime(), DateTimeZone.UTC);
+ this.timeout = session.getTimeout();
+ this.host = session.getHost();
+ try {
+ this.sessionData = serializeSessionData(session);
+ } catch (IOException e) {
+ this.sessionData = new byte[]{};
+ }
+ }
+
+ public Session toSimpleSession() throws IOException {
+ final SimpleSession simpleSession = new SimpleSession();
+ simpleSession.setId(recordId);
+ simpleSession.setStartTimestamp(startTimestamp.toDate());
+ simpleSession.setLastAccessTime(lastAccessTime.toDate());
+ simpleSession.setTimeout(timeout);
+ simpleSession.setHost(host);
+
+ final Map attributes = serializer.deserialize(sessionData);
+ //noinspection unchecked
+ simpleSession.setAttributes(attributes);
+
+ return simpleSession;
+ }
+
+ public Long getRecordId() {
+ return recordId;
+ }
+
+ public DateTime getStartTimestamp() {
+ return startTimestamp;
+ }
+
+ public DateTime getLastAccessTime() {
+ return lastAccessTime;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public byte[] getSessionData() {
+ return sessionData;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("SessionModelDao{");
+ sb.append("recordId=").append(recordId);
+ sb.append(", startTimestamp=").append(startTimestamp);
+ sb.append(", lastAccessTime=").append(lastAccessTime);
+ sb.append(", timeout=").append(timeout);
+ sb.append(", host='").append(host).append('\'');
+ sb.append(", sessionData=").append(Arrays.toString(sessionData));
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final SessionModelDao that = (SessionModelDao) o;
+
+ if (timeout != that.timeout) {
+ return false;
+ }
+ if (host != null ? !host.equals(that.host) : that.host != null) {
+ return false;
+ }
+ if (lastAccessTime != null ? !lastAccessTime.equals(that.lastAccessTime) : that.lastAccessTime != null) {
+ return false;
+ }
+ if (recordId != null ? !recordId.equals(that.recordId) : that.recordId != null) {
+ return false;
+ }
+ if (!Arrays.equals(sessionData, that.sessionData)) {
+ return false;
+ }
+ if (startTimestamp != null ? !startTimestamp.equals(that.startTimestamp) : that.startTimestamp != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = recordId != null ? recordId.hashCode() : 0;
+ result = 31 * result + (startTimestamp != null ? startTimestamp.hashCode() : 0);
+ result = 31 * result + (lastAccessTime != null ? lastAccessTime.hashCode() : 0);
+ result = 31 * result + (int) (timeout ^ (timeout >>> 32));
+ result = 31 * result + (host != null ? host.hashCode() : 0);
+ result = 31 * result + (sessionData != null ? Arrays.hashCode(sessionData) : 0);
+ return result;
+ }
+
+ private byte[] serializeSessionData(final Session session) throws IOException {
+ final Map<Object, Object> sessionAttributes = new HashMap<Object, Object>();
+ for (final Object key : session.getAttributeKeys()) {
+ sessionAttributes.put(key, session.getAttribute(key));
+ }
+
+ return serializer.serialize(sessionAttributes);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/shiro/realm/KillBillJndiLdapRealm.java b/util/src/main/java/com/ning/billing/util/security/shiro/realm/KillBillJndiLdapRealm.java
new file mode 100644
index 0000000..a4eb644
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/shiro/realm/KillBillJndiLdapRealm.java
@@ -0,0 +1,222 @@
+/*
+ * 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.util.security.shiro.realm;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.config.Ini.Section;
+import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
+import org.apache.shiro.realm.ldap.JndiLdapRealm;
+import org.apache.shiro.realm.ldap.LdapContextFactory;
+import org.apache.shiro.realm.ldap.LdapUtils;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.util.config.SecurityConfig;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+
+public class KillBillJndiLdapRealm extends JndiLdapRealm {
+
+ private static final Logger log = LoggerFactory.getLogger(KillBillJndiLdapRealm.class);
+
+ private static final String USERDN_SUBSTITUTION_TOKEN = "{0}";
+
+ private static final SearchControls SUBTREE_SCOPE = new SearchControls();
+
+ static {
+ SUBTREE_SCOPE.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ }
+
+ private static final Splitter SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
+
+ private final String searchBase;
+ private final String groupSearchFilter;
+ private final String groupNameId;
+ private final Map<String, Collection<String>> permissionsByGroup = Maps.newLinkedHashMap();
+
+ @Inject
+ public KillBillJndiLdapRealm(final SecurityConfig securityConfig) {
+ super();
+
+ if (securityConfig.getShiroLDAPUserDnTemplate() != null) {
+ setUserDnTemplate(securityConfig.getShiroLDAPUserDnTemplate());
+ }
+
+ final JndiLdapContextFactory contextFactory = (JndiLdapContextFactory) getContextFactory();
+ if (securityConfig.disableShiroLDAPSSLCheck()) {
+ contextFactory.getEnvironment().put("java.naming.ldap.factory.socket", SkipSSLCheckSocketFactory.class.getName());
+ }
+ if (securityConfig.getShiroLDAPUrl() != null) {
+ contextFactory.setUrl(securityConfig.getShiroLDAPUrl());
+ }
+ if (securityConfig.getShiroLDAPSystemUsername() != null) {
+ contextFactory.setSystemUsername(securityConfig.getShiroLDAPSystemUsername());
+ }
+ if (securityConfig.getShiroLDAPSystemPassword() != null) {
+ contextFactory.setSystemPassword(securityConfig.getShiroLDAPSystemPassword());
+ }
+ if (securityConfig.getShiroLDAPAuthenticationMechanism() != null) {
+ contextFactory.setAuthenticationMechanism(securityConfig.getShiroLDAPAuthenticationMechanism());
+ }
+ setContextFactory(contextFactory);
+
+ searchBase = securityConfig.getShiroLDAPSearchBase();
+ groupSearchFilter = securityConfig.getShiroLDAPGroupSearchFilter();
+ groupNameId = securityConfig.getShiroLDAPGroupNameID();
+
+ if (securityConfig.getShiroLDAPPermissionsByGroup() != null) {
+ final Ini ini = new Ini();
+ ini.load(securityConfig.getShiroLDAPPermissionsByGroup());
+ for (final Section section : ini.getSections()) {
+ for (final String role : section.keySet()) {
+ final Collection<String> permissions = ImmutableList.<String>copyOf(SPLITTER.split(section.get(role)));
+ permissionsByGroup.put(role, permissions);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected AuthorizationInfo queryForAuthorizationInfo(final PrincipalCollection principals, final LdapContextFactory ldapContextFactory) throws NamingException {
+ final Set<String> userGroups = findLDAPGroupsForUser(principals, ldapContextFactory);
+
+ final SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(userGroups);
+ final Set<String> stringPermissions = groupsPermissions(userGroups);
+ simpleAuthorizationInfo.setStringPermissions(stringPermissions);
+
+ return simpleAuthorizationInfo;
+ }
+
+ private Set<String> findLDAPGroupsForUser(final PrincipalCollection principals, final LdapContextFactory ldapContextFactory) throws NamingException {
+ final String username = (String) getAvailablePrincipal(principals);
+
+ LdapContext systemLdapCtx = null;
+ try {
+ systemLdapCtx = ldapContextFactory.getSystemLdapContext();
+ return findLDAPGroupsForUser(username, systemLdapCtx);
+ } catch (AuthenticationException ex) {
+ log.info("LDAP authentication exception: " + ex.getLocalizedMessage());
+ return ImmutableSet.<String>of();
+ } finally {
+ LdapUtils.closeContext(systemLdapCtx);
+ }
+ }
+
+ private Set<String> findLDAPGroupsForUser(final String userName, final LdapContext ldapCtx) throws NamingException {
+ final NamingEnumeration<SearchResult> foundGroups = ldapCtx.search(searchBase,
+ groupSearchFilter.replace(USERDN_SUBSTITUTION_TOKEN, userName),
+ SUBTREE_SCOPE);
+
+ // Extract the name of all the groups
+ final Iterator<SearchResult> groupsIterator = Iterators.<SearchResult>forEnumeration(foundGroups);
+ final Iterator<String> groupsNameIterator = Iterators.<SearchResult, String>transform(groupsIterator,
+ new Function<SearchResult, String>() {
+ @Override
+ public String apply(final SearchResult groupEntry) {
+ return extractGroupNameFromSearchResult(groupEntry);
+ }
+ });
+ final Iterator<String> finalGroupsNameIterator = Iterators.<String>filter(groupsNameIterator, Predicates.notNull());
+
+ return Sets.newHashSet(finalGroupsNameIterator);
+ }
+
+ private String extractGroupNameFromSearchResult(final SearchResult searchResult) {
+ // Get all attributes for that group
+ final Iterator<? extends Attribute> attributesIterator = Iterators.forEnumeration(searchResult.getAttributes().getAll());
+
+ // Find the attribute representing the group name
+ final Iterator<? extends Attribute> groupNameAttributesIterator = Iterators.filter(attributesIterator,
+ new Predicate<Attribute>() {
+ @Override
+ public boolean apply(final Attribute attribute) {
+ return groupNameId.equalsIgnoreCase(attribute.getID());
+ }
+ });
+
+ // Extract the group name from the attribute
+ // Note: at this point, groupNameAttributesIterator should really contain a single element
+ final Iterator<String> groupNamesIterator = Iterators.transform(groupNameAttributesIterator,
+ new Function<Attribute, String>() {
+ @Override
+ public String apply(final Attribute groupNameAttribute) {
+ try {
+ final NamingEnumeration<?> enumeration = groupNameAttribute.getAll();
+ if (enumeration.hasMore()) {
+ return enumeration.next().toString();
+ } else {
+ return null;
+ }
+ } catch (NamingException namingException) {
+ log.warn("Unable to read group name", namingException);
+ return null;
+ }
+ }
+ });
+ final Iterator<String> finalGroupNamesIterator = Iterators.<String>filter(groupNamesIterator, Predicates.notNull());
+
+ if (finalGroupNamesIterator.hasNext()) {
+ return finalGroupNamesIterator.next();
+ } else {
+ log.warn("Unable to find an attribute matching {}", groupNameId);
+ return null;
+ }
+ }
+
+ private Set<String> groupsPermissions(final Set<String> groups) {
+ final Set<String> permissions = new HashSet<String>();
+ for (final String group : groups) {
+ final Collection<String> permissionsForGroup = permissionsByGroup.get(group);
+ if (permissionsForGroup != null) {
+ permissions.addAll(permissionsForGroup);
+ }
+ }
+ return permissions;
+ }
+
+ @VisibleForTesting
+ public Map<String, Collection<String>> getPermissionsByGroup() {
+ return permissionsByGroup;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/security/shiro/realm/SkipSSLCheckSocketFactory.java b/util/src/main/java/com/ning/billing/util/security/shiro/realm/SkipSSLCheckSocketFactory.java
new file mode 100644
index 0000000..d8580e8
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/security/shiro/realm/SkipSSLCheckSocketFactory.java
@@ -0,0 +1,78 @@
+/*
+ * 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.util.security.shiro.realm;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SkipSSLCheckSocketFactory extends SocketFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(SkipSSLCheckSocketFactory.class);
+
+ private static SocketFactory skipSSLCheckFactory = null;
+
+ static {
+ final TrustManager[] noOpTrustManagers = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() { return null; }
+
+ public void checkClientTrusted(X509Certificate[] c, String a) { }
+
+ public void checkServerTrusted(X509Certificate[] c, String a) { }
+ }};
+
+ try {
+ final SSLContext context = SSLContext.getInstance("SSL");
+ context.init(null, noOpTrustManagers, new SecureRandom());
+ skipSSLCheckFactory = context.getSocketFactory();
+ } catch (GeneralSecurityException e) {
+ log.warn("SSL exception", e);
+ }
+ }
+
+ public static SocketFactory getDefault() {
+ return new SkipSSLCheckSocketFactory();
+ }
+
+ public Socket createSocket(final String arg0, final int arg1) throws IOException {
+ return skipSSLCheckFactory.createSocket(arg0, arg1);
+ }
+
+ public Socket createSocket(final InetAddress arg0, final int arg1) throws IOException {
+ return skipSSLCheckFactory.createSocket(arg0, arg1);
+ }
+
+ public Socket createSocket(final String arg0, final int arg1, final InetAddress arg2, final int arg3) throws IOException {
+ return skipSSLCheckFactory.createSocket(arg0, arg1, arg2, arg3);
+ }
+
+ public Socket createSocket(final InetAddress arg0, final int arg1, final InetAddress arg2, final int arg3) throws IOException {
+ return skipSSLCheckFactory.createSocket(arg0, arg1, arg2, arg3);
+ }
+}
diff --git a/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg
index 3e11edb..1969615 100644
--- a/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg
@@ -8,6 +8,14 @@ where id = :id
;
>>
+getIdFromObject(tableName) ::= <<
+select
+ id
+from <tableName>
+where record_id = :recordId
+;
+>>
+
getAccountRecordIdFromAccountHistory() ::= <<
select
target_record_id
diff --git a/util/src/main/resources/com/ning/billing/util/ddl.sql b/util/src/main/resources/com/ning/billing/util/ddl.sql
index d0b48cd..b586ec2 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -224,3 +224,13 @@ DROP TABLE IF EXISTS notifications;
search_key2 int(11) unsigned default null,
PRIMARY KEY(record_id)
);
+
+create table sessions (
+ record_id int(11) unsigned not null auto_increment
+, start_timestamp datetime not null
+, last_access_time datetime default null
+, timeout int(11)
+, host varchar(100) default null
+, session_data mediumblob default null
+, primary key(record_id)
+);
\ No newline at end of file
diff --git a/util/src/main/resources/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
new file mode 100644
index 0000000..fe228d2
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
@@ -0,0 +1,51 @@
+group JDBCSessionSqlDao;
+
+read() ::= <<
+select
+ record_id
+, start_timestamp
+, last_access_time
+, timeout
+, host
+, session_data
+from sessions
+where record_id = :recordId
+;
+>>
+
+create() ::= <<
+insert into sessions (
+ start_timestamp
+, last_access_time
+, timeout
+, host
+, session_data
+) values (
+ :startTimestamp
+, :lastAccessTime
+, :timeout
+, :host
+, :sessionData
+);
+>>
+
+update() ::= <<
+update sessions set
+ start_timestamp = :startTimestamp
+, last_access_time = :lastAccessTime
+, timeout = :timeout
+, host = :host
+, session_data = :sessionData
+where record_id = :recordId
+;
+>>
+
+delete() ::= <<
+delete from sessions
+where record_id = :recordId
+;
+>>
+
+getLastInsertId() ::= <<
+select LAST_INSERT_ID();
+>>
diff --git a/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java b/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java
index 4444bdf..3bb80f9 100644
--- a/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java
+++ b/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java
@@ -52,4 +52,9 @@ public class MockNonEntityDao implements NonEntityDao {
public Long retrieveHistoryTargetRecordId(final Long recordId, final TableName tableName) {
return null;
}
+
+ @Override
+ public UUID retrieveIdFromObject(final Long recordId, final ObjectType objectType) {
+ return null;
+ }
}
diff --git a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
index a54ee30..824e50e 100644
--- a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
+++ b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
@@ -16,8 +16,6 @@
package com.ning.billing.dbi;
-import java.util.concurrent.TimeUnit;
-
import javax.sql.DataSource;
import org.skife.jdbi.v2.DBI;
@@ -39,24 +37,15 @@ import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DBIProvider implements Provider<IDBI> {
- private final String jdbcUri;
- private final String userName;
- private final String userPwd;
+ private final DataSource ds;
@Inject
- public DBIProvider(final DbiConfig config) {
- this(config.getJdbcUrl(), config.getUsername(), config.getPassword());
- }
-
- public DBIProvider(final String jdbcUri, final String userName, final String userPwd) {
- this.jdbcUri = jdbcUri;
- this.userName = userName;
- this.userPwd = userPwd;
+ public DBIProvider(final DataSource ds) {
+ this.ds = ds;
}
@Override
public IDBI get() {
- final DataSource ds = getC3P0DataSource();
final DBI dbi = new DBI(ds);
dbi.registerArgumentFactory(new UUIDArgumentFactory());
dbi.registerArgumentFactory(new DateTimeZoneArgumentFactory());
@@ -72,29 +61,4 @@ public class DBIProvider implements Provider<IDBI> {
return dbi;
}
-
-
-
- private DataSource getBoneCPDatSource() {
- final BoneCPConfig dbConfig = new BoneCPConfig();
- dbConfig.setJdbcUrl(jdbcUri);
- dbConfig.setUsername(userName);
- dbConfig.setPassword(userPwd);
- dbConfig.setPartitionCount(1);
- //dbConfig.setDefaultTransactionIsolation("READ_COMMITTED");
- dbConfig.setDisableJMX(false);
-
- final BoneCPDataSource ds = new BoneCPDataSource(dbConfig);
- return ds;
- }
-
- private DataSource getC3P0DataSource() {
- ComboPooledDataSource cpds = new ComboPooledDataSource();
- cpds.setJdbcUrl(jdbcUri);
- cpds.setUser(userName);
- cpds.setPassword(userPwd);
- cpds.setMinPoolSize(1);
- cpds.setMaxPoolSize(10);
- return cpds;
- }
}
diff --git a/util/src/test/java/com/ning/billing/GuicyKillbillTestNoDBModule.java b/util/src/test/java/com/ning/billing/GuicyKillbillTestNoDBModule.java
index 265f94e..77adf8d 100644
--- a/util/src/test/java/com/ning/billing/GuicyKillbillTestNoDBModule.java
+++ b/util/src/test/java/com/ning/billing/GuicyKillbillTestNoDBModule.java
@@ -16,20 +16,11 @@
package com.ning.billing;
-
import org.mockito.Mockito;
import org.skife.jdbi.v2.IDBI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.ning.billing.dbi.DBTestingHelper;
-import com.ning.billing.dbi.H2TestingHelper;
-import com.ning.billing.dbi.MysqlTestingHelper;
public class GuicyKillbillTestNoDBModule extends GuicyKillbillTestModule {
- private final static Logger log = LoggerFactory.getLogger(GuicyKillbillTestNoDBModule.class);
-
private void installDBI() {
final IDBI idbi = Mockito.mock(IDBI.class);
bind(IDBI.class).toInstance(idbi);
diff --git a/util/src/test/java/com/ning/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java b/util/src/test/java/com/ning/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
index cfc6f22..1ac9403 100644
--- a/util/src/test/java/com/ning/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
+++ b/util/src/test/java/com/ning/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
@@ -17,6 +17,7 @@
package com.ning.billing;
import javax.inject.Inject;
+import javax.sql.DataSource;
import org.skife.jdbi.v2.IDBI;
import org.slf4j.Logger;
@@ -25,34 +26,30 @@ import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
-import com.ning.billing.dbi.DBTestingHelper;
+import com.ning.billing.commons.embeddeddb.EmbeddedDB;
public class GuicyKillbillTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite {
- private static final Logger log = LoggerFactory.getLogger(KillbillTestSuiteWithEmbeddedDB.class);
+ private static final Logger log = LoggerFactory.getLogger(GuicyKillbillTestSuiteWithEmbeddedDB.class);
@Inject
- protected DBTestingHelper helper;
+ protected EmbeddedDB helper;
- public DBTestingHelper getDBTestingHelper() {
- return GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper();
- }
+ @Inject
+ protected DataSource dataSource;
- public IDBI getDBI() {
- return GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().getDBI();
- }
+ @Inject
+ protected IDBI dbi;
@BeforeSuite(groups = {"slow", "mysql"})
public void beforeSuite() throws Exception {
- GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().start();
- GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().initDb();
- GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().cleanupAllTables();
+ DBTestingHelper.start();
}
@BeforeMethod(groups = {"slow", "mysql"})
public void beforeMethod() throws Exception {
try {
- GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().cleanupAllTables();
+ DBTestingHelper.get().cleanupAllTables();
} catch (Exception ignored) {
}
}
@@ -62,13 +59,13 @@ public class GuicyKillbillTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite
if (hasFailed()) {
log.error("**********************************************************************************************");
log.error("*** TESTS HAVE FAILED - LEAVING DB RUNNING FOR DEBUGGING - MAKE SURE TO KILL IT ONCE DONE ****");
- log.error(GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().getConnectionString());
+ log.error(DBTestingHelper.get().getCmdLineConnectionString());
log.error("**********************************************************************************************");
return;
}
try {
- GuicyKillbillTestWithEmbeddedDBModule.getDBTestingHelper().stop();
+ DBTestingHelper.get().stop();
} catch (Exception ignored) {
}
}
diff --git a/util/src/test/java/com/ning/billing/GuicyKillbillTestWithEmbeddedDBModule.java b/util/src/test/java/com/ning/billing/GuicyKillbillTestWithEmbeddedDBModule.java
index c5567a1..43810bd 100644
--- a/util/src/test/java/com/ning/billing/GuicyKillbillTestWithEmbeddedDBModule.java
+++ b/util/src/test/java/com/ning/billing/GuicyKillbillTestWithEmbeddedDBModule.java
@@ -16,38 +16,29 @@
package com.ning.billing;
+import java.io.IOException;
+
+import javax.sql.DataSource;
import org.skife.jdbi.v2.IDBI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.testng.Assert;
-import com.ning.billing.dbi.DBTestingHelper;
-import com.ning.billing.dbi.H2TestingHelper;
-import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.commons.embeddeddb.EmbeddedDB;
public class GuicyKillbillTestWithEmbeddedDBModule extends GuicyKillbillTestModule {
- private static final Logger log = LoggerFactory.getLogger(GuicyKillbillTestWithEmbeddedDBModule.class);
-
- private static final DBTestingHelper instance = getDBTestingHelper();
-
- public static synchronized DBTestingHelper getDBTestingHelper() {
- if (instance == null) {
- if ("true".equals(System.getProperty("com.ning.billing.dbi.test.h2"))) {
- log.info("Using h2 as the embedded database");
- return new H2TestingHelper();
- } else {
- log.info("Using MySQL as the embedded database");
- return new MysqlTestingHelper();
- }
- }
- return instance;
- }
-
@Override
protected void configure() {
super.configure();
- bind(DBTestingHelper.class).toInstance(instance);
- bind(IDBI.class).toInstance(instance.getDBI());
+
+ final EmbeddedDB instance = DBTestingHelper.get();
+ bind(EmbeddedDB.class).toInstance(instance);
+
+ try {
+ bind(DataSource.class).toInstance(DBTestingHelper.get().getDataSource());
+ bind(IDBI.class).toInstance(DBTestingHelper.getDBI());
+ } catch (IOException e) {
+ Assert.fail(e.toString());
+ }
}
}
diff --git a/util/src/test/java/com/ning/billing/KillbillTestSuiteWithEmbeddedDB.java b/util/src/test/java/com/ning/billing/KillbillTestSuiteWithEmbeddedDB.java
index 20d2451..0ac8b85 100644
--- a/util/src/test/java/com/ning/billing/KillbillTestSuiteWithEmbeddedDB.java
+++ b/util/src/test/java/com/ning/billing/KillbillTestSuiteWithEmbeddedDB.java
@@ -27,45 +27,19 @@ import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
-import com.ning.billing.dbi.DBTestingHelper;
-import com.ning.billing.dbi.H2TestingHelper;
-import com.ning.billing.dbi.MysqlTestingHelper;
-
public class KillbillTestSuiteWithEmbeddedDB extends KillbillTestSuite {
private static final Logger log = LoggerFactory.getLogger(KillbillTestSuiteWithEmbeddedDB.class);
- protected static DBTestingHelper helper;
-
- static {
- if ("true".equals(System.getProperty("com.ning.billing.dbi.test.h2"))) {
- log.info("Using h2 as the embedded database");
- helper = new H2TestingHelper();
- } else {
- log.info("Using MySQL as the embedded database");
- helper = new MysqlTestingHelper();
- }
- }
-
- public static DBTestingHelper getDBTestingHelper() {
- return helper;
- }
-
- public static IDBI getDBI() {
- return helper.getDBI();
- }
-
@BeforeSuite(groups = {"slow", "mysql"})
public void startMysqlBeforeTestSuite() throws IOException, ClassNotFoundException, SQLException, URISyntaxException {
- helper.start();
- helper.initDb();
- helper.cleanupAllTables();
+ DBTestingHelper.start();
}
@BeforeMethod(groups = {"slow", "mysql"})
public void cleanupTablesBetweenMethods() {
try {
- helper.cleanupAllTables();
+ DBTestingHelper.get().cleanupAllTables();
} catch (Exception ignored) {
}
}
@@ -75,13 +49,13 @@ public class KillbillTestSuiteWithEmbeddedDB extends KillbillTestSuite {
if (hasFailed()) {
log.error("**********************************************************************************************");
log.error("*** TESTS HAVE FAILED - LEAVING DB RUNNING FOR DEBUGGING - MAKE SURE TO KILL IT ONCE DONE ****");
- log.error(helper.getConnectionString());
+ log.error(DBTestingHelper.get().getCmdLineConnectionString());
log.error("**********************************************************************************************");
return;
}
try {
- helper.stop();
+ DBTestingHelper.get().stop();
} catch (Exception ignored) {
}
}
diff --git a/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java b/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
index 16c758f..488b8d8 100644
--- a/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
+++ b/util/src/test/java/com/ning/billing/mock/api/MockAccountUserApi.java
@@ -17,6 +17,7 @@
package com.ning.billing.mock.api;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -106,6 +107,20 @@ public class MockAccountUserApi implements AccountUserApi {
}
@Override
+ public List<Account> searchAccounts(final String searchKey, final TenantContext tenantContext) {
+ final List<Account> results = new LinkedList<Account>();
+ for (final Account account : accounts) {
+ if ((account.getName() != null && account.getName().contains(searchKey)) ||
+ (account.getEmail() != null && account.getEmail().contains(searchKey)) ||
+ (account.getExternalKey() != null && account.getExternalKey().contains(searchKey)) ||
+ (account.getCompanyName() != null && account.getCompanyName().contains(searchKey))) {
+ results.add(account);
+ }
+ }
+ return results;
+ }
+
+ @Override
public List<Account> getAccounts(final TenantContext context) {
return new ArrayList<Account>(accounts);
}
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockGlobalLockerModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockGlobalLockerModule.java
index 03fd184..5457791 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockGlobalLockerModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockGlobalLockerModule.java
@@ -16,8 +16,8 @@
package com.ning.billing.mock.glue;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.MockGlobalLocker;
+import com.ning.billing.commons.locker.GlobalLocker;
+import com.ning.billing.commons.locker.memory.MemoryGlobalLocker;
import com.google.inject.AbstractModule;
@@ -25,6 +25,6 @@ public class MockGlobalLockerModule extends AbstractModule {
@Override
protected void configure() {
- bind(GlobalLocker.class).to(MockGlobalLocker.class).asEagerSingleton();
+ bind(GlobalLocker.class).to(MemoryGlobalLocker.class).asEagerSingleton();
}
}
diff --git a/util/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPluginBase.java b/util/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPluginBase.java
index 118303b..2737016 100644
--- a/util/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPluginBase.java
+++ b/util/src/test/java/com/ning/billing/payment/api/TestPaymentMethodPluginBase.java
@@ -24,6 +24,11 @@ import com.google.common.collect.ImmutableList;
public class TestPaymentMethodPluginBase implements PaymentMethodPlugin {
@Override
+ public UUID getKbPaymentMethodId() {
+ return UUID.randomUUID();
+ }
+
+ @Override
public String getExternalPaymentMethodId() {
return UUID.randomUUID().toString();
}
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
index 6fbc2a9..bdee1c6 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
@@ -45,7 +45,7 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
addTag();
// Verify we get an audit entry for the tag_history table
- final Handle handle = getDBI().open();
+ final Handle handle = dbi.open();
final String tagHistoryString = (String) handle.select("select id from tag_history limit 1").get(0).get("id");
handle.close();
diff --git a/util/src/test/java/com/ning/billing/util/cache/TestCache.java b/util/src/test/java/com/ning/billing/util/cache/TestCache.java
index 07680f1..f1c4570 100644
--- a/util/src/test/java/com/ning/billing/util/cache/TestCache.java
+++ b/util/src/test/java/com/ning/billing/util/cache/TestCache.java
@@ -73,7 +73,7 @@ public class TestCache extends UtilTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testCacheRecordId() throws Exception {
- this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(getDBI(), clock, controlCacheDispatcher, nonEntityDao);
+ this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controlCacheDispatcher, nonEntityDao);
final TagModelDao tag = new TagModelDao(clock.getUTCNow(), UUID.randomUUID(), UUID.randomUUID(), ObjectType.TAG);
// Verify we start with nothing in the cache
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java b/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
index 0508da6..edfb7e8 100644
--- a/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
@@ -40,7 +40,7 @@ public class TestInternalCallContextFactory extends UtilTestSuiteWithEmbeddedDB
final UUID invoiceId = UUID.randomUUID();
final Long accountRecordId = 19384012L;
- getDBI().withHandle(new HandleCallback<Void>() {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
handle.execute("DROP TABLE IF EXISTS invoices;\n" +
@@ -75,7 +75,7 @@ public class TestInternalCallContextFactory extends UtilTestSuiteWithEmbeddedDB
final UUID accountId = UUID.randomUUID();
final Long accountRecordId = 19384012L;
- getDBTestingHelper().getDBI().withHandle(new HandleCallback<Void>() {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
diff --git a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
index ac85be2..6fe8609 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
@@ -41,7 +41,7 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
final UUID accountId = UUID.randomUUID();
final Long accountRecordId = 19384012L;
- getDBI().withHandle(new HandleCallback<Void>() {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
@@ -60,7 +60,7 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
Assert.assertEquals(customFields.size(), 1);
Assert.assertEquals(customFields.get(0), customField);
// Verify the account_record_id was populated
- getDBTestingHelper().getDBI().withHandle(new HandleCallback<Void>() {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
final List<Map<String, Object>> values = handle.select("select account_record_id from custom_fields where object_id = ?", accountId.toString());
diff --git a/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java b/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java
index 153968f..efbe509 100644
--- a/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java
+++ b/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java
@@ -16,6 +16,7 @@
package com.ning.billing.util.dao;
+import java.io.IOException;
import java.util.Date;
import java.util.UUID;
@@ -47,8 +48,7 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
- public void testRetrieveRecordIdFromObject() {
-
+ public void testRetrieveRecordIdFromObject() throws IOException {
insertAccount();
final Long resultRecordId = nonEntityDao.retrieveRecordIdFromObject(accountId, ObjectType.ACCOUNT, null);
@@ -56,8 +56,7 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
}
@Test(groups = "slow")
- public void testRetrieveAccountRecordIdFromAccountObject() {
-
+ public void testRetrieveAccountRecordIdFromAccountObject() throws IOException {
insertAccount();
final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(accountId, ObjectType.ACCOUNT, null);
@@ -66,8 +65,7 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
- public void testRetrieveAccountRecordIdFromTagDefinitionObject() {
-
+ public void testRetrieveAccountRecordIdFromTagDefinitionObject() throws IOException {
insertTagDefinition();
final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(tagDefinitionId, ObjectType.TAG_DEFINITION, null);
@@ -76,8 +74,7 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
// Not Tag_definition or account which are special
@Test(groups = "slow")
- public void testRetrieveAccountRecordIdFromOtherObject() {
-
+ public void testRetrieveAccountRecordIdFromOtherObject() throws IOException {
insertTag();
final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(tagId, ObjectType.TAG, null);
@@ -85,8 +82,7 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
}
@Test(groups = "slow")
- public void testRetrieveTenantRecordIdFromObject() {
-
+ public void testRetrieveTenantRecordIdFromObject() throws IOException {
insertAccount();
final Long resultTenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(accountId, ObjectType.ACCOUNT, null);
@@ -94,15 +90,14 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
}
@Test(groups = "slow")
- public void testRetrieveTenantRecordIdFromTenantObject() {
-
+ public void testRetrieveTenantRecordIdFromTenantObject() throws IOException {
insertTenant();
final Long resultTenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(tenantId, ObjectType.TENANT, null);
Assert.assertEquals(resultTenantRecordId, tenantRecordId);
}
- private void insertAccount() {
- getDBI().withHandle(new HandleCallback<Void>() {
+ private void insertAccount() throws IOException {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
@@ -113,8 +108,8 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
});
}
- private void insertHistoryAccount() {
- getDBI().withHandle(new HandleCallback<Void>() {
+ private void insertHistoryAccount() throws IOException {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
@@ -126,8 +121,8 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
}
- private void insertTagDefinition() {
- getDBI().withHandle(new HandleCallback<Void>() {
+ private void insertTagDefinition() throws IOException {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
@@ -138,8 +133,8 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
});
}
- private void insertTag() {
- getDBI().withHandle(new HandleCallback<Void>() {
+ private void insertTag() throws IOException {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
@@ -150,8 +145,8 @@ public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
});
}
- private void insertTenant() {
- getDBI().withHandle(new HandleCallback<Void>() {
+ private void insertTenant() throws IOException {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
diff --git a/util/src/test/java/com/ning/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java b/util/src/test/java/com/ning/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
index ef86f5b..24abcd5 100644
--- a/util/src/test/java/com/ning/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
+++ b/util/src/test/java/com/ning/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
@@ -42,7 +42,7 @@ public class TestStringTemplateInheritanceWithJdbi extends UtilTestSuiteWithEmbe
@Test(groups = "slow")
public void testInheritQueries() throws Exception {
- final KombuchaSqlDao dao = getDBI().onDemand(KombuchaSqlDao.class);
+ final KombuchaSqlDao dao = dbi.onDemand(KombuchaSqlDao.class);
// Verify non inherited template
Assert.assertEquals(dao.isIsTimeForKombucha(), clock.getUTCNow().getHourOfDay() == 17);
diff --git a/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java b/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
index 9e2184b..17739b1 100644
--- a/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
+++ b/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
@@ -50,7 +50,7 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
final String tableNameA = "test_database_export_dao_a";
final String tableNameB = "test_database_export_dao_b";
- getDBTestingHelper().getDBI().withHandle(new HandleCallback<Void>() {
+ dbi.withHandle(new HandleCallback<Void>() {
@Override
public Void withHandle(final Handle handle) throws Exception {
handle.execute("drop table if exists " + tableNameA);
diff --git a/util/src/test/java/com/ning/billing/util/globallocker/TestGlobalLockerModule.java b/util/src/test/java/com/ning/billing/util/globallocker/TestGlobalLockerModule.java
index 5b0acad..06bdd94 100644
--- a/util/src/test/java/com/ning/billing/util/globallocker/TestGlobalLockerModule.java
+++ b/util/src/test/java/com/ning/billing/util/globallocker/TestGlobalLockerModule.java
@@ -16,8 +16,7 @@
package com.ning.billing.util.globallocker;
-import com.ning.billing.dbi.DBTestingHelper;
-import com.ning.billing.dbi.DBTestingHelper.DBEngine;
+import com.ning.billing.commons.embeddeddb.EmbeddedDB;
import com.ning.billing.mock.glue.MockGlobalLockerModule;
import com.ning.billing.util.glue.GlobalLockerModule;
@@ -25,15 +24,15 @@ import com.google.inject.AbstractModule;
public class TestGlobalLockerModule extends AbstractModule {
- private final DBTestingHelper helper;
+ private final EmbeddedDB helper;
- public TestGlobalLockerModule(final DBTestingHelper helper) {
+ public TestGlobalLockerModule(final EmbeddedDB helper) {
this.helper = helper;
}
@Override
protected void configure() {
- if (DBEngine.MYSQL.equals(helper.getDBEngine())) {
+ if (EmbeddedDB.DBEngine.MYSQL.equals(helper.getDBEngine())) {
install(new GlobalLockerModule());
} else {
install(new MockGlobalLockerModule());
diff --git a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
index 8682bc5..f6d695a 100644
--- a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
+++ b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
@@ -16,6 +16,7 @@
package com.ning.billing.util.globallocker;
+import java.io.IOException;
import java.util.UUID;
import org.skife.jdbi.v2.Handle;
@@ -24,21 +25,23 @@ import org.skife.jdbi.v2.TransactionStatus;
import org.testng.Assert;
import org.testng.annotations.Test;
+import com.ning.billing.commons.locker.GlobalLock;
+import com.ning.billing.commons.locker.GlobalLocker;
+import com.ning.billing.commons.locker.LockFailedException;
+import com.ning.billing.commons.locker.mysql.MySqlGlobalLocker;
import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
-import com.ning.billing.util.globallocker.GlobalLocker.LockerType;
public class TestMysqlGlobalLocker extends UtilTestSuiteWithEmbeddedDB {
-
// Used as a manual test to validate the simple DAO by stepping through that locking is done and release correctly
@Test(groups = "mysql")
- public void testSimpleLocking() {
+ public void testSimpleLocking() throws IOException, LockFailedException {
final String lockName = UUID.randomUUID().toString();
- final GlobalLocker locker = new MySqlGlobalLocker(getDBI());
- final GlobalLock lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, lockName, 3);
+ final GlobalLocker locker = new MySqlGlobalLocker(dataSource);
+ final GlobalLock lock = locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), lockName, 3);
- getDBI().inTransaction(new TransactionCallback<Void>() {
+ dbi.inTransaction(new TransactionCallback<Void>() {
@Override
public Void inTransaction(final Handle conn, final TransactionStatus status)
throws Exception {
@@ -46,11 +49,11 @@ public class TestMysqlGlobalLocker extends UtilTestSuiteWithEmbeddedDB {
return null;
}
});
- Assert.assertEquals(locker.isFree(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, lockName), Boolean.FALSE);
+ Assert.assertEquals(locker.isFree(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), lockName), false);
boolean gotException = false;
try {
- locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, lockName, 1);
+ locker.lockWithNumberOfTries(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), lockName, 1);
} catch (LockFailedException e) {
gotException = true;
}
@@ -58,6 +61,6 @@ public class TestMysqlGlobalLocker extends UtilTestSuiteWithEmbeddedDB {
lock.release();
- Assert.assertEquals(locker.isFree(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS, lockName), Boolean.TRUE);
+ Assert.assertEquals(locker.isFree(LockerType.ACCOUNT_FOR_INVOICE_PAYMENTS.toString(), lockName), true);
}
}
diff --git a/util/src/test/java/com/ning/billing/util/glue/TestUtilModuleNoDB.java b/util/src/test/java/com/ning/billing/util/glue/TestUtilModuleNoDB.java
index ec302c8..a5b8594 100644
--- a/util/src/test/java/com/ning/billing/util/glue/TestUtilModuleNoDB.java
+++ b/util/src/test/java/com/ning/billing/util/glue/TestUtilModuleNoDB.java
@@ -50,5 +50,9 @@ public class TestUtilModuleNoDB extends TestUtilModule {
install(new MockNotificationQueueModule(configSource));
installAuditMock();
+
+ install(new KillBillShiroModule());
+ install(new KillBillShiroAopModule());
+ install(new SecurityModule());
}
}
diff --git a/util/src/test/java/com/ning/billing/util/security/api/TestDefaultSecurityApi.java b/util/src/test/java/com/ning/billing/util/security/api/TestDefaultSecurityApi.java
new file mode 100644
index 0000000..e76f64b
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/security/api/TestDefaultSecurityApi.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util.security.api;
+
+import java.util.Set;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.api.SecurityApi;
+import com.ning.billing.util.UtilTestSuiteNoDB;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestDefaultSecurityApi extends UtilTestSuiteNoDB {
+
+ @Test(groups = "fast")
+ public void testRetrievePermissions() throws Exception {
+ configureShiro();
+
+ // We don't want the Guice injected one (it has Shiro disabled)
+ final SecurityApi securityApi = new DefaultSecurityApi();
+
+ final Set<Permission> anonsPermissions = securityApi.getCurrentUserPermissions(callContext);
+ Assert.assertEquals(anonsPermissions.size(), 0);
+
+ login("pierre");
+ final Set<Permission> pierresPermissions = securityApi.getCurrentUserPermissions(callContext);
+ Assert.assertEquals(pierresPermissions.size(), 2);
+ Assert.assertTrue(pierresPermissions.containsAll(ImmutableList.<Permission>of(Permission.INVOICE_CAN_CREDIT, Permission.INVOICE_CAN_ITEM_ADJUST)));
+
+ login("stephane");
+ final Set<Permission> stephanesPermissions = securityApi.getCurrentUserPermissions(callContext);
+ Assert.assertEquals(stephanesPermissions.size(), 1);
+ Assert.assertTrue(stephanesPermissions.containsAll(ImmutableList.<Permission>of(Permission.PAYMENT_CAN_REFUND)));
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestJDBCSessionDao.java b/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestJDBCSessionDao.java
new file mode 100644
index 0000000..1b13ce7
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestJDBCSessionDao.java
@@ -0,0 +1,74 @@
+/*
+ * 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.util.security.shiro.dao;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.UUID;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SimpleSession;
+import org.skife.jdbi.v2.DBI;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+
+public class TestJDBCSessionDao extends UtilTestSuiteWithEmbeddedDB {
+
+ @Test(groups = "slow")
+ public void testCRUD() throws Exception {
+ // Note! We are testing the do* methods here to bypass the caching layer
+ final JDBCSessionDao jdbcSessionDao = new JDBCSessionDao((DBI) dbi);
+
+ // Retrieve
+ final SimpleSession session = createSession();
+ Assert.assertNull(jdbcSessionDao.doReadSession(session.getId()));
+
+ // Create
+ final Serializable sessionId = jdbcSessionDao.doCreate(session);
+ final Session retrievedSession = jdbcSessionDao.doReadSession(sessionId);
+ Assert.assertEquals(retrievedSession, session);
+
+ // Update
+ final String newHost = UUID.randomUUID().toString();
+ Assert.assertNotEquals(retrievedSession.getHost(), newHost);
+ session.setHost(newHost);
+ jdbcSessionDao.doUpdate(session);
+ Assert.assertEquals(jdbcSessionDao.doReadSession(sessionId).getHost(), newHost);
+
+ // Delete
+ jdbcSessionDao.doDelete(session);
+ Assert.assertNull(jdbcSessionDao.doReadSession(session.getId()));
+ }
+
+ private SimpleSession createSession() {
+ final SimpleSession simpleSession = new SimpleSession();
+ simpleSession.setStartTimestamp(new Date(System.currentTimeMillis() - 5000));
+ simpleSession.setLastAccessTime(new Date(System.currentTimeMillis()));
+ simpleSession.setTimeout(493934L);
+ simpleSession.setHost(UUID.randomUUID().toString());
+ simpleSession.setAttribute(UUID.randomUUID().toString(), Short.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID().toString(), Integer.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID().toString(), Long.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+ // Test with Serializable objects
+ simpleSession.setAttribute(UUID.randomUUID().toString(), UUID.randomUUID());
+ simpleSession.setAttribute(UUID.randomUUID().toString(), new Date(1242));
+ return simpleSession;
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestSessionModelDao.java b/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestSessionModelDao.java
new file mode 100644
index 0000000..bf14642
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/security/shiro/dao/TestSessionModelDao.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util.security.shiro.dao;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SimpleSession;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.util.UtilTestSuiteNoDB;
+
+public class TestSessionModelDao extends UtilTestSuiteNoDB {
+
+ @Test(groups = "fast")
+ public void testRoundTrip() throws Exception {
+ final SimpleSession simpleSession = new SimpleSession();
+ simpleSession.setStartTimestamp(new Date(System.currentTimeMillis() - 5000));
+ simpleSession.setLastAccessTime(new Date(System.currentTimeMillis()));
+ simpleSession.setTimeout(493934L);
+ simpleSession.setHost(UUID.randomUUID().toString());
+ simpleSession.setAttribute(UUID.randomUUID(), Short.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID(), Integer.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID(), Long.MIN_VALUE);
+ simpleSession.setAttribute(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+ // Test with Serializable objects
+ simpleSession.setAttribute(UUID.randomUUID().toString(), UUID.randomUUID());
+ simpleSession.setAttribute(UUID.randomUUID().toString(), new Date(1242));
+
+ final SessionModelDao sessionModelDao = new SessionModelDao(simpleSession);
+ Assert.assertEquals(sessionModelDao.getTimeout(), simpleSession.getTimeout());
+ Assert.assertEquals(sessionModelDao.getHost(), simpleSession.getHost());
+ Assert.assertTrue(sessionModelDao.getSessionData().length > 0);
+
+ final Session retrievedSession = sessionModelDao.toSimpleSession();
+ Assert.assertEquals(retrievedSession, simpleSession);
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/security/shiro/realm/TestKillBillJndiLdapRealm.java b/util/src/test/java/com/ning/billing/util/security/shiro/realm/TestKillBillJndiLdapRealm.java
new file mode 100644
index 0000000..8b4d8d2
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/security/shiro/realm/TestKillBillJndiLdapRealm.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util.security.shiro.realm;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.subject.SimplePrincipalCollection;
+import org.skife.config.ConfigSource;
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.config.SimplePropertyConfigSource;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.util.UtilTestSuiteNoDB;
+import com.ning.billing.util.config.SecurityConfig;
+
+import com.google.common.collect.Sets;
+
+public class TestKillBillJndiLdapRealm extends UtilTestSuiteNoDB {
+
+ @Test(groups = "fast")
+ public void testCheckConfiguration() throws Exception {
+ // Test default configuration (see SecurityConfig)
+ final Map<String, Collection<String>> permission = killBillJndiLdapRealm.getPermissionsByGroup();
+
+ Assert.assertEquals(permission.get("admin").size(), 1);
+ Assert.assertEquals(permission.get("admin").iterator().next(), "*:*");
+
+ Assert.assertEquals(permission.get("finance").size(), 2);
+ Assert.assertEquals(Sets.newHashSet(permission.get("finance")), Sets.newHashSet("invoice:*", "payment:*"));
+
+ Assert.assertEquals(permission.get("support").size(), 2);
+ Assert.assertEquals(Sets.newHashSet(permission.get("support")), Sets.newHashSet("entitlement:*", "invoice:item_adjust"));
+ }
+
+ @Test(groups = "external", enabled = false)
+ public void testCheckLDAPConnection() throws Exception {
+ // Convenience method to verify your LDAP connectivity
+ final Properties props = new Properties();
+ props.setProperty("killbill.security.ldap.userDnTemplate", "uid={0},ou=users,dc=mycompany,dc=com");
+ props.setProperty("killbill.security.ldap.searchBase", "ou=groups,dc=mycompany,dc=com");
+ props.setProperty("killbill.security.ldap.groupSearchFilter", "memberOf=uid={0},ou=users,dc=mycompany,dc=com");
+ props.setProperty("killbill.security.ldap.groupNameId", "cn");
+ props.setProperty("killbill.security.ldap.url", "ldap://ldap:389");
+ props.setProperty("killbill.security.ldap.disableSSLCheck", "true");
+ props.setProperty("killbill.security.ldap.systemUsername", "cn=root");
+ props.setProperty("killbill.security.ldap.systemPassword", "password");
+ props.setProperty("killbill.security.ldap.authenticationMechanism", "simple");
+ props.setProperty("killbill.security.ldap.permissionsByGroup", "support-group: entitlement:*\n" +
+ "finance-group: invoice:*, payment:*\n" +
+ "ops-group: *:*");
+ final ConfigSource customConfigSource = new SimplePropertyConfigSource(props);
+ final SecurityConfig securityConfig = new ConfigurationObjectFactory(customConfigSource).build(SecurityConfig.class);
+ final KillBillJndiLdapRealm ldapRealm = new KillBillJndiLdapRealm(securityConfig);
+
+ final String username = "pierre";
+ final String password = "password";
+
+ // Check authentication
+ final UsernamePasswordToken token = new UsernamePasswordToken(username, password);
+ final AuthenticationInfo authenticationInfo = ldapRealm.getAuthenticationInfo(token);
+ System.out.println(authenticationInfo);
+
+ // Check permissions
+ final SimplePrincipalCollection principals = new SimplePrincipalCollection(username, username);
+ final AuthorizationInfo authorizationInfo = ldapRealm.queryForAuthorizationInfo(principals, ldapRealm.getContextFactory());
+ System.out.println("Roles: " + authorizationInfo.getRoles());
+ System.out.println("Permissions: " + authorizationInfo.getStringPermissions());
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/security/TestPermissionAnnotationMethodInterceptor.java b/util/src/test/java/com/ning/billing/util/security/TestPermissionAnnotationMethodInterceptor.java
new file mode 100644
index 0000000..2330078
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/security/TestPermissionAnnotationMethodInterceptor.java
@@ -0,0 +1,146 @@
+/*
+ * 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.util.security;
+
+import javax.inject.Singleton;
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.UnauthenticatedException;
+import org.mockito.Mockito;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.RequiresPermissions;
+import com.ning.billing.util.UtilTestSuiteNoDB;
+import com.ning.billing.util.glue.KillBillShiroAopModule;
+import com.ning.billing.util.glue.KillBillShiroModule;
+import com.ning.billing.util.glue.SecurityModule;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import net.sf.ehcache.CacheManager;
+
+public class TestPermissionAnnotationMethodInterceptor extends UtilTestSuiteNoDB {
+
+ public static interface IAopTester {
+
+ @RequiresPermissions(Permission.PAYMENT_CAN_REFUND)
+ public void createRefund();
+ }
+
+ public static class AopTesterImpl implements IAopTester {
+
+ @Override
+ public void createRefund() {}
+ }
+
+ @Singleton
+ public static class AopTester implements IAopTester {
+
+ @RequiresPermissions(Permission.PAYMENT_CAN_REFUND)
+ public void createRefund() {}
+ }
+
+ @Test(groups = "fast")
+ public void testAOPForClass() throws Exception {
+ // Make sure it works as expected without any AOP magic
+ final IAopTester simpleTester = new AopTester();
+ try {
+ simpleTester.createRefund();
+ } catch (Exception e) {
+ Assert.fail(e.getLocalizedMessage());
+ }
+
+ // Now, verify the interception works
+ configureShiro();
+ // Shutdown the cache manager to avoid duplicate exceptions
+ CacheManager.getInstance().shutdown();
+ final Injector injector = Guice.createInjector(Stage.PRODUCTION,
+ new KillBillShiroModule(),
+ new KillBillShiroAopModule(),
+ new SecurityModule(),
+ new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(IDBI.class).toInstance(Mockito.mock(IDBI.class));
+ }
+ });
+ final AopTester aopedTester = injector.getInstance(AopTester.class);
+ verifyAopedTester(aopedTester);
+ }
+
+ @Test(groups = "fast")
+ public void testAOPForInterface() throws Exception {
+ // Make sure it works as expected without any AOP magic
+ final IAopTester simpleTester = new AopTesterImpl();
+ try {
+ simpleTester.createRefund();
+ } catch (Exception e) {
+ Assert.fail(e.getLocalizedMessage());
+ }
+
+ // Now, verify the interception works
+ configureShiro();
+ // Shutdown the cache manager to avoid duplicate exceptions
+ CacheManager.getInstance().shutdown();
+ final Injector injector = Guice.createInjector(Stage.PRODUCTION,
+ new KillBillShiroModule(),
+ new KillBillShiroAopModule(),
+ new SecurityModule(),
+ new AbstractModule() {
+ @Override
+ public void configure() {
+ bind(IDBI.class).toInstance(Mockito.mock(IDBI.class));
+ bind(IAopTester.class).to(AopTesterImpl.class).asEagerSingleton();
+ }
+ });
+ final IAopTester aopedTester = injector.getInstance(IAopTester.class);
+ verifyAopedTester(aopedTester);
+ }
+
+ private void verifyAopedTester(final IAopTester aopedTester) {
+ // Anonymous user
+ logout();
+ try {
+ aopedTester.createRefund();
+ Assert.fail();
+ } catch (UnauthenticatedException e) {
+ // Good!
+ } catch (Exception e) {
+ Assert.fail(e.getLocalizedMessage());
+ }
+
+ // pierre can credit, but not refund
+ login("pierre");
+ try {
+ aopedTester.createRefund();
+ Assert.fail();
+ } catch (AuthorizationException e) {
+ // Good!
+ } catch (Exception e) {
+ Assert.fail(e.getLocalizedMessage());
+ }
+
+ // stephane can refund
+ login("stephane");
+ aopedTester.createRefund();
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/UtilTestSuiteNoDB.java b/util/src/test/java/com/ning/billing/util/UtilTestSuiteNoDB.java
index f82fc0d..acb66b1 100644
--- a/util/src/test/java/com/ning/billing/util/UtilTestSuiteNoDB.java
+++ b/util/src/test/java/com/ning/billing/util/UtilTestSuiteNoDB.java
@@ -18,18 +18,30 @@ package com.ning.billing.util;
import javax.inject.Inject;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.config.IniSecurityManagerFactory;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.Factory;
+import org.apache.shiro.util.ThreadContext;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import com.ning.billing.GuicyKillbillTestSuiteNoDB;
import com.ning.billing.bus.api.PersistentBus;
+import com.ning.billing.security.Permission;
+import com.ning.billing.security.api.SecurityApi;
import com.ning.billing.util.api.AuditUserApi;
import com.ning.billing.util.audit.dao.AuditDao;
import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.glue.TestUtilModuleNoDB;
+import com.ning.billing.util.security.shiro.realm.KillBillJndiLdapRealm;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -37,7 +49,6 @@ import com.google.inject.Stage;
public class UtilTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
-
@Inject
protected PersistentBus eventBus;
@Inject
@@ -52,6 +63,10 @@ public class UtilTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
protected AuditDao auditDao;
@Inject
protected AuditUserApi auditUserApi;
+ @Inject
+ protected SecurityApi securityApi;
+ @Inject
+ protected KillBillJndiLdapRealm killBillJndiLdapRealm;
@BeforeClass(groups = "fast")
public void beforeClass() throws Exception {
@@ -69,4 +84,37 @@ public class UtilTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
eventBus.stop();
}
+ // Security helpers
+
+ protected void login(final String username) {
+ logout();
+
+ final AuthenticationToken token = new UsernamePasswordToken(username, "password");
+ final Subject currentUser = SecurityUtils.getSubject();
+ currentUser.login(token);
+ }
+
+ protected void logout() {
+ final Subject currentUser = SecurityUtils.getSubject();
+ if (currentUser.isAuthenticated()) {
+ currentUser.logout();
+ }
+ }
+
+ protected void configureShiro() {
+ final Ini config = new Ini();
+ config.addSection("users");
+ config.getSection("users").put("pierre", "password, creditor");
+ config.getSection("users").put("stephane", "password, refunder");
+ config.addSection("roles");
+ config.getSection("roles").put("creditor", Permission.INVOICE_CAN_CREDIT.toString() + "," + Permission.INVOICE_CAN_ITEM_ADJUST.toString());
+ config.getSection("roles").put("refunder", Permission.PAYMENT_CAN_REFUND.toString());
+
+ // Reset the security manager
+ ThreadContext.unbindSecurityManager();
+
+ final Factory<SecurityManager> factory = new IniSecurityManagerFactory(config);
+ final SecurityManager securityManager = factory.getInstance();
+ SecurityUtils.setSecurityManager(securityManager);
+ }
}
diff --git a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
index c7c8803..c639fbb 100644
--- a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
+++ b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
@@ -41,9 +41,9 @@ public class TestValidationManager extends UtilTestSuiteWithEmbeddedDB {
@BeforeClass(groups = "slow")
public void beforeClass() throws Exception {
super.beforeClass();
- final DatabaseSchemaDao dao = new DatabaseSchemaDao(getDBI());
+ final DatabaseSchemaDao dao = new DatabaseSchemaDao(dbi);
vm = new ValidationManager(dao);
- vm.loadSchemaInformation(helper.getDbName());
+ vm.loadSchemaInformation(helper.getDatabaseName());
}