Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public static void main(String[] args) throws IOException {

// Updating (novating) the contract to version of 2025
SubscriptionUpdateRequest upReq = SubscriptionUpdateRequest.builder()
.service("WireMock", "2025")
.startService("WireMock", "2025")
.plan("Enterprise")
.add();
.endService()
.build();

Subscription updatedSubscription = client.contracts().updateContractByUserId(userId, upReq);
System.out.println(updatedSubscription);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import io.github.pgmarc.space.deserializers.ErrorDeserializer;
import io.github.pgmarc.space.deserializers.FeatureEvaluationDeserializer;
import io.github.pgmarc.space.exceptions.SpaceApiException;
import io.github.pgmarc.space.features.Consumption;
import io.github.pgmarc.space.features.Revert;
import io.github.pgmarc.space.features.UsageLimitConsumption;
import io.github.pgmarc.space.features.FeatureEvaluationResult;
import io.github.pgmarc.space.serializers.ConsumptionSerializer;
import okhttp3.*;
Expand Down Expand Up @@ -56,11 +57,11 @@ public FeatureEvaluationResult evaluate(String userId, String service, String fe
return res;
}

public FeatureEvaluationResult evaluateOptimistically(String userId, String service, String featureId, Consumption consumption)
public FeatureEvaluationResult evaluateOptimistically(String userId, String service, String featureId, UsageLimitConsumption usageLimitConsumption)
throws IOException {
HttpUrl url = this.baseUrl.newBuilder().addEncodedPathSegment(userId)
.addEncodedPathSegment(formatFeatureId(service, featureId)).build();
RequestBody body = RequestBody.create(consumptionSerializer.toJson(consumption).toString(), JSON);
RequestBody body = RequestBody.create(consumptionSerializer.toJson(usageLimitConsumption).toString(), JSON);
Request request = new Request(url, requiredHeaders ,"POST" , body);

FeatureEvaluationResult res = null;
Expand All @@ -77,20 +78,6 @@ public FeatureEvaluationResult evaluateOptimistically(String userId, String serv
return res;
}

public enum Revert {
OLDEST_VALUE(false),
NEWEST_VALUE(true);

private final boolean latest;

Revert(boolean latest) {
this.latest = latest;
}

public boolean isLatest() {
return latest;
}
}

public boolean revert(String userId, String service, String feature, Revert revert) throws IOException {
HttpUrl url = this.baseUrl.newBuilder().addEncodedPathSegment(userId)
Expand Down Expand Up @@ -118,7 +105,6 @@ public String generatePricingTokenForUser(String userId) throws IOException {
.addPathSegment("pricing-token").build();
Request request = new Request(url, requiredHeaders ,"POST" , RequestBody.EMPTY);

FeatureEvaluationResult res = null;
try (Response response = client.newCall(request).execute()) {
JSONObject jsonResponse = new JSONObject(response.body().string());
if (!response.isSuccessful()) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package io.github.pgmarc.space.contracts;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -19,42 +16,49 @@ public final class Subscription {

private final UserContact userContact;
private final Map<String, Service> services;
private final BillingPeriod billingPeriod;
private final ZonedDateTime startDate;
private final ZonedDateTime endDate;
private final Period renewalPeriod;
private final List<Snapshot> history;
private final Map<String, Map<String, UsageLevel>> usageLevels;

private Subscription(Builder builder) {
this.userContact = builder.userContact;
this.billingPeriod = builder.billingPeriod;
this.startDate = builder.startDate;
this.endDate = builder.endDate;
this.renewalPeriod = builder.renewalPeriod;
this.services = Collections.unmodifiableMap(builder.services);
this.history = Collections.unmodifiableList(builder.history);
this.usageLevels = Collections.unmodifiableMap(builder.usageLevels);
}

public static Builder builder(UserContact userContact, BillingPeriod billingPeriod,
public static Builder builder(UserContact userContact, ZonedDateTime startDate, ZonedDateTime endDate,
Service service) {
return new Builder(userContact, billingPeriod).subscribe(service);
return new Builder(userContact, startDate, endDate).subscribe(service);
}

public static Builder builder(UserContact userContact, BillingPeriod billingPeriod,
Collection<Service> services) {
return new Builder(userContact, billingPeriod).subscribeAll(services);
public static Builder builder(UserContact userContact, ZonedDateTime startDate, ZonedDateTime endDate, Collection<Service> services) {
return new Builder(userContact, startDate, endDate).subscribeAll(services);
}

public LocalDateTime getStartDate() {
return billingPeriod.getStartDate();
return startDate.toLocalDateTime();
}

public LocalDateTime getEndDate() {
return billingPeriod.getEndDate();
return endDate.toLocalDateTime();
}

public Optional<Duration> getRenewalDuration() {
return Optional.of(billingPeriod.getDuration());
public Optional<Period> getRenewalPeriod() {
return Optional.of(renewalPeriod);
}

public boolean isAutoRenewable() {
return billingPeriod.isAutoRenewable();
return renewalPeriod != null;
}

public Optional<LocalDateTime> getRenewalDate() {
return Optional.ofNullable(isAutoRenewable() ? endDate.plus(renewalPeriod).toLocalDateTime() : null);
}

/**
Expand All @@ -64,7 +68,10 @@ public boolean isAutoRenewable() {
*/
public boolean isActive(LocalDateTime date) {
Objects.requireNonNull(date, "date must not be null");
return billingPeriod.isActive(ZonedDateTime.of(date, ZoneId.of("UTC")));
ZonedDateTime utcDate = ZonedDateTime.of(date, ZoneId.of("UTC"));

return (startDate.isEqual(utcDate) || startDate.isBefore(utcDate)) &&
(endDate.isAfter(utcDate) || endDate.isEqual(utcDate));
}

/**
Expand All @@ -73,12 +80,10 @@ public boolean isActive(LocalDateTime date) {
*/
public boolean isExpired(LocalDateTime date) {
Objects.requireNonNull(date, "date must not be null");
return billingPeriod.isExpired(ZonedDateTime.of(date, ZoneId.of("UTC")));
ZonedDateTime utcDate = ZonedDateTime.of(date, ZoneId.of("UTC"));
return startDate.isBefore(utcDate) && endDate.isBefore(utcDate);
}

public Optional<LocalDateTime> getRenewalDate() {
return billingPeriod.getRenewalDate();
}

public String getUserId() {
return userContact.getUserId();
Expand Down Expand Up @@ -114,7 +119,7 @@ public enum Keys {
CONTRACTED_SERVICES("contractedServices"),
SUBSCRIPTION_PLANS("subscriptionPlans"),
SUBSCRIPTION_ADDONS("subscriptionAddOns"),
USAGE_LEVEL("usageLevel"),
USAGE_LEVELS("usageLevels"),
HISTORY("history");

private final String name;
Expand All @@ -131,19 +136,37 @@ public String toString() {

public static final class Builder {

private final BillingPeriod billingPeriod;
private final ZonedDateTime startDate;
private final ZonedDateTime endDate;
private final UserContact userContact;
private final Map<String, Service> services = new HashMap<>();
private final List<Snapshot> history = new ArrayList<>();
private final Map<String, Map<String, UsageLevel>> usageLevels = new HashMap<>();
private Period renewalPeriod;

private Builder(UserContact userContact, BillingPeriod billingPeriod) {
this.billingPeriod = billingPeriod;
private Builder(UserContact userContact, ZonedDateTime startDate, ZonedDateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
this.userContact = userContact;
}

public Builder renewIn(Duration renewalDays) {
this.billingPeriod.setRenewalDays(renewalDays);
public Builder renewIn(Period renewalPeriod) {
this.renewalPeriod = renewalPeriod;
return this;
}

public Builder renewInDays(int days) {
this.renewalPeriod = Period.ofDays(days);
return this;
}

public Builder renewInMonths(int months) {
this.renewalPeriod = Period.ofMonths(months);
return this;
}

public Builder renewInYears(int years) {
this.renewalPeriod = Period.ofYears(years);
return this;
}

Expand Down Expand Up @@ -174,32 +197,51 @@ public Builder addUsageLevels(Map<String, Map<String, UsageLevel>> usageLevels)
return this;
}

private void validateSubscriptionInterval() {
Objects.requireNonNull(startDate, "start date must not be null");
Objects.requireNonNull(endDate, "end date must not be null");
if (startDate.isAfter(endDate)) {
throw new IllegalStateException("startDate is after endDate");
}
}

private void validateRenewalPeriod() {
if (renewalPeriod != null && renewalPeriod.isZero()) {
throw new IllegalArgumentException("your renewal period must not be zero");
}

if (renewalPeriod != null && renewalPeriod.isNegative()) {
throw new IllegalStateException("renewal period must not be negative");
}
}

public Subscription build() {
Objects.requireNonNull(billingPeriod, "billingPeriod must not be null");
Objects.requireNonNull(userContact, "userContact must not be null");
validateSubscriptionInterval();
validateRenewalPeriod();
return new Subscription(this);
}
}

public static final class Snapshot {

private final LocalDateTime starDateTime;
private final LocalDateTime endDateTime;
private final ZonedDateTime starDateTime;
private final ZonedDateTime endDateTime;
private final Map<String, Service> services;

private Snapshot(LocalDateTime startDateTime, LocalDateTime endDateTime,
private Snapshot(ZonedDateTime startDateTime, ZonedDateTime endDateTime,
Map<String, Service> services) {
this.starDateTime = startDateTime;
this.endDateTime = endDateTime;
this.services = new HashMap<>(services);
}

public LocalDateTime getStartDate() {
return starDateTime;
return starDateTime.toLocalDateTime();
}

public LocalDateTime getEndDate() {
return endDateTime;
return endDateTime.toLocalDateTime();
}

public Map<String, Service> getServices() {
Expand All @@ -210,7 +252,7 @@ public Optional<Service> getService(String name) {
return Optional.ofNullable(services.get(name));
}

public static Snapshot of(LocalDateTime startDateTime, LocalDateTime endDateTime,
public static Snapshot of(ZonedDateTime startDateTime, ZonedDateTime endDateTime,
Map<String, Service> services) {
return new Snapshot(startDateTime, endDateTime, services);
}
Expand Down
Loading