killbill-uncached

Merge pull request #624 from javier-gomez-github/jgomez-issue-604 Issue

10/10/2016 3:57:17 PM

Changes

pom.xml 2(+1 -1)

Details

diff --git a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
index 1f1ad92..8c75df8 100644
--- a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
@@ -93,6 +93,11 @@ public class DefaultAccountUserApi extends DefaultAccountApiBase implements Acco
         }
 
         final AccountModelDao account = new AccountModelDao(data);
+
+        if (null != account.getExternalKey() && account.getExternalKey().length() > 255) {
+            throw new AccountApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
+        }
+
         accountDao.create(account, internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(context));
 
         return new DefaultAccount(account);
diff --git a/account/src/main/resources/org/killbill/billing/account/ddl.sql b/account/src/main/resources/org/killbill/billing/account/ddl.sql
index b025697..295a88d 100644
--- a/account/src/main/resources/org/killbill/billing/account/ddl.sql
+++ b/account/src/main/resources/org/killbill/billing/account/ddl.sql
@@ -4,7 +4,7 @@ DROP TABLE IF EXISTS accounts;
 CREATE TABLE accounts (
     record_id serial unique,
     id varchar(36) NOT NULL,
-    external_key varchar(128) NULL,
+    external_key varchar(255) NULL,
     email varchar(128) DEFAULT NULL,
     name varchar(100) DEFAULT NULL,
     first_name_length int DEFAULT NULL,
@@ -42,7 +42,7 @@ CREATE TABLE account_history (
     record_id serial unique,
     id varchar(36) NOT NULL,
     target_record_id bigint /*! unsigned */ not null,
-    external_key varchar(128) NULL,
+    external_key varchar(255) NULL,
     email varchar(128) DEFAULT NULL,
     name varchar(100) DEFAULT NULL,
     first_name_length int DEFAULT NULL,
diff --git a/account/src/main/resources/org/killbill/billing/account/migration/V20161004171445__account_external_keys.sql b/account/src/main/resources/org/killbill/billing/account/migration/V20161004171445__account_external_keys.sql
new file mode 100644
index 0000000..1809a23
--- /dev/null
+++ b/account/src/main/resources/org/killbill/billing/account/migration/V20161004171445__account_external_keys.sql
@@ -0,0 +1,2 @@
+alter table accounts modify external_key varchar(255);
+alter table account_history modify external_key varchar(255);
\ No newline at end of file
diff --git a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
index 78df7a1..338c58c 100644
--- a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
+++ b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
+import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.AccountTestSuiteWithEmbeddedDB;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
@@ -41,6 +42,7 @@ import com.google.common.eventbus.Subscribe;
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.killbill.billing.account.AccountTestUtils.createTestAccount;
+import static org.testng.Assert.assertEquals;
 
 public class TestDefaultAccountUserApi extends AccountTestSuiteWithEmbeddedDB {
 
@@ -162,4 +164,17 @@ public class TestDefaultAccountUserApi extends AccountTestSuiteWithEmbeddedDB {
 
     }
 
+    @Test(groups = "slow", description = "Test Account creation with External Key over limit")
+        public void testCreateAccountWithExternalKeyOverLimit() throws Exception {
+        AccountModelDao accountModelDao = createTestAccount();
+        // Set an externalKey of 256 characters (over limit)
+        accountModelDao.setExternalKey("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.");
+        final AccountData accountData = new DefaultAccount(accountModelDao);
+        try {
+            accountUserApi.createAccount(accountData, callContext);
+            Assert.fail();
+        } catch (final AccountApiException e) {
+            assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
+        }
+    }
 }
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
index 18a4beb..f23a365 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -32,7 +32,6 @@ import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
 import org.killbill.billing.catalog.api.PlanSpecifier;
 import org.killbill.billing.catalog.api.PriceListSet;
-import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.entitlement.EntitlementService;
 import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
 import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
@@ -526,6 +525,27 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
         }
     }
 
