diff --git a/src/main/java/com/meteroid/api/Licenses.java b/src/main/java/com/meteroid/api/Licenses.java index 1321109..4af4741 100644 --- a/src/main/java/com/meteroid/api/Licenses.java +++ b/src/main/java/com/meteroid/api/Licenses.java @@ -195,7 +195,8 @@ MeteroidHttpClient.Exchange exchangeRetrieve( /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @return the response body @@ -207,7 +208,8 @@ public LicenseActivationCode retrieveActivationCode(final String licenseId) { /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @param requestOptions headers, timeout and retries of this call @@ -475,7 +477,8 @@ public ApiResponse retrieve( /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @return the status, headers and body @@ -487,7 +490,8 @@ public ApiResponse retrieveActivationCode(final String li /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @param requestOptions headers, timeout and retries of this call diff --git a/src/main/java/com/meteroid/api/LicensesAsync.java b/src/main/java/com/meteroid/api/LicensesAsync.java index 9158a84..56304fd 100644 --- a/src/main/java/com/meteroid/api/LicensesAsync.java +++ b/src/main/java/com/meteroid/api/LicensesAsync.java @@ -139,7 +139,8 @@ public CompletableFuture retrieve( /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @return the response body, once received @@ -151,7 +152,8 @@ public CompletableFuture retrieveActivationCode(final Str /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @param requestOptions headers, timeout and retries of this call @@ -353,7 +355,8 @@ public CompletableFuture> retrieve( /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @return the status, headers and body, once received @@ -366,7 +369,8 @@ public CompletableFuture> retrieveActivationC /** * Get a license's activation code * - *

Available until the license is activated or revoked. + *

Available until the license is activated or revoked; for an ephemeral license, until + * revoked. * * @param licenseId the {@code license_id} path parameter * @param requestOptions headers, timeout and retries of this call diff --git a/src/main/java/com/meteroid/models/IssueLicenseRequest.java b/src/main/java/com/meteroid/models/IssueLicenseRequest.java index d0ef579..9269ce3 100644 --- a/src/main/java/com/meteroid/models/IssueLicenseRequest.java +++ b/src/main/java/com/meteroid/models/IssueLicenseRequest.java @@ -29,6 +29,10 @@ public final class IssueLicenseRequest { @JsonProperty("customer_id") private String customerId; + @JsonProperty("ephemeral_hours") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private JsonField ephemeralHours = JsonField.missing(); + @JsonProperty("instance_id") @JsonInclude(JsonInclude.Include.NON_EMPTY) private JsonField instanceId = JsonField.missing(); @@ -50,6 +54,7 @@ private IssueLicenseRequest() {} private IssueLicenseRequest(Builder builder) { this.customerId = builder.customerId; + this.ephemeralHours = builder.ephemeralHours; this.instanceId = builder.instanceId; this.offline = builder.offline; this.subscriptionId = builder.subscriptionId; @@ -74,6 +79,7 @@ public static Builder builder() { public Builder toBuilder() { Builder builder = new Builder(); builder.customerId = customerId; + builder.ephemeralHours = ephemeralHours; builder.instanceId = instanceId; builder.offline = offline; builder.subscriptionId = subscriptionId; @@ -91,6 +97,18 @@ public String customerId() { return Utils.required(customerId, "customer_id"); } + /** + * Ephemeral, for CI and other short-lived installations: the activation code can be used any + * number of times, each activation gets a license of this many hours (1 to 24) for the + * installation activating, and nothing is refreshed. Not with offline or + * validity_days. + * + * @return the value, empty when unset or null + */ + public Optional ephemeralHours() { + return ephemeralHours.asOptional(); + } + /** * Offline only. The installation's id as it reports it, up to 255 characters without spaces: * the license names it (aud) and stays bound to it. Without one, the license is @@ -161,6 +179,7 @@ public boolean equals(Object o) { } IssueLicenseRequest that = (IssueLicenseRequest) o; return Objects.equals(customerId, that.customerId) + && Objects.equals(ephemeralHours, that.ephemeralHours) && Objects.equals(instanceId, that.instanceId) && Objects.equals(offline, that.offline) && Objects.equals(subscriptionId, that.subscriptionId) @@ -172,6 +191,7 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash( customerId, + ephemeralHours, instanceId, offline, subscriptionId, @@ -184,6 +204,8 @@ public String toString() { return "IssueLicenseRequest{" + "customerId=" + customerId + + ", ephemeralHours=" + + ephemeralHours + ", instanceId=" + instanceId + ", offline=" @@ -200,6 +222,7 @@ public String toString() { /** Builds {@link IssueLicenseRequest}. */ public static final class Builder { private String customerId; + private JsonField ephemeralHours = JsonField.missing(); private JsonField instanceId = JsonField.missing(); private Boolean offline; private JsonField subscriptionId = JsonField.missing(); @@ -219,6 +242,20 @@ public Builder customerId(String customerId) { return this; } + /** + * Ephemeral, for CI and other short-lived installations: the activation code can be used + * any number of times, each activation gets a license of this many hours (1 to 24) for the + * installation activating, and nothing is refreshed. Not with offline or + * validity_days. + * + * @param ephemeralHours the value, null to send an explicit {@code null} + * @return this builder + */ + public Builder ephemeralHours(Integer ephemeralHours) { + this.ephemeralHours = JsonField.ofNullable(ephemeralHours); + return this; + } + /** * Offline only. The installation's id as it reports it, up to 255 characters without * spaces: the license names it (aud) and stays bound to it. Without one, the diff --git a/src/main/java/com/meteroid/models/IssueLicenseResponse.java b/src/main/java/com/meteroid/models/IssueLicenseResponse.java index c27c61a..7203e7f 100644 --- a/src/main/java/com/meteroid/models/IssueLicenseResponse.java +++ b/src/main/java/com/meteroid/models/IssueLicenseResponse.java @@ -73,6 +73,7 @@ public Builder toBuilder() { /** * Online: one-time code the customer enters in their installation to activate the license. + * Ephemeral: the reusable code, e.g. a CI secret. * * @return the value, empty when unset or null */ @@ -162,6 +163,7 @@ private Builder() {} /** * Online: one-time code the customer enters in their installation to activate the license. + * Ephemeral: the reusable code, e.g. a CI secret. * * @param activationCode the value, null to send an explicit {@code null} * @return this builder diff --git a/src/main/java/com/meteroid/models/License.java b/src/main/java/com/meteroid/models/License.java index 460ca3b..f396267 100644 --- a/src/main/java/com/meteroid/models/License.java +++ b/src/main/java/com/meteroid/models/License.java @@ -39,6 +39,10 @@ public final class License { @JsonProperty("customer_name") private String customerName; + @JsonProperty("ephemeral_hours") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private JsonField ephemeralHours = JsonField.missing(); + @JsonProperty("has_activation_code") private Boolean hasActivationCode; @@ -86,6 +90,7 @@ private License(Builder builder) { this.createdAt = builder.createdAt; this.customerId = builder.customerId; this.customerName = builder.customerName; + this.ephemeralHours = builder.ephemeralHours; this.hasActivationCode = builder.hasActivationCode; this.id = builder.id; this.instanceId = builder.instanceId; @@ -120,6 +125,7 @@ public Builder toBuilder() { builder.createdAt = createdAt; builder.customerId = customerId; builder.customerName = customerName; + builder.ephemeralHours = ephemeralHours; builder.hasActivationCode = hasActivationCode; builder.id = id; builder.instanceId = instanceId; @@ -171,6 +177,15 @@ public String customerName() { return Utils.required(customerName, "customer_name"); } + /** + * Ephemeral: each activation of the reusable code gets a license of this many hours. + * + * @return the value, empty when unset or null + */ + public Optional ephemeralHours() { + return ephemeralHours.asOptional(); + } + /** * Whether the activation code can still be retrieved: only until activation or revocation. * @@ -304,6 +319,7 @@ public boolean equals(Object o) { && Objects.equals(createdAt, that.createdAt) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) + && Objects.equals(ephemeralHours, that.ephemeralHours) && Objects.equals(hasActivationCode, that.hasActivationCode) && Objects.equals(id, that.id) && Objects.equals(instanceId, that.instanceId) @@ -325,6 +341,7 @@ public int hashCode() { createdAt, customerId, customerName, + ephemeralHours, hasActivationCode, id, instanceId, @@ -350,6 +367,8 @@ public String toString() { + customerId + ", customerName=" + customerName + + ", ephemeralHours=" + + ephemeralHours + ", hasActivationCode=" + hasActivationCode + ", id=" @@ -383,6 +402,7 @@ public static final class Builder { private OffsetDateTime createdAt; private String customerId; private String customerName; + private JsonField ephemeralHours = JsonField.missing(); private Boolean hasActivationCode; private String id; private JsonField instanceId = JsonField.missing(); @@ -442,6 +462,17 @@ public Builder customerName(String customerName) { return this; } + /** + * Ephemeral: each activation of the reusable code gets a license of this many hours. + * + * @param ephemeralHours the value, null to send an explicit {@code null} + * @return this builder + */ + public Builder ephemeralHours(Integer ephemeralHours) { + this.ephemeralHours = JsonField.ofNullable(ephemeralHours); + return this; + } + /** * Whether the activation code can still be retrieved: only until activation or revocation. * diff --git a/src/test/java/com/meteroid/api/LicensesTest.java b/src/test/java/com/meteroid/api/LicensesTest.java index 11e08a1..0ae02e6 100644 --- a/src/test/java/com/meteroid/api/LicensesTest.java +++ b/src/test/java/com/meteroid/api/LicensesTest.java @@ -15,7 +15,7 @@ void list() throws Exception { new PerseidMock( 200, "application/json", - "{\"data\":[{\"auto_issued\":false,\"created_at\":\"2023-12-31T23:59:59.999-05:30\",\"customer_id\":\"customer_id_2\",\"customer_name\":\"sample\",\"has_activation_code\":false,\"id\":\"license_id_0\",\"offline\":false,\"revoked_immediately\":false,\"status\":\"REVOKED\",\"validity_days\":-123456789}]}"); + "{\"data\":[{\"auto_issued\":false,\"created_at\":\"2023-12-31T23:59:59.999-05:30\",\"customer_id\":\"customer_id_2\",\"customer_name\":\"sample\",\"has_activation_code\":true,\"id\":\"license_id_78\",\"offline\":false,\"revoked_immediately\":false,\"status\":\"PENDING\",\"validity_days\":2147483647}]}"); mock.client.licenses().list(); assertEquals(List.of("GET /api/v1/licenses"), mock.requests); } @@ -26,7 +26,7 @@ void create() throws Exception { new PerseidMock( 200, "application/json", - "{\"license\":{\"auto_issued\":false,\"created_at\":\"2023-12-31T23:59:59.999-05:30\",\"customer_id\":\"customer_id_37\",\"customer_name\":\"sample\",\"has_activation_code\":true,\"id\":\"license_id_40\",\"offline\":true,\"revoked_immediately\":true,\"status\":\"PENDING\",\"validity_days\":123456789}}"); + "{\"license\":{\"auto_issued\":false,\"created_at\":\"2023-12-31T23:59:59.999-05:30\",\"customer_id\":\"customer_id_37\",\"customer_name\":\"sample\",\"has_activation_code\":true,\"id\":\"license_id_32\",\"offline\":true,\"revoked_immediately\":false,\"status\":\"REVOKED\",\"validity_days\":2147483647}}"); mock.client .licenses() .create( @@ -42,7 +42,7 @@ void retrieve() throws Exception { new PerseidMock( 200, "application/json", - "{\"auto_issued\":false,\"created_at\":\"2024-03-15T10:30:45.123+02:00\",\"customer_id\":\"customer_id_79\",\"customer_name\":\"sample\",\"has_activation_code\":false,\"id\":\"license_id_90\",\"offline\":false,\"revoked_immediately\":true,\"status\":\"PENDING\",\"validity_days\":-123456789}"); + "{\"auto_issued\":false,\"created_at\":\"2024-03-15T10:30:45.123+02:00\",\"customer_id\":\"customer_id_79\",\"customer_name\":\"sample\",\"has_activation_code\":true,\"id\":\"license_id_13\",\"offline\":true,\"revoked_immediately\":false,\"status\":\"PENDING\",\"validity_days\":-2147483648}"); mock.client.licenses().retrieve("license_id"); assertEquals(List.of("GET /api/v1/licenses/license_id"), mock.requests); } @@ -74,7 +74,7 @@ void revoke() throws Exception { new PerseidMock( 200, "application/json", - "{\"auto_issued\":false,\"created_at\":\"2024-03-15T10:30:45.123+02:00\",\"customer_id\":\"customer_id_79\",\"customer_name\":\"sample\",\"has_activation_code\":false,\"id\":\"license_id_90\",\"offline\":false,\"revoked_immediately\":true,\"status\":\"PENDING\",\"validity_days\":-123456789}"); + "{\"auto_issued\":false,\"created_at\":\"2024-03-15T10:30:45.123+02:00\",\"customer_id\":\"customer_id_79\",\"customer_name\":\"sample\",\"has_activation_code\":true,\"id\":\"license_id_13\",\"offline\":true,\"revoked_immediately\":false,\"status\":\"PENDING\",\"validity_days\":-2147483648}"); mock.client .licenses() .revoke(