Search in sources :

Example 1 with Tenant

use of org.killbill.billing.client.model.Tenant in project killbill by killbill.

the class TestPerTenantConfig method testFailedPaymentWithPerTenantRetryConfig.

@Test(groups = "slow")
public void testFailedPaymentWithPerTenantRetryConfig() throws Exception {
    // Create the tenant
    final String apiKeyTenant1 = "tenantSuperTuned";
    final String apiSecretTenant1 = "2367$$ffr79";
    loginTenant(apiKeyTenant1, apiSecretTenant1);
    final Tenant tenant1 = new Tenant();
    tenant1.setApiKey(apiKeyTenant1);
    tenant1.setApiSecret(apiSecretTenant1);
    killBillClient.createTenant(tenant1, createdBy, reason, comment);
    // Configure our plugin to fail
    mockPaymentProviderPlugin.makeAllInvoicesFailWithError(true);
    // Upload the config
    final ObjectMapper mapper = new ObjectMapper();
    final HashMap<String, String> perTenantProperties = new HashMap<String, String>();
    perTenantProperties.put("org.killbill.payment.retry.days", "1,1,1");
    final String perTenantConfig = mapper.writeValueAsString(perTenantProperties);
    final TenantKey tenantKey = killBillClient.postConfigurationPropertiesForTenant(perTenantConfig, requestOptions);
    final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
    final Payments payments = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments.size(), 1);
    Assert.assertEquals(payments.get(0).getTransactions().size(), 1);
    //
    // Because we have specified a retry interval of one day we should see the new attempt after moving clock 1 day (and not 8 days which is default)
    //
    //
    // Now unregister special per tenant config and we the first retry occurs one day after (and still fails), it now sets a retry date of 8 days
    //
    killBillClient.unregisterConfigurationForTenant(requestOptions);
    // org.killbill.tenant.broadcast.rate has been set to 1s
    crappyWaitForLackOfProperSynchonization(2000);
    clock.addDays(1);
    Awaitility.await().atMost(4, TimeUnit.SECONDS).pollInterval(Duration.ONE_SECOND).until(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            return killBillClient.getPaymentsForAccount(accountJson.getAccountId()).get(0).getTransactions().size() == 2;
        }
    });
    final Payments payments2 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments2.size(), 1);
    Assert.assertEquals(payments2.get(0).getTransactions().size(), 2);
    Assert.assertEquals(payments2.get(0).getTransactions().get(0).getStatus(), TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(payments2.get(0).getTransactions().get(1).getStatus(), TransactionStatus.PAYMENT_FAILURE.name());
    clock.addDays(1);
    crappyWaitForLackOfProperSynchonization(3000);
    // No retry with default config
    final Payments payments3 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments3.size(), 1);
    Assert.assertEquals(payments3.get(0).getTransactions().size(), 2);
    mockPaymentProviderPlugin.makeAllInvoicesFailWithError(false);
    clock.addDays(7);
    Awaitility.await().atMost(4, TimeUnit.SECONDS).pollInterval(Duration.ONE_SECOND).until(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            return killBillClient.getPaymentsForAccount(accountJson.getAccountId()).get(0).getTransactions().size() == 3;
        }
    });
    final Payments payments4 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments4.size(), 1);
    Assert.assertEquals(payments4.get(0).getTransactions().size(), 3);
    Assert.assertEquals(payments4.get(0).getTransactions().get(0).getStatus(), TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(payments4.get(0).getTransactions().get(1).getStatus(), TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(payments4.get(0).getTransactions().get(2).getStatus(), TransactionStatus.SUCCESS.name());
}
Also used : Account(org.killbill.billing.client.model.Account) Tenant(org.killbill.billing.client.model.Tenant) HashMap(java.util.HashMap) TenantKey(org.killbill.billing.client.model.TenantKey) Payments(org.killbill.billing.client.model.Payments) ObjectMapper(org.killbill.billing.util.jackson.ObjectMapper) Test(org.testng.annotations.Test)

Example 2 with Tenant

use of org.killbill.billing.client.model.Tenant in project killbill by killbill.

the class TestTenantKV method testPerTenantPluginPaymentStateMachineConfig.

@Test(groups = "slow", description = "Upload and retrieve a per plugin payment state machine config")
public void testPerTenantPluginPaymentStateMachineConfig() throws Exception {
    // Create another tenant - it will have a different state machine
    final Tenant otherTenantWithDifferentStateMachine = new Tenant();
    otherTenantWithDifferentStateMachine.setApiKey(UUID.randomUUID().toString());
    otherTenantWithDifferentStateMachine.setApiSecret(UUID.randomUUID().toString());
    killBillClient.createTenant(otherTenantWithDifferentStateMachine, true, requestOptions);
    final RequestOptions requestOptionsOtherTenant = requestOptions.extend().withTenantApiKey(otherTenantWithDifferentStateMachine.getApiKey()).withTenantApiSecret(otherTenantWithDifferentStateMachine.getApiSecret()).build();
    // Verify initial state
    final TenantKey emptyTenantKey = killBillClient.getPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptions);
    Assert.assertEquals(emptyTenantKey.getValues().size(), 0);
    final TenantKey emptyTenantKeyOtherTenant = killBillClient.getPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptionsOtherTenant);
    Assert.assertEquals(emptyTenantKeyOtherTenant.getValues().size(), 0);
    final String stateMachineConfigPath = Resources.getResource("SimplePaymentStates.xml").getPath();
    final TenantKey tenantKey0 = killBillClient.registerPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, stateMachineConfigPath, requestOptionsOtherTenant);
    Assert.assertEquals(tenantKey0.getKey(), TenantKV.TenantKey.PLUGIN_PAYMENT_STATE_MACHINE_.toString() + PLUGIN_NAME);
    // Verify only the other tenant has the new state machine
    final TenantKey emptyTenantKey1 = killBillClient.getPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptions);
    Assert.assertEquals(emptyTenantKey1.getValues().size(), 0);
    final TenantKey tenantKey1OtherTenant = killBillClient.getPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptionsOtherTenant);
    Assert.assertEquals(tenantKey1OtherTenant.getKey(), TenantKV.TenantKey.PLUGIN_PAYMENT_STATE_MACHINE_.toString() + PLUGIN_NAME);
    Assert.assertEquals(tenantKey1OtherTenant.getValues().size(), 1);
    // Create an auth in both tenant
    final Payment payment = createComboPaymentTransaction(requestOptions);
    final Payment paymentOtherTenant = createComboPaymentTransaction(requestOptionsOtherTenant);
    // Void in the first tenant (allowed by the default state machine)
    final Payment voidPayment = killBillClient.voidPayment(payment.getPaymentId(), payment.getPaymentExternalKey(), UUID.randomUUID().toString(), ImmutableList.<String>of(), ImmutableMap.<String, String>of(), requestOptions);
    Assert.assertEquals(voidPayment.getTransactions().get(0).getStatus(), TransactionStatus.SUCCESS.toString());
    Assert.assertEquals(voidPayment.getTransactions().get(1).getStatus(), TransactionStatus.SUCCESS.toString());
    // Void in the other tenant (disallowed)
    try {
        killBillClient.voidPayment(paymentOtherTenant.getPaymentId(), paymentOtherTenant.getPaymentExternalKey(), UUID.randomUUID().toString(), ImmutableList.<String>of(), ImmutableMap.<String, String>of(), requestOptionsOtherTenant);
        Assert.fail();
    } catch (final KillBillClientException e) {
        Assert.assertEquals((int) e.getBillingException().getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
    }
    // Remove the custom state machine
    killBillClient.unregisterPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptionsOtherTenant);
    final TenantKey tenantKey2 = killBillClient.getPluginPaymentStateMachineConfigurationForTenant(PLUGIN_NAME, requestOptionsOtherTenant);
    Assert.assertEquals(tenantKey2.getKey(), TenantKV.TenantKey.PLUGIN_PAYMENT_STATE_MACHINE_.toString() + PLUGIN_NAME);
    Assert.assertEquals(tenantKey2.getValues().size(), 0);
    final AtomicReference<Payment> voidPaymentOtherTenant2Ref = new AtomicReference<Payment>();
    Awaitility.await().atMost(8, TimeUnit.SECONDS).pollInterval(Duration.TWO_SECONDS).until(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            // The void should now go through
            try {
                final Payment voidPaymentOtherTenant2 = killBillClient.voidPayment(paymentOtherTenant.getPaymentId(), paymentOtherTenant.getPaymentExternalKey(), UUID.randomUUID().toString(), ImmutableList.<String>of(), ImmutableMap.<String, String>of(), requestOptionsOtherTenant);
                voidPaymentOtherTenant2Ref.set(voidPaymentOtherTenant2);
                return voidPaymentOtherTenant2 != null;
            } catch (final KillBillClientException e) {
                // Invalidation hasn't happened yet
                return false;
            }
        }
    });
    Assert.assertEquals(voidPaymentOtherTenant2Ref.get().getTransactions().get(0).getStatus(), TransactionStatus.SUCCESS.toString());
    Assert.assertEquals(voidPaymentOtherTenant2Ref.get().getTransactions().get(1).getStatus(), TransactionStatus.SUCCESS.toString());
}
Also used : Payment(org.killbill.billing.client.model.Payment) Tenant(org.killbill.billing.client.model.Tenant) RequestOptions(org.killbill.billing.client.RequestOptions) TenantKey(org.killbill.billing.client.model.TenantKey) KillBillClientException(org.killbill.billing.client.KillBillClientException) AtomicReference(java.util.concurrent.atomic.AtomicReference) KillBillClientException(org.killbill.billing.client.KillBillClientException) Test(org.testng.annotations.Test)

