-
Notifications
You must be signed in to change notification settings - Fork 4
DO NOT MERGE: Adding flows and amending UI to handle different calm types to view #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
LeighFinegold
wants to merge
1
commit into
jpgough:main
Choose a base branch
from
LeighFinegold:calm-hub-flows
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package org.finos.calm.domain; | ||
|
|
||
| import java.util.Objects; | ||
|
|
||
| public class Flow { | ||
| private final String namespace; | ||
| private final int id; | ||
| private final String version; | ||
| private final String flow; | ||
|
|
||
| private Flow(FlowBuilder builder) { | ||
| this.namespace = builder.namespace; | ||
| this.id = builder.id; | ||
| this.version = builder.version; | ||
| this.flow = builder.flow; | ||
| } | ||
|
|
||
| public String getNamespace() { | ||
| return namespace; | ||
| } | ||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public String getDotVersion() { | ||
| return version; | ||
| } | ||
|
|
||
| public String getMongoVersion() { | ||
| return version.replace('.', '-'); | ||
| } | ||
|
|
||
| public String getFlowJson() { | ||
| return flow; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
| Flow flow1 = (Flow) o; | ||
| return id == flow1.id && Objects.equals(namespace, flow1.namespace) && Objects.equals(version, flow1.version) && Objects.equals(flow, flow1.flow); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(namespace, id, version, flow); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "Flow{" + | ||
| "namespace='" + namespace + '\'' + | ||
| ", id=" + id + | ||
| ", version='" + version + '\'' + | ||
| ", flow='" + flow + '\'' + | ||
| '}'; | ||
| } | ||
|
|
||
| public static class FlowBuilder { | ||
| private String namespace; | ||
| private int id; | ||
| private String version; | ||
| private String flow; | ||
|
|
||
| public FlowBuilder setNamespace(String namespace) { | ||
| this.namespace = namespace; | ||
| return this; | ||
| } | ||
|
|
||
| public FlowBuilder setId(int id) { | ||
| this.id = id; | ||
| return this; | ||
| } | ||
|
|
||
| public FlowBuilder setVersion(String version) { | ||
| this.version = version; | ||
| return this; | ||
| } | ||
|
|
||
| public FlowBuilder setFlow(String flow) { | ||
| this.flow = flow; | ||
| return this; | ||
| } | ||
|
|
||
| public Flow build() { | ||
| return new Flow(this); | ||
| } | ||
| } | ||
| } |
4 changes: 4 additions & 0 deletions
4
src/main/java/org/finos/calm/domain/exception/FlowNotFoundException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package org.finos.calm.domain.exception; | ||
|
|
||
| public class FlowNotFoundException extends Exception { | ||
| } |
4 changes: 4 additions & 0 deletions
4
src/main/java/org/finos/calm/domain/exception/FlowVersionExistsException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package org.finos.calm.domain.exception; | ||
|
|
||
| public class FlowVersionExistsException extends Exception { | ||
| } |
4 changes: 4 additions & 0 deletions
4
src/main/java/org/finos/calm/domain/exception/FlowVersionNotFoundException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package org.finos.calm.domain.exception; | ||
|
|
||
| public class FlowVersionNotFoundException extends Exception { | ||
| } |
198 changes: 198 additions & 0 deletions
198
src/main/java/org/finos/calm/resources/FlowResource.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| package org.finos.calm.resources; | ||
|
|
||
| import jakarta.ws.rs.*; | ||
| import jakarta.ws.rs.core.MediaType; | ||
| import jakarta.ws.rs.core.Response; | ||
| import org.eclipse.microprofile.config.inject.ConfigProperty; | ||
| import org.eclipse.microprofile.openapi.annotations.Operation; | ||
| import org.finos.calm.domain.*; | ||
| import org.finos.calm.domain.exception.NamespaceNotFoundException; | ||
| import org.finos.calm.domain.exception.FlowNotFoundException; | ||
| import org.finos.calm.domain.exception.FlowVersionExistsException; | ||
| import org.finos.calm.domain.exception.FlowVersionNotFoundException; | ||
| import org.finos.calm.store.FlowStore; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import java.net.URI; | ||
| import java.net.URISyntaxException; | ||
|
|
||
| @Path("/calm/namespaces") | ||
| public class FlowResource { | ||
|
|
||
| private final FlowStore store; | ||
|
|
||
| private final Logger logger = LoggerFactory.getLogger(FlowResource.class); | ||
|
|
||
| @ConfigProperty(name = "allow.put.operations", defaultValue = "false") | ||
| Boolean allowPutOperations; | ||
|
|
||
| public FlowResource(FlowStore store) { | ||
| this.store = store; | ||
| } | ||
|
|
||
| @GET | ||
| @Path("{namespace}/flows") | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Operation( | ||
| summary = "Retrieve flows in a given namespace", | ||
| description = "Flows stored in a given namespace" | ||
| ) | ||
| public Response getFlowsForNamespace(@PathParam("namespace") String namespace) { | ||
| try { | ||
| return Response.ok(new ValueWrapper<>(store.getFlowsForNamespace(namespace))).build(); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when retrieving flows", namespace, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } | ||
| } | ||
|
|
||
| @POST | ||
| @Path("{namespace}/flows") | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Operation( | ||
| summary = "Create flow for namespace", | ||
| description = "Creates a flow for a given namespace with an allocated ID and version 1.0.0" | ||
| ) | ||
| public Response createFlowForNamespace(@PathParam("namespace") String namespace, String flowJson) throws URISyntaxException { | ||
| Flow flow = new Flow.FlowBuilder() | ||
| .setNamespace(namespace) | ||
| .setFlow(flowJson) | ||
| .build(); | ||
|
|
||
| try { | ||
| return flowWithLocationResponse(store.createFlowForNamespace(flow)); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when creating flow", namespace, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } | ||
| } | ||
|
|
||
| @GET | ||
| @Path("{namespace}/flows/{flowId}/versions") | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Operation( | ||
| summary = "Retrieve a list of versions for a given flow", | ||
| description = "Flow versions are not opinionated, outside of the first version created" | ||
| ) | ||
| public Response getFlowVersions(@PathParam("namespace") String namespace, @PathParam("flowId") int flowId) { | ||
| Flow flow = new Flow.FlowBuilder() | ||
| .setNamespace(namespace) | ||
| .setId(flowId) | ||
| .build(); | ||
|
|
||
| try { | ||
| return Response.ok(new ValueWrapper<>(store.getFlowVersions(flow))).build(); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when getting versions of flow", flow, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } catch (FlowNotFoundException e) { | ||
| logger.error("Invalid flow [{}] when getting versions of flow", flow, e); | ||
| return invalidFlowResponse(flowId); | ||
| } | ||
| } | ||
|
|
||
| @GET | ||
| @Path("{namespace}/flows/{flowId}/versions/{version}") | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Operation( | ||
| summary = "Retrieve a specific flow at a given version", | ||
| description = "Retrieve flows at a specific version" | ||
| ) | ||
| public Response getFlow(@PathParam("namespace") String namespace, @PathParam("flowId") int flowId, @PathParam("version") String version) { | ||
| Flow flow = new Flow.FlowBuilder() | ||
| .setNamespace(namespace) | ||
| .setId(flowId) | ||
| .setVersion(version) | ||
| .build(); | ||
|
|
||
| try { | ||
| return Response.ok(store.getFlowForVersion(flow)).build(); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when getting a flow", flow, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } catch (FlowNotFoundException e) { | ||
| logger.error("Invalid flow [{}] when getting a flow", flow, e); | ||
| return invalidFlowResponse(flowId); | ||
| } catch (FlowVersionNotFoundException e) { | ||
| logger.error("Invalid version [{}] when getting a flow", flow, e); | ||
| return invalidVersionResponse(version); | ||
| } | ||
| } | ||
|
|
||
| @POST | ||
| @Path("{namespace}/flows/{flowId}/versions/{version}") | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| public Response createVersionedFlow(@PathParam("namespace") String namespace, @PathParam("flowId") int flowId, @PathParam("version") String version, String flowJson) throws URISyntaxException { | ||
| Flow flow = new Flow.FlowBuilder() | ||
| .setNamespace(namespace) | ||
| .setId(flowId) | ||
| .setVersion(version) | ||
| .setFlow(flowJson) | ||
| .build(); | ||
|
|
||
| try { | ||
| store.createFlowForVersion(flow); | ||
| return flowWithLocationResponse(flow); | ||
| } catch (FlowVersionExistsException e) { | ||
| logger.error("Flow version already exists [{}] when trying to create new flow", flow, e); | ||
| return Response.status(Response.Status.CONFLICT).entity("Version already exists: " + version).build(); | ||
| } catch (FlowNotFoundException e) { | ||
| logger.error("Invalid flow [{}] when getting a flow", flow, e); | ||
| return invalidFlowResponse(flowId); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when getting a flow", flow, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } | ||
| } | ||
|
|
||
| @PUT | ||
| @Path("{namespace}/flows/{flowId}/versions/{version}") | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| @Produces(MediaType.APPLICATION_JSON) | ||
| @Operation( | ||
| summary = "Updates a Flow (if available)", | ||
| description = "In mutable version stores flow updates are supported by this endpoint, operation unavailable returned in repositories without configuration specified" | ||
| ) | ||
| public Response updateVersionedFlow(@PathParam("namespace") String namespace, @PathParam("flowId") int flowId, @PathParam("version") String version, String flowJson) throws URISyntaxException { | ||
| Flow flow = new Flow.FlowBuilder() | ||
| .setNamespace(namespace) | ||
| .setId(flowId) | ||
| .setVersion(version) | ||
| .setFlow(flowJson) | ||
| .build(); | ||
|
|
||
| if (!allowPutOperations) { | ||
| return Response.status(Response.Status.FORBIDDEN).entity("This Calm Hub does not support PUT operations").build(); | ||
| } | ||
|
|
||
| try { | ||
| store.updateFlowForVersion(flow); | ||
| return flowWithLocationResponse(flow); | ||
| } catch (NamespaceNotFoundException e) { | ||
| logger.error("Invalid namespace [{}] when trying to put flow", flow, e); | ||
| return invalidNamespaceResponse(namespace); | ||
| } catch (FlowNotFoundException e) { | ||
| logger.error("Invalid flow [{}] when trying to put flow", flow, e); | ||
| return invalidFlowResponse(flowId); | ||
| } | ||
| } | ||
|
|
||
| private Response flowWithLocationResponse(Flow flow) throws URISyntaxException { | ||
| return Response.created(new URI("/calm/namespaces/" + flow.getNamespace() + "/flows/" + flow.getId() + "/versions/" + flow.getDotVersion())).build(); | ||
| } | ||
|
|
||
| private Response invalidNamespaceResponse(String namespace) { | ||
| return Response.status(Response.Status.NOT_FOUND).entity("Invalid namespace provided: " + namespace).build(); | ||
| } | ||
|
|
||
| private Response invalidFlowResponse(int flowId) { | ||
| return Response.status(Response.Status.NOT_FOUND).entity("Invalid flow provided: " + flowId).build(); | ||
| } | ||
|
|
||
| private Response invalidVersionResponse(String version) { | ||
| return Response.status(Response.Status.NOT_FOUND).entity("Invalid version provided: " + version).build(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package org.finos.calm.store; | ||
|
|
||
| import org.bson.json.JsonParseException; | ||
| import org.finos.calm.domain.*; | ||
| import org.finos.calm.domain.exception.NamespaceNotFoundException; | ||
| import org.finos.calm.domain.exception.FlowNotFoundException; | ||
| import org.finos.calm.domain.exception.FlowVersionExistsException; | ||
| import org.finos.calm.domain.exception.FlowVersionNotFoundException; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public interface FlowStore { | ||
| List<Integer> getFlowsForNamespace(String namespace) throws NamespaceNotFoundException; | ||
| Flow createFlowForNamespace(Flow flow) throws NamespaceNotFoundException, JsonParseException; | ||
| List<String> getFlowVersions(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException; | ||
| String getFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException, FlowVersionNotFoundException; | ||
| Flow createFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException, FlowVersionExistsException; | ||
| Flow updateFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not saying one needs to use mongo:4.0.
I have an old mac and 4.2 didn't work :D