+    @Test(groups = "slow")
+    public void testSubscriptionCreationWithExternalKeyOverLimit() throws AccountApiException, SubscriptionApiException, EntitlementApiException {
+        final String externalKey = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.";
+
+        final LocalDate initialDate = new LocalDate(2013, 8, 7);
+        clock.setDay(initialDate);
+
+        final Account account = createAccount(getAccountData(7));
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+        //2013-08-07
+        final LocalDate effectiveDate = initialDate.plusMonths(1);
+
+        try {
+            entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, effectiveDate, effectiveDate, false, ImmutableList.<PluginProperty>of(), callContext);
+            Assert.fail();
+        } catch (final EntitlementApiException e) {
+            assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
+        }
+    }
 
     private void verifyBlockingStates(final Iterable<BlockingState> result, final List<BlockingState> expected) {
         int i = 0;
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
index 54bfd9d..e2bcac5 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
@@ -65,4 +65,10 @@ public class DefaultApiBase {
             throw new PaymentApiException(ErrorCode.PAYMENT_INVALID_PARAMETER, parameterName, "should not be null");
         }
     }
+
+    protected void checkExternalKeyLength(final String externalKey) throws PaymentApiException {
+        if (null != externalKey && externalKey.length() > 255) {
+            throw new PaymentApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
+        }
+    }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index e24e4fa..96ad05e 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -79,6 +79,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
             checkNotNullParameter(currency, "currency");
         }
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentExternalKey);
 
         final String transactionType = TransactionType.AUTHORIZE.name();
         Payment payment = null;
@@ -125,6 +126,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
             checkNotNullParameter(currency, "currency");
         }
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentExternalKey);
 
         final String transactionType = TransactionType.AUTHORIZE.name();
 
@@ -165,6 +167,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         checkNotNullParameter(amount, "amount");
         checkNotNullParameter(currency, "currency");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CAPTURE.name();
         Payment payment = null;
@@ -208,6 +211,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         checkNotNullParameter(amount, "amount");
         checkNotNullParameter(currency, "currency");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CAPTURE.name();
         Payment payment = null;
@@ -249,6 +253,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
             checkNotNullParameter(currency, "currency");
         }
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.PURCHASE.name();
         Payment payment = null;
@@ -294,6 +299,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         }
 
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         if (paymentMethodId == null && !paymentOptions.isExternalPayment()) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, "paymentMethodId", "should not be null");
@@ -343,6 +349,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         checkNotNullParameter(account, "account");
         checkNotNullParameter(paymentId, "paymentId");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.VOID.name();
         Payment payment = null;
@@ -384,6 +391,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         checkNotNullParameter(account, "account");
         checkNotNullParameter(paymentId, "paymentId");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.VOID.name();
         Payment payment = null;
@@ -423,6 +431,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         }
         checkNotNullParameter(paymentId, "paymentId");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.REFUND.name();
         Payment payment = null;
@@ -467,6 +476,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         }
         checkNotNullParameter(paymentId, "paymentId");
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.REFUND.name();
         Payment payment = null;
@@ -507,6 +517,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
             checkNotNullParameter(currency, "currency");
         }
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CREDIT.name();
         Payment payment = null;
@@ -556,6 +567,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
             checkNotNullParameter(currency, "currency");
         }
         checkNotNullParameter(properties, "plugin properties");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CREDIT.name();
         Payment payment = null;
@@ -655,6 +667,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
         checkNotNullParameter(amount, "amount");
         checkNotNullParameter(currency, "currency");
         checkNotNullParameter(paymentId, "paymentId");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CHARGEBACK.name();
         Payment payment = null;