Example 3 with Tenant

use of org.killbill.billing.client.model.Tenant in project killbill by killbill.

the class TestJaxrsBase method beforeMethod.

@BeforeMethod(groups = "slow")
public void beforeMethod() throws Exception {
    super.beforeMethod();
    // Because we truncate the tables, the database record_id auto_increment will be reset
    tenantCacheInvalidation.setLatestRecordIdProcessed(0L);
    externalBus.start();
    internalBus.start();
    cacheControllerDispatcher.clearAll();
    busHandler.reset();
    clock.resetDeltaFromReality();
    clock.setDay(new LocalDate(2012, 8, 25));
    // Make sure to re-generate the api key and secret (could be cached by Shiro)
    DEFAULT_API_KEY = UUID.randomUUID().toString();
    DEFAULT_API_SECRET = UUID.randomUUID().toString();
    loginTenant(DEFAULT_API_KEY, DEFAULT_API_SECRET);
    // Recreate the tenant (tables have been cleaned-up)
    final Tenant tenant = new Tenant();
    tenant.setApiKey(DEFAULT_API_KEY);
    tenant.setApiSecret(DEFAULT_API_SECRET);
    killBillClient.createTenant(tenant, createdBy, reason, comment);
}
Also used : Tenant(org.killbill.billing.client.model.Tenant) LocalDate(org.joda.time.LocalDate) BeforeMethod(org.testng.annotations.BeforeMethod)

