From bbf78ddbcc9cf7f3b7f43db389348672298c75d1 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Tue, 9 Jun 2026 01:22:54 +0000 Subject: [PATCH] Regenerate client from commit 302b39c of spec repo --- .generator/schemas/v2/openapi.yaml | 40 ++++++---- ...llocationsForFeatureFlagInEnvironment.java | 3 + ...llocationsForFeatureFlagInEnvironment.java | 3 + .../api/client/v2/model/Condition.java | 74 +++++++++++++++---- .../api/client/v2/model/ConditionRequest.java | 72 ++++++++++++------ .../api/client/v2/api/feature_flags.feature | 20 ++--- 6 files changed, 151 insertions(+), 61 deletions(-) diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 2d470c8f2f0..c5b00f59f4f 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -19568,10 +19568,14 @@ components: - CONTAINER - CALLOUTVALUE Condition: - description: Targeting condition details. + description: |- + Targeting condition details. A condition is either an inline + predicate with `operator`, `attribute`, and `value`, or a reference to a + saved filter with `saved_filter_id`. The inline fields are omitted for saved-filter + references. properties: attribute: - description: The user or request attribute to evaluate. + description: The user or request attribute to evaluate. Omitted for saved-filter references. example: "country" type: string created_at: @@ -19586,13 +19590,19 @@ components: type: string operator: $ref: "#/components/schemas/ConditionOperator" + saved_filter_id: + description: The ID of the saved filter referenced by this condition, or null for inline conditions. + example: "550e8400-e29b-41d4-a716-446655440090" + format: uuid + nullable: true + type: string updated_at: description: The timestamp when the condition was last updated. example: "2024-01-01T12:00:00Z" format: date-time type: string value: - description: Values used by the selected operator. + description: Values used by the selected operator. Omitted for saved-filter references. example: ["US", "CA"] items: description: Target value for the selected operator. @@ -19600,9 +19610,6 @@ components: type: array required: - id - - operator - - attribute - - value - created_at - updated_at type: object @@ -19633,25 +19640,32 @@ components: - IS_NULL - EQUALS ConditionRequest: - description: Condition request payload for targeting rules. + description: |- + Condition request payload for targeting rules. A condition is either an inline + predicate with `operator`, `attribute`, and `value`, or a reference to a + saved filter with `saved_filter_id`. The two shapes are mutually exclusive. properties: attribute: - description: The user or request attribute to evaluate. + description: The user or request attribute to evaluate. Required for inline conditions; omit when `saved_filter_id` is set. example: "user_tier" type: string operator: $ref: "#/components/schemas/ConditionOperator" + saved_filter_id: + description: |- + The ID of a saved filter to reference as this condition. Mutually exclusive + with `operator`, `attribute`, and `value`. When set, the saved filter's + targeting rules are evaluated in place of an inline predicate. + example: "550e8400-e29b-41d4-a716-446655440090" + format: uuid + type: string value: - description: Values used by the selected operator. + description: Values used by the selected operator. Required for inline conditions; omit when `saved_filter_id` is set. example: ["premium", "enterprise"] items: description: Target value for the selected operator. type: string type: array - required: - - operator - - attribute - - value type: object ConfigCatCredentials: description: The definition of the `ConfigCatCredentials` object. diff --git a/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java index ba79c235ada..2e5ec9610b2 100644 --- a/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java +++ b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java @@ -73,6 +73,9 @@ public static void main(String[] args) { new ConditionRequest() .attribute("user_tier") .operator(ConditionOperator.ONE_OF) + .savedFilterId( + UUID.fromString( + "550e8400-e29b-41d4-a716-446655440090")) .value( Arrays.asList("premium", "enterprise")))))) .type(AllocationType.FEATURE_GATE) diff --git a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java index eb0d514fc58..4feb3f0660f 100644 --- a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java +++ b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java @@ -75,6 +75,9 @@ public static void main(String[] args) { new ConditionRequest() .attribute("user_tier") .operator(ConditionOperator.ONE_OF) + .savedFilterId( + UUID.fromString( + "550e8400-e29b-41d4-a716-446655440090")) .value( Arrays.asList( "premium", "enterprise")))))) diff --git a/src/main/java/com/datadog/api/client/v2/model/Condition.java b/src/main/java/com/datadog/api/client/v2/model/Condition.java index b473d63a07b..96445b1835b 100644 --- a/src/main/java/com/datadog/api/client/v2/model/Condition.java +++ b/src/main/java/com/datadog/api/client/v2/model/Condition.java @@ -20,13 +20,19 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; +import org.openapitools.jackson.nullable.JsonNullable; -/** Targeting condition details. */ +/** + * Targeting condition details. A condition is either an inline predicate with operator + * , attribute, and value, or a reference to a saved filter with + * saved_filter_id. The inline fields are omitted for saved-filter references. + */ @JsonPropertyOrder({ Condition.JSON_PROPERTY_ATTRIBUTE, Condition.JSON_PROPERTY_CREATED_AT, Condition.JSON_PROPERTY_ID, Condition.JSON_PROPERTY_OPERATOR, + Condition.JSON_PROPERTY_SAVED_FILTER_ID, Condition.JSON_PROPERTY_UPDATED_AT, Condition.JSON_PROPERTY_VALUE }) @@ -46,29 +52,25 @@ public class Condition { public static final String JSON_PROPERTY_OPERATOR = "operator"; private ConditionOperator operator; + public static final String JSON_PROPERTY_SAVED_FILTER_ID = "saved_filter_id"; + private JsonNullable savedFilterId = JsonNullable.undefined(); + public static final String JSON_PROPERTY_UPDATED_AT = "updated_at"; private OffsetDateTime updatedAt; public static final String JSON_PROPERTY_VALUE = "value"; - private List value = new ArrayList<>(); + private List value = null; public Condition() {} @JsonCreator public Condition( - @JsonProperty(required = true, value = JSON_PROPERTY_ATTRIBUTE) String attribute, @JsonProperty(required = true, value = JSON_PROPERTY_CREATED_AT) OffsetDateTime createdAt, @JsonProperty(required = true, value = JSON_PROPERTY_ID) UUID id, - @JsonProperty(required = true, value = JSON_PROPERTY_OPERATOR) ConditionOperator operator, - @JsonProperty(required = true, value = JSON_PROPERTY_UPDATED_AT) OffsetDateTime updatedAt, - @JsonProperty(required = true, value = JSON_PROPERTY_VALUE) List value) { - this.attribute = attribute; + @JsonProperty(required = true, value = JSON_PROPERTY_UPDATED_AT) OffsetDateTime updatedAt) { this.createdAt = createdAt; this.id = id; - this.operator = operator; - this.unparsed |= !operator.isValid(); this.updatedAt = updatedAt; - this.value = value; } public Condition attribute(String attribute) { @@ -77,12 +79,13 @@ public Condition attribute(String attribute) { } /** - * The user or request attribute to evaluate. + * The user or request attribute to evaluate. Omitted for saved-filter references. * * @return attribute */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_ATTRIBUTE) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public String getAttribute() { return attribute; } @@ -142,8 +145,9 @@ public Condition operator(ConditionOperator operator) { * * @return operator */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_OPERATOR) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public ConditionOperator getOperator() { return operator; } @@ -155,6 +159,37 @@ public void setOperator(ConditionOperator operator) { this.operator = operator; } + public Condition savedFilterId(UUID savedFilterId) { + this.savedFilterId = JsonNullable.of(savedFilterId); + return this; + } + + /** + * The ID of the saved filter referenced by this condition, or null for inline conditions. + * + * @return savedFilterId + */ + @jakarta.annotation.Nullable + @JsonIgnore + public UUID getSavedFilterId() { + return savedFilterId.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_SAVED_FILTER_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getSavedFilterId_JsonNullable() { + return savedFilterId; + } + + @JsonProperty(JSON_PROPERTY_SAVED_FILTER_ID) + public void setSavedFilterId_JsonNullable(JsonNullable savedFilterId) { + this.savedFilterId = savedFilterId; + } + + public void setSavedFilterId(UUID savedFilterId) { + this.savedFilterId = JsonNullable.of(savedFilterId); + } + public Condition updatedAt(OffsetDateTime updatedAt) { this.updatedAt = updatedAt; return this; @@ -181,17 +216,21 @@ public Condition value(List value) { } public Condition addValueItem(String valueItem) { + if (this.value == null) { + this.value = new ArrayList<>(); + } this.value.add(valueItem); return this; } /** - * Values used by the selected operator. + * Values used by the selected operator. Omitted for saved-filter references. * * @return value */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_VALUE) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public List getValue() { return value; } @@ -260,6 +299,7 @@ public boolean equals(Object o) { && Objects.equals(this.createdAt, condition.createdAt) && Objects.equals(this.id, condition.id) && Objects.equals(this.operator, condition.operator) + && Objects.equals(this.savedFilterId, condition.savedFilterId) && Objects.equals(this.updatedAt, condition.updatedAt) && Objects.equals(this.value, condition.value) && Objects.equals(this.additionalProperties, condition.additionalProperties); @@ -267,7 +307,8 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(attribute, createdAt, id, operator, updatedAt, value, additionalProperties); + return Objects.hash( + attribute, createdAt, id, operator, savedFilterId, updatedAt, value, additionalProperties); } @Override @@ -278,6 +319,7 @@ public String toString() { sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" operator: ").append(toIndentedString(operator)).append("\n"); + sb.append(" savedFilterId: ").append(toIndentedString(savedFilterId)).append("\n"); sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); sb.append(" value: ").append(toIndentedString(value)).append("\n"); sb.append(" additionalProperties: ") diff --git a/src/main/java/com/datadog/api/client/v2/model/ConditionRequest.java b/src/main/java/com/datadog/api/client/v2/model/ConditionRequest.java index 2b2641dd83a..33875b38685 100644 --- a/src/main/java/com/datadog/api/client/v2/model/ConditionRequest.java +++ b/src/main/java/com/datadog/api/client/v2/model/ConditionRequest.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -18,11 +17,17 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.UUID; -/** Condition request payload for targeting rules. */ +/** + * Condition request payload for targeting rules. A condition is either an inline predicate with + * operator, attribute, and value, or a reference to a saved + * filter with saved_filter_id. The two shapes are mutually exclusive. + */ @JsonPropertyOrder({ ConditionRequest.JSON_PROPERTY_ATTRIBUTE, ConditionRequest.JSON_PROPERTY_OPERATOR, + ConditionRequest.JSON_PROPERTY_SAVED_FILTER_ID, ConditionRequest.JSON_PROPERTY_VALUE }) @jakarta.annotation.Generated( @@ -35,21 +40,11 @@ public class ConditionRequest { public static final String JSON_PROPERTY_OPERATOR = "operator"; private ConditionOperator operator; - public static final String JSON_PROPERTY_VALUE = "value"; - private List value = new ArrayList<>(); - - public ConditionRequest() {} + public static final String JSON_PROPERTY_SAVED_FILTER_ID = "saved_filter_id"; + private UUID savedFilterId; - @JsonCreator - public ConditionRequest( - @JsonProperty(required = true, value = JSON_PROPERTY_ATTRIBUTE) String attribute, - @JsonProperty(required = true, value = JSON_PROPERTY_OPERATOR) ConditionOperator operator, - @JsonProperty(required = true, value = JSON_PROPERTY_VALUE) List value) { - this.attribute = attribute; - this.operator = operator; - this.unparsed |= !operator.isValid(); - this.value = value; - } + public static final String JSON_PROPERTY_VALUE = "value"; + private List value = null; public ConditionRequest attribute(String attribute) { this.attribute = attribute; @@ -57,12 +52,14 @@ public ConditionRequest attribute(String attribute) { } /** - * The user or request attribute to evaluate. + * The user or request attribute to evaluate. Required for inline conditions; omit when + * saved_filter_id is set. * * @return attribute */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_ATTRIBUTE) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public String getAttribute() { return attribute; } @@ -82,8 +79,9 @@ public ConditionRequest operator(ConditionOperator operator) { * * @return operator */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_OPERATOR) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public ConditionOperator getOperator() { return operator; } @@ -95,23 +93,51 @@ public void setOperator(ConditionOperator operator) { this.operator = operator; } + public ConditionRequest savedFilterId(UUID savedFilterId) { + this.savedFilterId = savedFilterId; + return this; + } + + /** + * The ID of a saved filter to reference as this condition. Mutually exclusive with operator + * , attribute, and value. When set, the saved filter's targeting + * rules are evaluated in place of an inline predicate. + * + * @return savedFilterId + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SAVED_FILTER_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public UUID getSavedFilterId() { + return savedFilterId; + } + + public void setSavedFilterId(UUID savedFilterId) { + this.savedFilterId = savedFilterId; + } + public ConditionRequest value(List value) { this.value = value; return this; } public ConditionRequest addValueItem(String valueItem) { + if (this.value == null) { + this.value = new ArrayList<>(); + } this.value.add(valueItem); return this; } /** - * Values used by the selected operator. + * Values used by the selected operator. Required for inline conditions; omit when + * saved_filter_id is set. * * @return value */ + @jakarta.annotation.Nullable @JsonProperty(JSON_PROPERTY_VALUE) - @JsonInclude(value = JsonInclude.Include.ALWAYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public List getValue() { return value; } @@ -178,13 +204,14 @@ public boolean equals(Object o) { ConditionRequest conditionRequest = (ConditionRequest) o; return Objects.equals(this.attribute, conditionRequest.attribute) && Objects.equals(this.operator, conditionRequest.operator) + && Objects.equals(this.savedFilterId, conditionRequest.savedFilterId) && Objects.equals(this.value, conditionRequest.value) && Objects.equals(this.additionalProperties, conditionRequest.additionalProperties); } @Override public int hashCode() { - return Objects.hash(attribute, operator, value, additionalProperties); + return Objects.hash(attribute, operator, savedFilterId, value, additionalProperties); } @Override @@ -193,6 +220,7 @@ public String toString() { sb.append("class ConditionRequest {\n"); sb.append(" attribute: ").append(toIndentedString(attribute)).append("\n"); sb.append(" operator: ").append(toIndentedString(operator)).append("\n"); + sb.append(" savedFilterId: ").append(toIndentedString(savedFilterId)).append("\n"); sb.append(" value: ").append(toIndentedString(value)).append("\n"); sb.append(" additionalProperties: ") .append(toIndentedString(additionalProperties)) diff --git a/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature b/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature index df31d246a42..d8238606bff 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature +++ b/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature @@ -90,7 +90,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 202 Accepted - Approval required for this change @@ -99,7 +99,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 400 Bad Request @@ -108,7 +108,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 409 Conflict @@ -117,7 +117,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 201 Created @@ -126,7 +126,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 404 Not Found @@ -449,7 +449,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 202 Accepted - Approval required for this change @@ -458,7 +458,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 400 Bad Request @@ -467,7 +467,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 409 Conflict @@ -476,7 +476,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 404 Not Found @@ -485,6 +485,6 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 200 OK