Allow GET and PUT methods using application/yaml media type

Closes #42687

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2025-10-31 15:51:26 -03:00
parent 4d912a9c21
commit 2216ada20b
3 changed files with 37 additions and 27 deletions

View File

@ -1,7 +1,6 @@
package org.keycloak.workflow.admin.resource;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import com.fasterxml.jackson.jakarta.rs.yaml.YAMLMediaTypes;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
@ -52,7 +51,7 @@ public class WorkflowResource {
}
@GET
@Produces(APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML})
public WorkflowRepresentation toRepresentation() {
return manager.toRepresentation(workflow);
}

View File

@ -2,7 +2,6 @@ package org.keycloak.workflow.admin.resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import com.fasterxml.jackson.jakarta.rs.yaml.YAMLMediaTypes;
import jakarta.ws.rs.Consumes;
@ -79,10 +78,10 @@ public class WorkflowsResource {
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Stream<WorkflowRepresentation> list() {
@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML})
public List<WorkflowRepresentation> list() {
auth.realm().requireManageRealm();
return manager.getWorkflows().map(manager::toRepresentation);
return manager.getWorkflows().map(manager::toRepresentation).toList();
}
}

View File

@ -33,12 +33,16 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import com.fasterxml.jackson.jakarta.rs.yaml.JacksonYAMLProvider;
import com.fasterxml.jackson.jakarta.rs.yaml.YAMLMediaTypes;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import org.hamcrest.Matchers;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
@ -885,10 +889,11 @@ public class WorkflowManagementTest {
}
@Test
public void testCreateWorkflowsUsingYaml() throws IOException {
WorkflowSetRepresentation expectedWorkflows = WorkflowRepresentation.create()
public void testCreateUsingYaml() throws IOException {
YAMLMapper yamlMapper = YAMLMapper.builder().serializationInclusion(Include.NON_NULL).build();
WorkflowRepresentation expected = WorkflowRepresentation.create()
.of(UserCreationTimeWorkflowProviderFactory.ID)
.name(UserCreationTimeWorkflowProviderFactory.ID)
.name("test")
.withSteps(
WorkflowStepRepresentation.create().of(NotifyUserStepProviderFactory.ID)
.after(Duration.ofDays(5))
@ -896,35 +901,42 @@ public class WorkflowManagementTest {
WorkflowStepRepresentation.create().of(DisableUserStepProviderFactory.ID)
.after(Duration.ofDays(5))
.build()
).build();
).build().getWorkflows().get(0);
try (Client httpClient = Keycloak.getClientProvider().newRestEasyClient(null, null, true)) {
httpClient.register(JacksonYAMLProvider.class);
// multiple workflows
WebTarget target = httpClient.target(keycloakUrls.getBaseUrl().toString())
WebTarget workflowsApi = httpClient.target(keycloakUrls.getBaseUrl().toString())
.path("admin")
.path("realms")
.path(managedRealm.getName())
.path("workflows")
.path("set")
.register(new BearerAuthFilter(adminClient.tokenManager()));
Entity<WorkflowSetRepresentation> entitySet = Entity.entity(expectedWorkflows, YAMLMediaTypes.APPLICATION_JACKSON_YAML_TYPE);
try (Response response = target.request().post(entitySet)) {
assertThat(response.getStatus(), is(Response.Status.CREATED.getStatusCode()));
try (Response response = workflowsApi.request().post(Entity.entity(yamlMapper.writeValueAsString(expected),
YAMLMediaTypes.APPLICATION_JACKSON_YAML))) {
assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
}
// single workflow
target = httpClient.target(keycloakUrls.getBaseUrl().toString())
.path("admin")
.path("realms")
.path(managedRealm.getName())
.path("workflows")
.register(new BearerAuthFilter(adminClient.tokenManager()));
try (Response response = workflowsApi.request().accept(YAMLMediaTypes.APPLICATION_JACKSON_YAML).get()) {
assertEquals(Status.OK.getStatusCode(), response.getStatus());
List<WorkflowRepresentation> workflows = yamlMapper.readValue(response.readEntity(String.class),
new TypeReference<>() {
});
assertFalse(workflows.isEmpty());
expected = workflows.get(0);
}
Entity<WorkflowRepresentation> entity = Entity.entity(expectedWorkflows.getWorkflows().get(0), YAMLMediaTypes.APPLICATION_JACKSON_YAML_TYPE);
try (Response response = target.request().post(entity)) {
assertThat(response.getStatus(), is(Response.Status.CREATED.getStatusCode()));
try (Response response = workflowsApi.path(expected.getId()).request()
.accept(YAMLMediaTypes.APPLICATION_JACKSON_YAML).get()) {
assertEquals(Status.OK.getStatusCode(), response.getStatus());
WorkflowRepresentation actual = yamlMapper.readValue(response.readEntity(String.class), WorkflowRepresentation.class);
assertEquals(expected.getId(), actual.getId());
assertEquals(expected.getName(), actual.getName());
}
try (Response response = workflowsApi.path(expected.getId()).request()
.put(Entity.entity(yamlMapper.writeValueAsString(expected), YAMLMediaTypes.APPLICATION_JACKSON_YAML))) {
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
}
}
}