diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
index 1e51050..000d28d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
@@ -59,9 +59,12 @@ import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.clock.Clock;
import org.killbill.commons.metrics.TimedResource;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Ordering;
import com.google.inject.Singleton;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -124,8 +127,11 @@ public class UsageResource extends JaxRsResourceBase {
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
// Verify subscription exists..
final Entitlement entitlement = entitlementApi.getEntitlementForId(json.getSubscriptionId(), callContext);
- if (entitlement.getState() != EntitlementState.ACTIVE) {
- return Response.status(Status.BAD_REQUEST).build();
+ if (entitlement.getEffectiveEndDate() != null) {
+ final LocalDate highestRecordDate = getHighestRecordDate(json.getUnitUsageRecords());
+ if (entitlement.getEffectiveEndDate().compareTo(highestRecordDate) < 0) {
+ return Response.status(Status.BAD_REQUEST).build();
+ }
}
final SubscriptionUsageRecord record = json.toSubscriptionUsageRecord();
@@ -133,6 +139,28 @@ public class UsageResource extends JaxRsResourceBase {
return Response.status(Status.CREATED).build();
}
+ @VisibleForTesting
+ LocalDate getHighestRecordDate(final List<UnitUsageRecordJson> records) {
+ final Iterable<Iterable<LocalDate>> recordedDates = Iterables.transform(records, new Function<UnitUsageRecordJson, Iterable<LocalDate>>() {
+
+ @Override
+ public Iterable<LocalDate> apply(final UnitUsageRecordJson input) {
+ final Iterable<LocalDate> result = Iterables.transform(input.getUsageRecords(), new Function<UsageRecordJson, LocalDate>() {
+ @Override
+ public LocalDate apply(final UsageRecordJson input) {
+ return input.getRecordDate();
+ }
+ });
+ return result;
+ }
+ });
+ final Iterable<LocalDate> sortedRecordedDates = Ordering.<LocalDate>natural()
+ .reverse()
+ .sortedCopy(Iterables.concat(recordedDates));
+
+ return Iterables.getFirst(sortedRecordedDates, null);
+ }
+
@TimedResource
@GET
@Path("/{subscriptionId:" + UUID_PATTERN + "}/{unitType}")
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
index 85195c0..979f012 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
@@ -19,7 +19,10 @@ package org.killbill.billing.jaxrs.resources;
import java.util.List;
+import org.joda.time.LocalDate;
import org.killbill.billing.jaxrs.JaxrsTestSuiteNoDB;
+import org.killbill.billing.jaxrs.json.SubscriptionUsageRecordJson.UnitUsageRecordJson;
+import org.killbill.billing.jaxrs.json.SubscriptionUsageRecordJson.UsageRecordJson;
import org.killbill.billing.payment.api.PluginProperty;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -67,4 +70,50 @@ public class TestJaxRsResourceBase extends JaxrsTestSuiteNoDB {
super(null, null, null, null, null, null, null, null, null);
}
}
+
+
+ @Test(groups = "fast")
+ public void testGetHighestRecordDate() throws Exception {
+ final UsageResourceTest usageResource = new UsageResourceTest();
+
+ final List<UsageRecordJson> fooRecords = ImmutableList.<UsageRecordJson>builder()
+ .add(new UsageRecordJson(new LocalDate(2018, 03, 04), 28L))
+ .add(new UsageRecordJson(new LocalDate(2018, 03, 05), 2L))
+ .add(new UsageRecordJson(new LocalDate(2018, 03, 01), 1L))
+ .add(new UsageRecordJson(new LocalDate(2018, 04, 06), 24L))
+ .build();
+ final UnitUsageRecordJson unitRecordFoo = new UnitUsageRecordJson("foo", fooRecords);
+
+ final List<UsageRecordJson> barRecords = ImmutableList.<UsageRecordJson>builder()
+ .add(new UsageRecordJson(new LocalDate(2018, 02, 04), 28L))
+ .add(new UsageRecordJson(new LocalDate(2018, 03, 06), 2L))
+ .add(new UsageRecordJson(new LocalDate(2018, 04, 18), 1L)) // Highest date point
+ .add(new UsageRecordJson(new LocalDate(2018, 04, 13), 24L))
+ .build();
+ final UnitUsageRecordJson unitRecordBar = new UnitUsageRecordJson("bar", barRecords);
+
+ final List<UsageRecordJson> zooRecords = ImmutableList.<UsageRecordJson>builder()
+ .add(new UsageRecordJson(new LocalDate(2018, 02, 04), 28L))
+ .add(new UsageRecordJson(new LocalDate(2018, 03, 06), 2L))
+ .add(new UsageRecordJson(new LocalDate(2018, 04, 17), 1L))
+ .add(new UsageRecordJson(new LocalDate(2018, 04, 12), 24L))
+ .build();
+ final UnitUsageRecordJson unitRecordZoo = new UnitUsageRecordJson("zoo", zooRecords);
+
+ final List<UnitUsageRecordJson> input = ImmutableList.<UnitUsageRecordJson>builder()
+ .add(unitRecordFoo)
+ .add(unitRecordBar)
+ .add(unitRecordZoo)
+ .build();
+ final LocalDate result = usageResource.getHighestRecordDate(input);
+
+ Assert.assertTrue(result.compareTo(new LocalDate(2018, 04, 18)) == 0);
+ }
+
+
+ private static class UsageResourceTest extends UsageResource {
+ public UsageResourceTest() {
+ super(null, null, null, null, null, null, null, null, null, null);
+ }
+ }
}