Skip to content

Commit

Permalink
server: add first draft of overdue endpoint
Browse files Browse the repository at this point in the history
I'm not sure yet how the overdue APIs should look like. They are
separate for now (/1.0/kb/overdue/...) but we might want to put them
under the blockable resources (e.g./1.0/kb/accounts/<accountId>/overdue).

These resources are currently useful for overdue server tests that I
just added and for Kaui (to display e.g. the bundle overdue state, if
any).

Signed-off-by: Pierre-Alexandre Meyer <pierre@ning.com>
  • Loading branch information
Pierre-Alexandre Meyer committed Aug 30, 2012
1 parent f1dfcf4 commit 9a80396
Show file tree
Hide file tree
Showing 11 changed files with 471 additions and 1 deletion.
165 changes: 165 additions & 0 deletions jaxrs/src/main/java/com/ning/billing/jaxrs/json/OverdueStateJson.java
@@ -0,0 +1,165 @@
/*
* Copyright 2010-2012 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.json;

import org.joda.time.Period;

import com.ning.billing.overdue.OverdueApiException;
import com.ning.billing.overdue.OverdueState;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class OverdueStateJson {

private final String name;
private final String externalMessage;
private final Integer daysBetweenPaymentRetries;
private final Boolean disableEntitlementAndChangesBlocked;
private final Boolean blockChanges;
private final Boolean isClearState;
private final Integer reevaluationIntervalDays;

@JsonCreator
public OverdueStateJson(@JsonProperty("name") final String name,
@JsonProperty("externalMessage") final String externalMessage,
@JsonProperty("daysBetweenPaymentRetries") final Integer daysBetweenPaymentRetries,
@JsonProperty("disableEntitlementAndChangesBlocked") final Boolean disableEntitlementAndChangesBlocked,
@JsonProperty("blockChanges") final Boolean blockChanges,
@JsonProperty("clearState") final Boolean isClearState,
@JsonProperty("reevaluationIntervalDays") final Integer reevaluationIntervalDays) {
this.name = name;
this.externalMessage = externalMessage;
this.daysBetweenPaymentRetries = daysBetweenPaymentRetries;
this.disableEntitlementAndChangesBlocked = disableEntitlementAndChangesBlocked;
this.blockChanges = blockChanges;
this.isClearState = isClearState;
this.reevaluationIntervalDays = reevaluationIntervalDays;
}

public OverdueStateJson(final OverdueState overdueState) {
this.name = overdueState.getName();
this.externalMessage = overdueState.getExternalMessage();
this.daysBetweenPaymentRetries = overdueState.getDaysBetweenPaymentRetries();
this.disableEntitlementAndChangesBlocked = overdueState.disableEntitlementAndChangesBlocked();
this.blockChanges = overdueState.blockChanges();
this.isClearState = overdueState.isClearState();

Period reevaluationIntervalPeriod = null;
try {
reevaluationIntervalPeriod = overdueState.getReevaluationInterval();
} catch (OverdueApiException ignored) {
}

if (reevaluationIntervalPeriod != null) {
this.reevaluationIntervalDays = reevaluationIntervalPeriod.getDays();
} else {
this.reevaluationIntervalDays = null;
}
}

public String getName() {
return name;
}

public String getExternalMessage() {
return externalMessage;
}

public Integer getDaysBetweenPaymentRetries() {
return daysBetweenPaymentRetries;
}

public Boolean isDisableEntitlementAndChangesBlocked() {
return disableEntitlementAndChangesBlocked;
}

public Boolean isBlockChanges() {
return blockChanges;
}

public Boolean isClearState() {
return isClearState;
}

public Integer getReevaluationIntervalDays() {
return reevaluationIntervalDays;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("OverdueStateJson");
sb.append("{name='").append(name).append('\'');
sb.append(", externalMessage='").append(externalMessage).append('\'');
sb.append(", daysBetweenPaymentRetries=").append(daysBetweenPaymentRetries);
sb.append(", disableEntitlementAndChangesBlocked=").append(disableEntitlementAndChangesBlocked);
sb.append(", blockChanges=").append(blockChanges);
sb.append(", isClearState=").append(isClearState);
sb.append(", reevaluationIntervalDays=").append(reevaluationIntervalDays);
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 OverdueStateJson that = (OverdueStateJson) o;

if (blockChanges != null ? !blockChanges.equals(that.blockChanges) : that.blockChanges != null) {
return false;
}
if (daysBetweenPaymentRetries != null ? !daysBetweenPaymentRetries.equals(that.daysBetweenPaymentRetries) : that.daysBetweenPaymentRetries != null) {
return false;
}
if (disableEntitlementAndChangesBlocked != null ? !disableEntitlementAndChangesBlocked.equals(that.disableEntitlementAndChangesBlocked) : that.disableEntitlementAndChangesBlocked != null) {
return false;
}
if (externalMessage != null ? !externalMessage.equals(that.externalMessage) : that.externalMessage != null) {
return false;
}
if (isClearState != null ? !isClearState.equals(that.isClearState) : that.isClearState != null) {
return false;
}
if (name != null ? !name.equals(that.name) : that.name != null) {
return false;
}
if (reevaluationIntervalDays != null ? !reevaluationIntervalDays.equals(that.reevaluationIntervalDays) : that.reevaluationIntervalDays != null) {
return false;
}

return true;
}

@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (externalMessage != null ? externalMessage.hashCode() : 0);
result = 31 * result + (daysBetweenPaymentRetries != null ? daysBetweenPaymentRetries.hashCode() : 0);
result = 31 * result + (disableEntitlementAndChangesBlocked != null ? disableEntitlementAndChangesBlocked.hashCode() : 0);
result = 31 * result + (blockChanges != null ? blockChanges.hashCode() : 0);
result = 31 * result + (isClearState != null ? isClearState.hashCode() : 0);
result = 31 * result + (reevaluationIntervalDays != null ? reevaluationIntervalDays.hashCode() : 0);
return result;
}
}
Expand Up @@ -119,4 +119,6 @@ public interface JaxrsResource {
public static final String CATALOG = "catalog";
public static final String CATALOG_PATH = PREFIX + "/" + CATALOG;

public static final String OVERDUE = "overdue";
public static final String OVERDUE_PATH = PREFIX + "/" + OVERDUE;
}
@@ -0,0 +1,92 @@
/*
* Copyright 2010-2012 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.UUID;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.jaxrs.json.OverdueStateJson;
import com.ning.billing.overdue.OverdueApiException;
import com.ning.billing.overdue.OverdueState;
import com.ning.billing.overdue.OverdueUserApi;
import com.ning.billing.overdue.config.api.OverdueError;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;

@Singleton
@Path(JaxrsResource.OVERDUE_PATH)
public class OverdueResource implements JaxrsResource {

private final OverdueUserApi overdueApi;
private final AccountUserApi accountApi;
private final EntitlementUserApi entitlementApi;

@Inject
public OverdueResource(final OverdueUserApi overdueApi,
final AccountUserApi accountApi,
final EntitlementUserApi entitlementApi) {
this.overdueApi = overdueApi;
this.accountApi = accountApi;
this.entitlementApi = entitlementApi;
}

@GET
@Path("/" + ACCOUNTS + "/{accountId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
public Response getOverdueAccount(@PathParam("accountId") final String accountId) throws AccountApiException, OverdueError, OverdueApiException {
final Account account = accountApi.getAccountById(UUID.fromString(accountId));
final OverdueState<Account> overdueState = overdueApi.getOverdueStateFor(account);

return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
}

@GET
@Path("/" + BUNDLES + "/{bundleId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
public Response getOverdueBundle(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException, OverdueError, OverdueApiException {
final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
final OverdueState<SubscriptionBundle> overdueState = overdueApi.getOverdueStateFor(bundle);

return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
}

@GET
@Path("/" + SUBSCRIPTIONS + "/{subscriptionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
public Response getOverdueSubscription(@PathParam("subscriptionId") final String subscriptionId) throws EntitlementUserApiException, OverdueError, OverdueApiException {
final Subscription subscription = entitlementApi.getSubscriptionFromId(UUID.fromString(subscriptionId));
final OverdueState<Subscription> overdueState = overdueApi.getOverdueStateFor(subscription);

return Response.status(Status.OK).entity(new OverdueStateJson(overdueState)).build();
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2012 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.json;

import java.util.UUID;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.ning.billing.jaxrs.JaxrsTestSuite;

public class TestOverdueStateJson extends JaxrsTestSuite {

@Test(groups = "fast")
public void testJson() throws Exception {
final String name = UUID.randomUUID().toString();
final String externalMessage = UUID.randomUUID().toString();
final int daysBetweenPaymentRetries = 12;
final boolean disableEntitlementAndChangesBlocked = true;
final boolean blockChanges = false;
final boolean clearState = true;
final int reevaluationIntervalDays = 100;
final OverdueStateJson overdueStateJson = new OverdueStateJson(name, externalMessage, daysBetweenPaymentRetries,
disableEntitlementAndChangesBlocked, blockChanges, clearState,
reevaluationIntervalDays);
Assert.assertEquals(overdueStateJson.getName(), name);
Assert.assertEquals(overdueStateJson.getExternalMessage(), externalMessage);
Assert.assertEquals(overdueStateJson.getDaysBetweenPaymentRetries(), (Integer) daysBetweenPaymentRetries);
Assert.assertEquals(overdueStateJson.isDisableEntitlementAndChangesBlocked(), (Boolean) disableEntitlementAndChangesBlocked);
Assert.assertEquals(overdueStateJson.isBlockChanges(), (Boolean) blockChanges);
Assert.assertEquals(overdueStateJson.isClearState(), (Boolean) clearState);
Assert.assertEquals(overdueStateJson.getReevaluationIntervalDays(), (Integer) reevaluationIntervalDays);

final String asJson = mapper.writeValueAsString(overdueStateJson);
final OverdueStateJson fromJson = mapper.readValue(asJson, OverdueStateJson.class);
Assert.assertEquals(fromJson, overdueStateJson);
}
}
Expand Up @@ -85,9 +85,13 @@ public OverdueConfig getOverdueConfig() {
public synchronized void loadConfig() throws ServiceException {
if (!isInitialized) {
try {
System.out.println("Overdue config URI" + properties.getConfigURI());
final URI u = new URI(properties.getConfigURI());
overdueConfig = XMLLoader.getObjectFromUri(u, OverdueConfig.class);
// File not found?
if (overdueConfig == null) {
log.warn("Unable to load the overdue config from " + properties.getConfigURI());
overdueConfig = new OverdueConfig();
}

isInitialized = true;
} catch (URISyntaxException e) {
Expand Down
4 changes: 4 additions & 0 deletions server/pom.xml
Expand Up @@ -191,6 +191,10 @@
<groupId>com.ning.billing</groupId>
<artifactId>killbill-junction</artifactId>
</dependency>
<dependency>
<groupId>com.ning.billing</groupId>
<artifactId>killbill-overdue</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand Down
Expand Up @@ -38,6 +38,7 @@
import com.ning.billing.jaxrs.resources.TagResource;
import com.ning.billing.jaxrs.util.KillbillEventHandler;
import com.ning.billing.junction.glue.DefaultJunctionModule;
import com.ning.billing.overdue.glue.DefaultOverdueModule;
import com.ning.billing.payment.glue.PaymentModule;
import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
Expand Down Expand Up @@ -105,6 +106,7 @@ protected void installKillbillModules() {
install(new PaymentModule());
install(new BeatrixModule());
install(new DefaultJunctionModule());
install(new DefaultOverdueModule());
installClock();
}
}

0 comments on commit 9a80396

Please sign in to comment.