Example 4 with Tenant

use of org.killbill.billing.client.model.Tenant in project killbill by killbill.

the class TestCache method testInvalidateCacheByTenant.

@Test(groups = "slow", description = "Can Invalidate (clear) all Tenant Caches for current Tenant")
public void testInvalidateCacheByTenant() throws Exception {
    // creating a new Tenant for this test
    final String testApiKey = "testApiKey";
    final String testApiSecret = "testApiSecret";
    final Tenant tenant = new Tenant();
    tenant.setApiKey(testApiKey);
    tenant.setApiSecret(testApiSecret);
    loginTenant(testApiKey, testApiSecret);
    Tenant currentTenant = killBillClient.createTenant(tenant, false, requestOptions);
    // using custom RequestOptions with the new Tenant created before
    RequestOptions inputOptions = RequestOptions.builder().withCreatedBy(createdBy).withReason(reason).withComment(comment).withTenantApiKey(currentTenant.getApiKey()).withTenantApiSecret(currentTenant.getApiSecret()).build();
    // Uploading the test catalog using the new Tenant created before
    killBillClient.uploadXMLCatalog(Resources.getResource("SpyCarAdvanced.xml").getPath(), inputOptions);
    // creating an Account with PaymentMethod and a Subscription
    createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoiceWithInputOptions(inputOptions);
    // get all caches per tenant level
    final Ehcache tenantRecordIdCache = cacheManager.getEhcache(CacheType.TENANT_RECORD_ID.getCacheName());
    final Ehcache tenantPaymentStateMachineConfigCache = cacheManager.getEhcache(CacheType.TENANT_PAYMENT_STATE_MACHINE_CONFIG.getCacheName());
    final Ehcache tenantCache = cacheManager.getEhcache(CacheType.TENANT.getCacheName());
    final Ehcache tenantKvCache = cacheManager.getEhcache(CacheType.TENANT_KV.getCacheName());
    final Ehcache tenantConfigCache = cacheManager.getEhcache(CacheType.TENANT_CONFIG.getCacheName());
    final Ehcache tenantOverdueConfigCache = cacheManager.getEhcache(CacheType.TENANT_OVERDUE_CONFIG.getCacheName());
    final Ehcache tenantCatalogCache = cacheManager.getEhcache(CacheType.TENANT_CATALOG.getCacheName());
    // getting current Tenant's record Id from the specific Cache
    Long tenantRecordId = (Long) tenantRecordIdCache.get(currentTenant.getTenantId().toString()).getObjectValue();
    // verify that they are not null and have the expected tenant information
    assertNotNull(tenantRecordIdCache);
    assertNotNull(tenantRecordIdCache.get(currentTenant.getTenantId().toString()));
    assertNotNull(tenantPaymentStateMachineConfigCache);
    assertTrue(hasKeysByTenantRecordId(tenantPaymentStateMachineConfigCache, tenantRecordId.toString()));
    assertNotNull(tenantCache);
    assertNotNull(tenantCache.get(testApiKey));
    assertNotNull(tenantKvCache);
    assertTrue(hasKeysByTenantRecordId(tenantKvCache, tenantRecordId.toString()));
    assertNotNull(tenantConfigCache);
    assertNotNull(tenantConfigCache.get(tenantRecordId));
    assertNotNull(tenantOverdueConfigCache);
    assertNotNull(tenantOverdueConfigCache.get(tenantRecordId));
    assertNotNull(tenantCatalogCache);
    assertNotNull(tenantCatalogCache.get(tenantRecordId));
    // invalidate caches per tenant level
    killBillClient.invalidateCacheByTenant(inputOptions);
    // verify that now the caches don't have the previous values
    Assert.assertNull(tenantRecordIdCache.get(currentTenant.getTenantId().toString()));
    assertFalse(hasKeysByTenantRecordId(tenantPaymentStateMachineConfigCache, tenantRecordId.toString()));
    Assert.assertNull(tenantCache.get(testApiKey));
    assertFalse(hasKeysByTenantRecordId(tenantKvCache, tenantRecordId.toString()));
    Assert.assertNull(tenantConfigCache.get(tenantRecordId));
    Assert.assertNull(tenantOverdueConfigCache.get(tenantRecordId));
    Assert.assertNull(tenantCatalogCache.get(tenantRecordId));
}
Also used : Tenant(org.killbill.billing.client.model.Tenant) RequestOptions(org.killbill.billing.client.RequestOptions) Ehcache(net.sf.ehcache.Ehcache) Test(org.testng.annotations.Test)

