From 3e312d91d8644af0f098ec69f109a52423b8171b Mon Sep 17 00:00:00 2001 From: Stefan Guilhen Date: Fri, 21 Nov 2025 18:47:16 -0300 Subject: [PATCH] Ensure null values are not serialized when fetching workflows in YAML format Closes #44396 Signed-off-by: Stefan Guilhen --- .../representations/workflows/WorkflowRepresentation.java | 3 ++- .../representations/workflows/WorkflowStepRepresentation.java | 3 ++- .../org/keycloak/workflow/admin/resource/WorkflowResource.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java b/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java index 80c19768f57..120b8d2dfe9 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java @@ -8,6 +8,7 @@ import org.keycloak.common.util.MultivaluedHashMap; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -25,6 +26,7 @@ import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_WI @JsonPropertyOrder({"id", CONFIG_NAME, CONFIG_USES, CONFIG_ENABLED, CONFIG_ON_EVENT, CONFIG_CONCURRENCY, CONFIG_IF, CONFIG_STEPS, CONFIG_STATE}) @JsonIgnoreProperties(CONFIG_WITH) +@JsonInclude(JsonInclude.Include.NON_NULL) public final class WorkflowRepresentation extends AbstractWorkflowComponentRepresentation { public static Builder withName(String name) { @@ -137,7 +139,6 @@ public final class WorkflowRepresentation extends AbstractWorkflowComponentRepre return false; } WorkflowRepresentation that = (WorkflowRepresentation) obj; - // TODO: include state in comparison? return Objects.equals(getConfig(), that.getConfig()) && Objects.equals(getSteps(), that.getSteps()); } diff --git a/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java b/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java index b20bcd99ce6..c6592fc1700 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java @@ -18,7 +18,7 @@ import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_US import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_WITH; @JsonPropertyOrder({CONFIG_USES, CONFIG_AFTER, CONFIG_PRIORITY, CONFIG_WITH}) -@JsonInclude(JsonInclude.Include.NON_EMPTY) +@JsonInclude(JsonInclude.Include.NON_NULL) public final class WorkflowStepRepresentation extends AbstractWorkflowComponentRepresentation { private final String uses; @@ -51,6 +51,7 @@ public final class WorkflowStepRepresentation extends AbstractWorkflowComponentR @JsonSerialize(using = MultivaluedHashMapValueSerializer.class) @JsonDeserialize(using = MultivaluedHashMapValueDeserializer.class) + @JsonInclude(value=JsonInclude.Include.NON_EMPTY, content=JsonInclude.Include.NON_NULL) public MultivaluedHashMap getConfig() { return super.getConfig(); } diff --git a/services/src/main/java/org/keycloak/workflow/admin/resource/WorkflowResource.java b/services/src/main/java/org/keycloak/workflow/admin/resource/WorkflowResource.java index 6f11808ce1c..0d5d7bf1628 100644 --- a/services/src/main/java/org/keycloak/workflow/admin/resource/WorkflowResource.java +++ b/services/src/main/java/org/keycloak/workflow/admin/resource/WorkflowResource.java @@ -55,7 +55,7 @@ public class WorkflowResource { } @GET - @Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) + @Produces({YAMLMediaTypes.APPLICATION_JACKSON_YAML, MediaType.APPLICATION_JSON}) public WorkflowRepresentation toRepresentation( @Parameter(description = "Indicates whether the workflow id should be included in the representation or not - defaults to true") @QueryParam("includeId") Boolean includeId ) {