Add backup levels to subscription configuration response

This commit is contained in:
ravi-signal
2024-04-11 10:58:40 -05:00
committed by GitHub
parent 44ad9d4f5f
commit 4863e1d227
4 changed files with 281 additions and 70 deletions

View File

@@ -8,11 +8,15 @@ package org.whispersystems.textsecuregcm.configuration;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Sets;
import io.dropwizard.validation.ValidationMethod;
import java.time.Duration;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@@ -21,16 +25,23 @@ public class SubscriptionConfiguration {
private final Duration badgeGracePeriod;
private final Duration badgeExpiration;
private final Map<Long, SubscriptionLevelConfiguration> levels;
private final Duration backupExpiration;
private final Map<Long, SubscriptionLevelConfiguration.Donation> donationLevels;
private final Map<Long, SubscriptionLevelConfiguration.Backup> backupLevels;
@JsonCreator
public SubscriptionConfiguration(
@JsonProperty("badgeGracePeriod") @Valid Duration badgeGracePeriod,
@JsonProperty("badgeExpiration") @Valid Duration badgeExpiration,
@JsonProperty("levels") @Valid Map<@NotNull @Min(1) Long, @NotNull @Valid SubscriptionLevelConfiguration> levels) {
@JsonProperty("backupExpiration") @Valid Duration backupExpiration,
@JsonProperty("levels") @Valid Map<@NotNull @Min(1) Long, SubscriptionLevelConfiguration.@NotNull @Valid Donation> donationLevels,
@JsonProperty("backupLevels") @Valid Map<@NotNull @Min(1) Long, SubscriptionLevelConfiguration.@NotNull @Valid Backup> backupLevels) {
this.badgeGracePeriod = badgeGracePeriod;
this.badgeExpiration = badgeExpiration;
this.levels = levels;
this.donationLevels = donationLevels;
this.backupExpiration = backupExpiration;
this.backupLevels = backupLevels == null ? Collections.emptyMap() : backupLevels;
}
public Duration getBadgeGracePeriod() {
@@ -42,19 +53,43 @@ public class SubscriptionConfiguration {
return badgeExpiration;
}
public Map<Long, SubscriptionLevelConfiguration> getLevels() {
return levels;
public Duration getBackupExpiration() {
return backupExpiration;
}
public SubscriptionLevelConfiguration getSubscriptionLevel(long level) {
return Optional
.<SubscriptionLevelConfiguration>ofNullable(this.donationLevels.get(level))
.orElse(this.backupLevels.get(level));
}
public Map<Long, SubscriptionLevelConfiguration.Donation> getDonationLevels() {
return donationLevels;
}
public Map<Long, SubscriptionLevelConfiguration.Backup> getBackupLevels() {
return backupLevels;
}
@JsonIgnore
@ValidationMethod(message = "Backup levels and donation levels should not contain the same level identifier")
public boolean areLevelsNonOverlapping() {
return Sets.intersection(backupLevels.keySet(), donationLevels.keySet()).isEmpty();
}
@JsonIgnore
@ValidationMethod(message = "has a mismatch between the levels supported currencies")
public boolean isCurrencyListSameAcrossAllLevels() {
Optional<SubscriptionLevelConfiguration> any = levels.values().stream().findAny();
final Map<Long, SubscriptionLevelConfiguration> subscriptionLevels = Stream
.concat(donationLevels.entrySet().stream(), backupLevels.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Optional<SubscriptionLevelConfiguration> any = subscriptionLevels.values().stream().findAny();
if (any.isEmpty()) {
return true;
}
Set<String> currencies = any.get().getPrices().keySet();
return levels.values().stream().allMatch(level -> currencies.equals(level.getPrices().keySet()));
Set<String> currencies = any.get().prices().keySet();
return subscriptionLevels.values().stream().allMatch(level -> currencies.equals(level.prices().keySet()));
}
}

View File

@@ -5,31 +5,35 @@
package org.whispersystems.textsecuregcm.configuration;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
public class SubscriptionLevelConfiguration {
public sealed interface SubscriptionLevelConfiguration permits
SubscriptionLevelConfiguration.Backup, SubscriptionLevelConfiguration.Donation {
private final String badge;
private final Map<String, SubscriptionPriceConfiguration> prices;
Map<String, SubscriptionPriceConfiguration> prices();
@JsonCreator
public SubscriptionLevelConfiguration(
enum Type {
DONATION,
BACKUP
}
default Type type() {
return switch (this) {
case Backup b -> Type.BACKUP;
case Donation d -> Type.DONATION;
};
}
record Backup(
@JsonProperty("prices") @Valid Map<@NotEmpty String, @NotNull @Valid SubscriptionPriceConfiguration> prices)
implements SubscriptionLevelConfiguration {}
record Donation(
@JsonProperty("badge") @NotEmpty String badge,
@JsonProperty("prices") @Valid Map<@NotEmpty String, @NotNull @Valid SubscriptionPriceConfiguration> prices) {
this.badge = badge;
this.prices = prices;
}
public String getBadge() {
return badge;
}
public Map<String, SubscriptionPriceConfiguration> getPrices() {
return prices;
}
@JsonProperty("prices") @Valid Map<@NotEmpty String, @NotNull @Valid SubscriptionPriceConfiguration> prices)
implements SubscriptionLevelConfiguration {}
}