Example 5 with Tenant

use of org.killbill.billing.client.model.Tenant in project killbill by killbill.

the class TestCatalog method testAddSimplePlanWithoutKBDefault.

@Test(groups = "slow", description = "Upload and retrieve a per plugin payment state machine config")
public void testAddSimplePlanWithoutKBDefault() throws Exception {
    // Create another tenant initialized with no default catalog,...
    final Tenant otherTenantNoKBDefault = new Tenant();
    otherTenantNoKBDefault.setApiKey(UUID.randomUUID().toString());
    otherTenantNoKBDefault.setApiSecret(UUID.randomUUID().toString());
    killBillClient.createTenant(otherTenantNoKBDefault, false, requestOptions);
    final RequestOptions requestOptionsOtherTenant = requestOptions.extend().withTenantApiKey(otherTenantNoKBDefault.getApiKey()).withTenantApiSecret(otherTenantNoKBDefault.getApiSecret()).build();
    // Verify the template catalog is not returned
    List<Catalog> catalogsJson = killBillClient.getJSONCatalog(requestOptionsOtherTenant);
    Assert.assertEquals(catalogsJson.size(), 0);
    killBillClient.addSimplePan(new SimplePlan("foo-monthly", "Foo", ProductCategory.BASE, Currency.USD, BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of()), requestOptionsOtherTenant);
    catalogsJson = killBillClient.getJSONCatalog(requestOptionsOtherTenant);
    Assert.assertEquals(catalogsJson.size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getProducts().size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getProducts().get(0).getName(), "Foo");
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getName(), "DEFAULT");
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().get(0), "foo-monthly");
    killBillClient.addSimplePan(new SimplePlan("foo-annual", "Foo", ProductCategory.BASE, Currency.USD, new BigDecimal("100.00"), BillingPeriod.ANNUAL, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of()), requestOptionsOtherTenant);
    catalogsJson = killBillClient.getJSONCatalog(requestOptionsOtherTenant);
    Assert.assertEquals(catalogsJson.size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getProducts().size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getProducts().get(0).getName(), "Foo");
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().size(), 1);
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getName(), "DEFAULT");
    Assert.assertEquals(catalogsJson.get(0).getPriceLists().get(0).getPlans().size(), 2);
}
Also used : SimplePlan(org.killbill.billing.client.model.SimplePlan) Tenant(org.killbill.billing.client.model.Tenant) RequestOptions(org.killbill.billing.client.RequestOptions) Catalog(org.killbill.billing.client.model.Catalog) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Aggregations

Tenant (org.killbill.billing.client.model.Tenant)6 Test (org.testng.annotations.Test)5 RequestOptions (org.killbill.billing.client.RequestOptions)3 KillBillClientException (org.killbill.billing.client.KillBillClientException)2 Account (org.killbill.billing.client.model.Account)2 TenantKey (org.killbill.billing.client.model.TenantKey)2 BigDecimal (java.math.BigDecimal)1 HashMap (java.util.HashMap)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Ehcache (net.sf.ehcache.Ehcache)1 LocalDate (org.joda.time.LocalDate)1 Catalog (org.killbill.billing.client.model.Catalog)1 Payment (org.killbill.billing.client.model.Payment)1 Payments (org.killbill.billing.client.model.Payments)1 SimplePlan (org.killbill.billing.client.model.SimplePlan)1 ObjectMapper (org.killbill.billing.util.jackson.ObjectMapper)1 BeforeMethod (org.testng.annotations.BeforeMethod)1