@@ -730,6 +743,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
     public Payment createChargebackReversal(final Account account, final UUID paymentId, final String paymentTransactionExternalKey, final CallContext callContext) throws PaymentApiException {
         checkNotNullParameter(account, "account");
         checkNotNullParameter(paymentId, "paymentId");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CHARGEBACK.name();
         Payment payment = null;
@@ -768,6 +782,7 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
 
         checkNotNullParameter(account, "account");
         checkNotNullParameter(paymentId, "paymentId");
+        checkExternalKeyLength(paymentTransactionExternalKey);
 
         final String transactionType = TransactionType.CHARGEBACK.name();
         Payment payment = null;
diff --git a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
index fef6bd7..25af914 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
+++ b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
@@ -6,9 +6,9 @@ CREATE TABLE payment_attempts (
     id varchar(36) NOT NULL,
     account_id varchar(36) NOT NULL,
     payment_method_id varchar(36) DEFAULT NULL,
-    payment_external_key varchar(128) NOT NULL,
+    payment_external_key varchar(255) NOT NULL,
     transaction_id varchar(36),
-    transaction_external_key varchar(128) NOT NULL,
+    transaction_external_key varchar(255) NOT NULL,
     transaction_type varchar(32) NOT NULL,
     state_name varchar(32) NOT NULL,
     amount numeric(15,9),
@@ -37,9 +37,9 @@ CREATE TABLE payment_attempt_history (
     target_record_id bigint /*! unsigned */ not null,
     account_id varchar(36) NOT NULL,
     payment_method_id varchar(36) DEFAULT NULL,
-    payment_external_key varchar(128) NOT NULL,
+    payment_external_key varchar(255) NOT NULL,
     transaction_id varchar(36),
-    transaction_external_key varchar(128) NOT NULL,
+    transaction_external_key varchar(255) NOT NULL,
     transaction_type varchar(32) NOT NULL,
     state_name varchar(32) NOT NULL,
     amount numeric(15,9),
diff --git a/payment/src/main/resources/org/killbill/billing/payment/migration/V20161005110745__payment_external_keys.sql b/payment/src/main/resources/org/killbill/billing/payment/migration/V20161005110745__payment_external_keys.sql
new file mode 100644
index 0000000..b5ccf70
--- /dev/null
+++ b/payment/src/main/resources/org/killbill/billing/payment/migration/V20161005110745__payment_external_keys.sql
@@ -0,0 +1,4 @@
+alter table payment_attempts modify payment_external_key varchar(255);
+alter table payment_attempts modify transaction_external_key varchar(255);
+alter table payment_attempt_history modify payment_external_key varchar(255);
+alter table payment_attempt_history modify transaction_external_key varchar(255);
\ No newline at end of file
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index e141506..92d8c17 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -868,7 +868,25 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(attempts.size(), 1);
     }
 
+    @Test(groups = "slow")
+    public void testCreatePurchaseWithExternalKeyOverLimit() throws PaymentApiException, InvoiceApiException, EventBusException {
+        final BigDecimal requestedAmount = BigDecimal.TEN;
+        final LocalDate now = clock.getUTCToday();
+
+        final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
+
+        final String paymentExternalKey = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.";
+        final String transactionExternalKey = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.";
+
+        try {
+            paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, paymentExternalKey, transactionExternalKey,
+                                                        createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+            Assert.fail();
+        } catch (final PaymentApiException e) {
+            assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
+        }
 
+    }
 
     @Test(groups = "slow")
     public void testCreateFailedPurchaseWithPaymentControl() throws PaymentApiException, InvoiceApiException, EventBusException {

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index a3f3db4..c1bbb5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.130</version>
+        <version>0.131-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.17.5-SNAPSHOT</version>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index fcc771d..4b18a23 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -318,6 +318,10 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
         final DateTime now = clock.getUTCNow();
         final DateTime originalCreatedDate = existingBundles.size() > 0 ? existingBundles.get(0).getCreatedDate() : now;
         final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, originalCreatedDate, now, now);
+
+        if (null != bundleKey && bundleKey.length() > 255) {
+            throw new SubscriptionBaseApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
+        }
         return dao.createSubscriptionBundle(bundle, context);
     }
 
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql b/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
index 9e5e0c6..80abc65 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
@@ -52,7 +52,7 @@ DROP TABLE IF EXISTS bundles;
 CREATE TABLE bundles (
     record_id serial unique,
     id varchar(36) NOT NULL,
-    external_key varchar(64) NOT NULL,
+    external_key varchar(255) NOT NULL,
     account_id varchar(36) NOT NULL,
     last_sys_update_date datetime,
     original_created_date datetime NOT NULL,
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/migration/V20161005110304__bundles_external_key.sql b/subscription/src/main/resources/org/killbill/billing/subscription/migration/V20161005110304__bundles_external_key.sql
new file mode 100644
index 0000000..d8aef66
--- /dev/null
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/migration/V20161005110304__bundles_external_key.sql
@@ -0,0 +1 @@
+alter table bundles modify external_key varchar(255);
\ No newline at end of file
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java b/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
index 0282ffd..b9a22bc 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
@@ -87,6 +87,10 @@ public class DefaultTenantUserApi implements TenantUserApi {
     public Tenant createTenant(final TenantData data, final CallContext context) throws TenantApiException {
         final Tenant tenant = new DefaultTenant(data);
 
+        if (null != tenant.getExternalKey() && tenant.getExternalKey().length() > 255) {
+            throw new TenantApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
+        }
+
         try {
             tenantDao.create(new TenantModelDao(tenant), internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(context));
         } catch (final TenantApiException e) {
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql b/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
index 6e34285..988714f 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
@@ -4,7 +4,7 @@ DROP TABLE IF EXISTS tenants;
 CREATE TABLE tenants (
     record_id serial unique,
     id varchar(36) NOT NULL,
-    external_key varchar(128) NULL,
+    external_key varchar(255) NULL,
     api_key varchar(128) NULL,
     api_secret varchar(128) NULL,
     api_salt varchar(128) NULL,
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/migration/V20161005110145__tenant_external_key.sql b/tenant/src/main/resources/org/killbill/billing/tenant/migration/V20161005110145__tenant_external_key.sql
new file mode 100644
index 0000000..fc6765f
--- /dev/null
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/migration/V20161005110145__tenant_external_key.sql
@@ -0,0 +1 @@
+alter table tenants modify external_key varchar(255);
\ No newline at end of file
diff --git a/tenant/src/test/java/org/killbill/billing/tenant/api/user/TestDefaultTenantUserApi.java b/tenant/src/test/java/org/killbill/billing/tenant/api/user/TestDefaultTenantUserApi.java
index 2d4faa4..8f4c091 100644
--- a/tenant/src/test/java/org/killbill/billing/tenant/api/user/TestDefaultTenantUserApi.java
+++ b/tenant/src/test/java/org/killbill/billing/tenant/api/user/TestDefaultTenantUserApi.java
@@ -20,9 +20,11 @@ package org.killbill.billing.tenant.api.user;
 import java.util.List;
 import java.util.UUID;
 
+import org.killbill.billing.ErrorCode;
 import org.killbill.billing.tenant.TenantTestSuiteWithEmbeddedDb;
 import org.killbill.billing.tenant.api.DefaultTenant;
 import org.killbill.billing.tenant.api.Tenant;
+import org.killbill.billing.tenant.api.TenantApiException;
 import org.killbill.billing.tenant.api.TenantData;
 import org.killbill.billing.tenant.api.TenantKV.TenantKey;
 import org.testng.Assert;
@@ -141,4 +143,19 @@ public class TestDefaultTenantUserApi extends TenantTestSuiteWithEmbeddedDb {
         value = tenantUserApi.getTenantValuesForKey(tenantKey, callContext);
         Assert.assertEquals(value.size(), 0);
     }
+
+    @Test(groups = "slow", description = "Test Tenant creation with External Key over limit")
+    public void testCreateTenantWithExternalKeyOverLimit() throws Exception {
+        final TenantData tenantdata = new DefaultTenant(UUID.randomUUID(),
+                                                        clock.getUTCNow(),
+                                                        clock.getUTCNow(),
+                                                        "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.",
+                                                        "TTR445ee2", "dskjhfs^^54R");
+        try {
+            tenantUserApi.createTenant(tenantdata, callContext);
+            Assert.fail();
+        } catch (final TenantApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
+        }
+    }
 }