From 0e641822a6758c59a7e5848410710004639f0263 Mon Sep 17 00:00:00 2001 From: Joshua Palis Date: Thu, 7 Dec 2023 23:45:06 +0000 Subject: [PATCH 1/5] Get template API Signed-off-by: Joshua Palis --- .../flowframework/FlowFrameworkPlugin.java | 9 +- .../rest/RestGetTemplateAction.java | 106 ++++++++++++++++++ .../transport/GetTemplateAction.java | 27 +++++ .../transport/GetTemplateResponse.java | 56 +++++++++ .../transport/GetTemplateTransportAction.java | 94 ++++++++++++++++ .../FlowFrameworkPluginTests.java | 4 +- 6 files changed, 292 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java create mode 100644 src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java create mode 100644 src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java create mode 100644 src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java diff --git a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java index 14df7e17e..2119c134b 100644 --- a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java +++ b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java @@ -28,11 +28,14 @@ import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; import org.opensearch.flowframework.indices.FlowFrameworkIndicesHandler; import org.opensearch.flowframework.rest.RestCreateWorkflowAction; +import org.opensearch.flowframework.rest.RestGetTemplateAction; import org.opensearch.flowframework.rest.RestGetWorkflowAction; import org.opensearch.flowframework.rest.RestProvisionWorkflowAction; import org.opensearch.flowframework.rest.RestSearchWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowTransportAction; +import org.opensearch.flowframework.transport.GetTemplateAction; +import org.opensearch.flowframework.transport.GetTemplateTransportAction; import org.opensearch.flowframework.transport.GetWorkflowAction; import org.opensearch.flowframework.transport.GetWorkflowTransportAction; import org.opensearch.flowframework.transport.ProvisionWorkflowAction; @@ -125,7 +128,8 @@ public List getRestHandlers( new RestCreateWorkflowAction(flowFrameworkFeatureEnabledSetting, settings, clusterService), new RestProvisionWorkflowAction(flowFrameworkFeatureEnabledSetting), new RestSearchWorkflowAction(flowFrameworkFeatureEnabledSetting), - new RestGetWorkflowAction(flowFrameworkFeatureEnabledSetting) + new RestGetWorkflowAction(flowFrameworkFeatureEnabledSetting), + new RestGetTemplateAction(flowFrameworkFeatureEnabledSetting) ); } @@ -135,7 +139,8 @@ public List getRestHandlers( new ActionHandler<>(CreateWorkflowAction.INSTANCE, CreateWorkflowTransportAction.class), new ActionHandler<>(ProvisionWorkflowAction.INSTANCE, ProvisionWorkflowTransportAction.class), new ActionHandler<>(SearchWorkflowAction.INSTANCE, SearchWorkflowTransportAction.class), - new ActionHandler<>(GetWorkflowAction.INSTANCE, GetWorkflowTransportAction.class) + new ActionHandler<>(GetWorkflowAction.INSTANCE, GetWorkflowTransportAction.class), + new ActionHandler<>(GetTemplateAction.INSTANCE, GetTemplateTransportAction.class) ); } diff --git a/src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java b/src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java new file mode 100644 index 000000000..bbacaa16f --- /dev/null +++ b/src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java @@ -0,0 +1,106 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.rest; + +import com.google.common.collect.ImmutableList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.ExceptionsHelper; +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; +import org.opensearch.flowframework.exception.FlowFrameworkException; +import org.opensearch.flowframework.transport.GetTemplateAction; +import org.opensearch.flowframework.transport.WorkflowRequest; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestRequest; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import static org.opensearch.flowframework.common.CommonValue.WORKFLOW_ID; +import static org.opensearch.flowframework.common.CommonValue.WORKFLOW_URI; +import static org.opensearch.flowframework.common.FlowFrameworkSettings.FLOW_FRAMEWORK_ENABLED; + +/** + * Rest Action to facilitate requests to get a stored template + */ +public class RestGetTemplateAction extends BaseRestHandler { + + private static final String GET_TEMPLATE_ACTION = "get_template"; + private static final Logger logger = LogManager.getLogger(RestGetTemplateAction.class); + private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; + + /** + * Instantiates a new RestGetWorkflowAction + * @param flowFrameworkFeatureEnabledSetting Whether this API is enabled + */ + public RestGetTemplateAction(FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting) { + this.flowFrameworkFeatureEnabledSetting = flowFrameworkFeatureEnabledSetting; + } + + @Override + public String getName() { + return GET_TEMPLATE_ACTION; + } + + @Override + public List routes() { + return ImmutableList.of(new Route(RestRequest.Method.GET, String.format(Locale.ROOT, "%s/{%s}", WORKFLOW_URI, WORKFLOW_ID))); + } + + @Override + protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + + try { + if (!flowFrameworkFeatureEnabledSetting.isFlowFrameworkEnabled()) { + throw new FlowFrameworkException( + "This API is disabled. To enable it, update the setting [" + FLOW_FRAMEWORK_ENABLED.getKey() + "] to true.", + RestStatus.FORBIDDEN + ); + } + + // Validate content + if (request.hasContent()) { + throw new FlowFrameworkException("Invalid request format", RestStatus.BAD_REQUEST); + } + // Validate params + String workflowId = request.param(WORKFLOW_ID); + if (workflowId == null) { + throw new FlowFrameworkException("workflow_id cannot be null", RestStatus.BAD_REQUEST); + } + + WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); + return channel -> client.execute(GetTemplateAction.INSTANCE, workflowRequest, ActionListener.wrap(response -> { + XContentBuilder builder = response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS); + channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder)); + }, exception -> { + try { + FlowFrameworkException ex = new FlowFrameworkException(exception.getMessage(), ExceptionsHelper.status(exception)); + XContentBuilder exceptionBuilder = ex.toXContent(channel.newErrorBuilder(), ToXContent.EMPTY_PARAMS); + channel.sendResponse(new BytesRestResponse(ex.getRestStatus(), exceptionBuilder)); + + } catch (IOException e) { + logger.error("Failed to send back get template exception", e); + channel.sendResponse(new BytesRestResponse(ExceptionsHelper.status(e), e.getMessage())); + } + })); + + } catch (FlowFrameworkException ex) { + return channel -> channel.sendResponse( + new BytesRestResponse(ex.getRestStatus(), ex.toXContent(channel.newErrorBuilder(), ToXContent.EMPTY_PARAMS)) + ); + } + } +} diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java b/src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java new file mode 100644 index 000000000..8fc3dc7a5 --- /dev/null +++ b/src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java @@ -0,0 +1,27 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.transport; + +import org.opensearch.action.ActionType; + +import static org.opensearch.flowframework.common.CommonValue.TRANSPORT_ACTION_NAME_PREFIX; + +/** + * External Action for public facing RestGetTemplateAction + */ +public class GetTemplateAction extends ActionType { + /** The name of this action */ + public static final String NAME = TRANSPORT_ACTION_NAME_PREFIX + "template/get"; + /** An instance of this action */ + public static final GetTemplateAction INSTANCE = new GetTemplateAction(); + + private GetTemplateAction() { + super(NAME, GetTemplateResponse::new); + } +} diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java b/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java new file mode 100644 index 000000000..472066d13 --- /dev/null +++ b/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java @@ -0,0 +1,56 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.transport; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.flowframework.model.Template; + +import java.io.IOException; + +/** + * Transport Response from getting a template + */ +public class GetTemplateResponse extends ActionResponse implements ToXContentObject { + + /** The template */ + public Template template; + + /** + * Instantiates a new GetTemplateResponse from an input stream + * @param in the input stream to read from + * @throws IOException if the template json cannot be read from the input stream + */ + public GetTemplateResponse(StreamInput in) throws IOException { + super(in); + this.template = Template.parse(in.readString()); + } + + /** + * Instantiates a new GetTemplateResponse + * @param template the template + */ + public GetTemplateResponse(Template template) { + this.template = template; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(template.toJson()); + } + + @Override + public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { + return this.template.toXContent(xContentBuilder, params); + } + +} diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java b/src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java new file mode 100644 index 000000000..7dfd94c85 --- /dev/null +++ b/src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java @@ -0,0 +1,94 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.transport; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.ExceptionsHelper; +import org.opensearch.action.get.GetRequest; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.client.Client; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.flowframework.exception.FlowFrameworkException; +import org.opensearch.flowframework.indices.FlowFrameworkIndicesHandler; +import org.opensearch.flowframework.model.Template; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.flowframework.common.CommonValue.GLOBAL_CONTEXT_INDEX; + +/** + * Transport action to retrieve a use case template within the Global Context + */ +public class GetTemplateTransportAction extends HandledTransportAction { + + private final Logger logger = LogManager.getLogger(GetTemplateTransportAction.class); + private final FlowFrameworkIndicesHandler flowFrameworkIndicesHandler; + private final Client client; + + /** + * Instantiates a new GetTempltateTransportAction instance + * @param transportService the transport service + * @param actionFilters action filters + * @param flowFrameworkIndicesHandler The Flow Framework indices handler + * @param client the Opensearch Client + */ + @Inject + public GetTemplateTransportAction( + TransportService transportService, + ActionFilters actionFilters, + FlowFrameworkIndicesHandler flowFrameworkIndicesHandler, + Client client + ) { + super(GetTemplateAction.NAME, transportService, actionFilters, WorkflowRequest::new); + this.flowFrameworkIndicesHandler = flowFrameworkIndicesHandler; + this.client = client; + } + + @Override + protected void doExecute(Task task, WorkflowRequest request, ActionListener listener) { + if (flowFrameworkIndicesHandler.doesIndexExist(GLOBAL_CONTEXT_INDEX)) { + + String workflowId = request.getWorkflowId(); + GetRequest getRequest = new GetRequest(GLOBAL_CONTEXT_INDEX, workflowId); + + // Retrieve workflow by ID + try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) { + client.get(getRequest, ActionListener.wrap(response -> { + context.restore(); + + if (!response.isExists()) { + listener.onFailure( + new FlowFrameworkException( + "Failed to retrieve template (" + workflowId + ") from global context.", + RestStatus.NOT_FOUND + ) + ); + } else { + listener.onResponse(new GetTemplateResponse(Template.parse(response.getSourceAsString()))); + } + }, exception -> { + logger.error("Failed to retrieve template from global context.", exception); + listener.onFailure(new FlowFrameworkException(exception.getMessage(), ExceptionsHelper.status(exception))); + })); + } catch (Exception e) { + logger.error("Failed to retrieve template from global context.", e); + listener.onFailure(new FlowFrameworkException(e.getMessage(), ExceptionsHelper.status(e))); + } + + } else { + listener.onFailure(new FlowFrameworkException("There are no templates in the global_context", RestStatus.NOT_FOUND)); + } + + } +} diff --git a/src/test/java/org/opensearch/flowframework/FlowFrameworkPluginTests.java b/src/test/java/org/opensearch/flowframework/FlowFrameworkPluginTests.java index e3827e0b3..c958e70e5 100644 --- a/src/test/java/org/opensearch/flowframework/FlowFrameworkPluginTests.java +++ b/src/test/java/org/opensearch/flowframework/FlowFrameworkPluginTests.java @@ -81,8 +81,8 @@ public void testPlugin() throws IOException { 4, ffp.createComponents(client, clusterService, threadPool, null, null, null, environment, null, null, null, null).size() ); - assertEquals(4, ffp.getRestHandlers(settings, null, null, null, null, null, null).size()); - assertEquals(4, ffp.getActions().size()); + assertEquals(5, ffp.getRestHandlers(settings, null, null, null, null, null, null).size()); + assertEquals(5, ffp.getActions().size()); assertEquals(1, ffp.getExecutorBuilders(settings).size()); assertEquals(4, ffp.getSettings().size()); } From 4357b9f7f46774686a967e3d4ada1bfd744057cb Mon Sep 17 00:00:00 2001 From: Joshua Palis Date: Fri, 8 Dec 2023 00:01:17 +0000 Subject: [PATCH 2/5] Adding rest action unit tests Signed-off-by: Joshua Palis --- .../rest/RestGetTemplateActionTests.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java diff --git a/src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java b/src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java new file mode 100644 index 000000000..7ed2e1a64 --- /dev/null +++ b/src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java @@ -0,0 +1,96 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.rest; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.common.bytes.BytesArray; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.MediaTypeRegistry; +import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; +import org.opensearch.rest.RestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.test.rest.FakeRestChannel; +import org.opensearch.test.rest.FakeRestRequest; + +import java.util.List; +import java.util.Locale; + +import static org.opensearch.flowframework.common.CommonValue.WORKFLOW_URI; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RestGetTemplateActionTests extends OpenSearchTestCase { + private RestGetTemplateAction restGetTemplateAction; + private String getPath; + private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; + private NodeClient nodeClient; + + @Override + public void setUp() throws Exception { + super.setUp(); + + this.getPath = String.format(Locale.ROOT, "%s/{%s}", WORKFLOW_URI, "workflow_id"); + flowFrameworkFeatureEnabledSetting = mock(FlowFrameworkFeatureEnabledSetting.class); + when(flowFrameworkFeatureEnabledSetting.isFlowFrameworkEnabled()).thenReturn(true); + this.restGetTemplateAction = new RestGetTemplateAction(flowFrameworkFeatureEnabledSetting); + this.nodeClient = mock(NodeClient.class); + } + + public void testRestGetWorkflowActionName() { + String name = restGetTemplateAction.getName(); + assertEquals("get_template", name); + } + + public void testRestGetWorkflowActionRoutes() { + List routes = restGetTemplateAction.routes(); + assertEquals(1, routes.size()); + assertEquals(RestRequest.Method.GET, routes.get(0).getMethod()); + assertEquals(this.getPath, routes.get(0).getPath()); + } + + public void testInvalidRequestWithContent() { + RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withMethod(RestRequest.Method.POST) + .withPath(this.getPath) + .withContent(new BytesArray("request body"), MediaTypeRegistry.JSON) + .build(); + + FakeRestChannel channel = new FakeRestChannel(request, false, 1); + IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> { + restGetTemplateAction.handleRequest(request, channel, nodeClient); + }); + assertEquals("request [POST /_plugins/_flow_framework/workflow/{workflow_id}] does not support having a body", ex.getMessage()); + } + + public void testNullWorkflowId() throws Exception { + + // Request with no params + RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withMethod(RestRequest.Method.POST) + .withPath(this.getPath) + .build(); + + FakeRestChannel channel = new FakeRestChannel(request, true, 1); + restGetTemplateAction.handleRequest(request, channel, nodeClient); + + assertEquals(1, channel.errors().get()); + assertEquals(RestStatus.BAD_REQUEST, channel.capturedResponse().status()); + assertTrue(channel.capturedResponse().content().utf8ToString().contains("workflow_id cannot be null")); + } + + public void testFeatureFlagNotEnabled() throws Exception { + when(flowFrameworkFeatureEnabledSetting.isFlowFrameworkEnabled()).thenReturn(false); + RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withMethod(RestRequest.Method.POST) + .withPath(this.getPath) + .build(); + FakeRestChannel channel = new FakeRestChannel(request, false, 1); + restGetTemplateAction.handleRequest(request, channel, nodeClient); + assertEquals(RestStatus.FORBIDDEN, channel.capturedResponse().status()); + assertTrue(channel.capturedResponse().content().utf8ToString().contains("This API is disabled.")); + } +} From 3f7649ac2a229e06f537a900e052d10d53275f89 Mon Sep 17 00:00:00 2001 From: Joshua Palis Date: Fri, 8 Dec 2023 00:27:09 +0000 Subject: [PATCH 3/5] Adding transport action unit tests Signed-off-by: Joshua Palis --- .../transport/GetTemplateResponse.java | 10 +- .../GetTemplateTransportActionTests.java | 158 ++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java b/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java index 472066d13..6d9f99068 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java @@ -23,7 +23,7 @@ public class GetTemplateResponse extends ActionResponse implements ToXContentObject { /** The template */ - public Template template; + private Template template; /** * Instantiates a new GetTemplateResponse from an input stream @@ -53,4 +53,12 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params return this.template.toXContent(xContentBuilder, params); } + /** + * Gets the template + * @return the template + */ + public Template getTemplate() { + return this.template; + } + } diff --git a/src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java b/src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java new file mode 100644 index 000000000..948e1bbd0 --- /dev/null +++ b/src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java @@ -0,0 +1,158 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.transport; + +import org.opensearch.Version; +import org.opensearch.action.get.GetRequest; +import org.opensearch.action.get.GetResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.client.Client; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.common.bytes.BytesReference; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.flowframework.TestHelpers; +import org.opensearch.flowframework.indices.FlowFrameworkIndicesHandler; +import org.opensearch.flowframework.model.Template; +import org.opensearch.flowframework.model.Workflow; +import org.opensearch.flowframework.model.WorkflowEdge; +import org.opensearch.flowframework.model.WorkflowNode; +import org.opensearch.index.get.GetResult; +import org.opensearch.tasks.Task; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.TransportService; + +import java.util.List; +import java.util.Map; + +import org.mockito.ArgumentCaptor; + +import static org.opensearch.flowframework.common.CommonValue.GLOBAL_CONTEXT_INDEX; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class GetTemplateTransportActionTests extends OpenSearchTestCase { + + private ThreadPool threadPool; + private Client client; + private GetTemplateTransportAction getTemplateTransportAction; + private FlowFrameworkIndicesHandler flowFrameworkIndicesHandler; + private Template template; + + @Override + public void setUp() throws Exception { + super.setUp(); + this.threadPool = mock(ThreadPool.class); + this.client = mock(Client.class); + this.flowFrameworkIndicesHandler = mock(FlowFrameworkIndicesHandler.class); + this.getTemplateTransportAction = new GetTemplateTransportAction( + mock(TransportService.class), + mock(ActionFilters.class), + flowFrameworkIndicesHandler, + client + ); + + Version templateVersion = Version.fromString("1.0.0"); + List compatibilityVersions = List.of(Version.fromString("2.0.0"), Version.fromString("3.0.0")); + WorkflowNode nodeA = new WorkflowNode("A", "a-type", Map.of(), Map.of("foo", "bar")); + WorkflowNode nodeB = new WorkflowNode("B", "b-type", Map.of(), Map.of("baz", "qux")); + WorkflowEdge edgeAB = new WorkflowEdge("A", "B"); + List nodes = List.of(nodeA, nodeB); + List edges = List.of(edgeAB); + Workflow workflow = new Workflow(Map.of("key", "value"), nodes, edges); + + this.template = new Template( + "test", + "description", + "use case", + templateVersion, + compatibilityVersions, + Map.of("provision", workflow), + Map.of(), + TestHelpers.randomUser() + ); + + ThreadPool clientThreadPool = mock(ThreadPool.class); + ThreadContext threadContext = new ThreadContext(Settings.EMPTY); + + when(client.threadPool()).thenReturn(clientThreadPool); + when(clientThreadPool.getThreadContext()).thenReturn(threadContext); + + } + + public void testGetTemplateNoGlobalContext() { + + when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(false); + @SuppressWarnings("unchecked") + ActionListener listener = mock(ActionListener.class); + WorkflowRequest workflowRequest = new WorkflowRequest("1", null); + getTemplateTransportAction.doExecute(mock(Task.class), workflowRequest, listener); + + ArgumentCaptor exceptionCaptor = ArgumentCaptor.forClass(Exception.class); + verify(listener, times(1)).onFailure(exceptionCaptor.capture()); + assertTrue(exceptionCaptor.getValue().getMessage().contains("There are no templates in the global_context")); + } + + public void testGetTemplateSuccess() { + String workflowId = "12345"; + @SuppressWarnings("unchecked") + ActionListener listener = mock(ActionListener.class); + WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); + + when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(true); + + // Stub client.get to force on response + doAnswer(invocation -> { + ActionListener responseListener = invocation.getArgument(1); + + XContentBuilder builder = XContentFactory.jsonBuilder(); + this.template.toXContent(builder, null); + BytesReference templateBytesRef = BytesReference.bytes(builder); + GetResult getResult = new GetResult(GLOBAL_CONTEXT_INDEX, workflowId, 1, 1, 1, true, templateBytesRef, null, null); + responseListener.onResponse(new GetResponse(getResult)); + return null; + }).when(client).get(any(GetRequest.class), any()); + + getTemplateTransportAction.doExecute(mock(Task.class), workflowRequest, listener); + + ArgumentCaptor templateCaptor = ArgumentCaptor.forClass(GetTemplateResponse.class); + verify(listener, times(1)).onResponse(templateCaptor.capture()); + assertEquals(this.template.name(), templateCaptor.getValue().getTemplate().name()); + } + + public void testGetTemplateFailure() { + String workflowId = "12345"; + @SuppressWarnings("unchecked") + ActionListener listener = mock(ActionListener.class); + WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); + + when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(true); + + // Stub client.get to force on failure + doAnswer(invocation -> { + ActionListener responseListener = invocation.getArgument(1); + responseListener.onFailure(new Exception("Failed to retrieve template from global context.")); + return null; + }).when(client).get(any(GetRequest.class), any()); + + getTemplateTransportAction.doExecute(mock(Task.class), workflowRequest, listener); + + ArgumentCaptor exceptionCaptor = ArgumentCaptor.forClass(Exception.class); + verify(listener, times(1)).onFailure(exceptionCaptor.capture()); + assertEquals("Failed to retrieve template from global context.", exceptionCaptor.getValue().getMessage()); + } +} From 59c7f2a17ed21bd5cfe77e9d982412391776a987 Mon Sep 17 00:00:00 2001 From: Joshua Palis Date: Mon, 11 Dec 2023 20:08:49 +0000 Subject: [PATCH 4/5] Renaming State API implementation, changing names to GetWorkflowState Signed-off-by: Joshua Palis --- .../flowframework/FlowFrameworkPlugin.java | 10 +++---- ...n.java => RestGetWorkflowStateAction.java} | 21 +++++++-------- ...ction.java => GetWorkflowStateAction.java} | 12 ++++----- ...uest.java => GetWorkflowStateRequest.java} | 8 +++--- ...nse.java => GetWorkflowStateResponse.java} | 6 ++--- ...a => GetWorkflowStateTransportAction.java} | 14 +++++----- ...a => RestGetWorkflowStateActionTests.java} | 10 +++---- ...GetWorkflowStateTransportActionTests.java} | 26 +++++++++---------- 8 files changed, 53 insertions(+), 54 deletions(-) rename src/main/java/org/opensearch/flowframework/rest/{RestGetWorkflowAction.java => RestGetWorkflowStateAction.java} (84%) rename src/main/java/org/opensearch/flowframework/transport/{GetWorkflowAction.java => GetWorkflowStateAction.java} (62%) rename src/main/java/org/opensearch/flowframework/transport/{GetWorkflowRequest.java => GetWorkflowStateRequest.java} (88%) rename src/main/java/org/opensearch/flowframework/transport/{GetWorkflowResponse.java => GetWorkflowStateResponse.java} (89%) rename src/main/java/org/opensearch/flowframework/transport/{GetWorkflowTransportAction.java => GetWorkflowStateTransportAction.java} (87%) rename src/test/java/org/opensearch/flowframework/rest/{RestGetWorkflowActionTests.java => RestGetWorkflowStateActionTests.java} (90%) rename src/test/java/org/opensearch/flowframework/transport/{GetWorkflowTransportActionTests.java => GetWorkflowStateTransportActionTests.java} (79%) diff --git a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java index 2119c134b..8614a0be7 100644 --- a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java +++ b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java @@ -29,15 +29,15 @@ import org.opensearch.flowframework.indices.FlowFrameworkIndicesHandler; import org.opensearch.flowframework.rest.RestCreateWorkflowAction; import org.opensearch.flowframework.rest.RestGetTemplateAction; -import org.opensearch.flowframework.rest.RestGetWorkflowAction; +import org.opensearch.flowframework.rest.RestGetWorkflowStateAction; import org.opensearch.flowframework.rest.RestProvisionWorkflowAction; import org.opensearch.flowframework.rest.RestSearchWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowTransportAction; import org.opensearch.flowframework.transport.GetTemplateAction; import org.opensearch.flowframework.transport.GetTemplateTransportAction; -import org.opensearch.flowframework.transport.GetWorkflowAction; -import org.opensearch.flowframework.transport.GetWorkflowTransportAction; +import org.opensearch.flowframework.transport.GetWorkflowStateAction; +import org.opensearch.flowframework.transport.GetWorkflowStateTransportAction; import org.opensearch.flowframework.transport.ProvisionWorkflowAction; import org.opensearch.flowframework.transport.ProvisionWorkflowTransportAction; import org.opensearch.flowframework.transport.SearchWorkflowAction; @@ -128,7 +128,7 @@ public List getRestHandlers( new RestCreateWorkflowAction(flowFrameworkFeatureEnabledSetting, settings, clusterService), new RestProvisionWorkflowAction(flowFrameworkFeatureEnabledSetting), new RestSearchWorkflowAction(flowFrameworkFeatureEnabledSetting), - new RestGetWorkflowAction(flowFrameworkFeatureEnabledSetting), + new RestGetWorkflowStateAction(flowFrameworkFeatureEnabledSetting), new RestGetTemplateAction(flowFrameworkFeatureEnabledSetting) ); } @@ -139,7 +139,7 @@ public List getRestHandlers( new ActionHandler<>(CreateWorkflowAction.INSTANCE, CreateWorkflowTransportAction.class), new ActionHandler<>(ProvisionWorkflowAction.INSTANCE, ProvisionWorkflowTransportAction.class), new ActionHandler<>(SearchWorkflowAction.INSTANCE, SearchWorkflowTransportAction.class), - new ActionHandler<>(GetWorkflowAction.INSTANCE, GetWorkflowTransportAction.class), + new ActionHandler<>(GetWorkflowStateAction.INSTANCE, GetWorkflowStateTransportAction.class), new ActionHandler<>(GetTemplateAction.INSTANCE, GetTemplateTransportAction.class) ); } diff --git a/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java b/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowStateAction.java similarity index 84% rename from src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java rename to src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowStateAction.java index 6d9d5e3b5..ab7335b2d 100644 --- a/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java +++ b/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowStateAction.java @@ -19,8 +19,8 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; import org.opensearch.flowframework.exception.FlowFrameworkException; -import org.opensearch.flowframework.transport.GetWorkflowAction; -import org.opensearch.flowframework.transport.GetWorkflowRequest; +import org.opensearch.flowframework.transport.GetWorkflowStateAction; +import org.opensearch.flowframework.transport.GetWorkflowStateRequest; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestRequest; @@ -36,23 +36,23 @@ /** * Rest Action to facilitate requests to get a workflow status */ -public class RestGetWorkflowAction extends BaseRestHandler { +public class RestGetWorkflowStateAction extends BaseRestHandler { - private static final String GET_WORKFLOW_ACTION = "get_workflow"; - private static final Logger logger = LogManager.getLogger(RestGetWorkflowAction.class); + private static final String GET_WORKFLOW_STATE_ACTION = "get_workflow_state"; + private static final Logger logger = LogManager.getLogger(RestGetWorkflowStateAction.class); private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; /** - * Instantiates a new RestGetWorkflowAction + * Instantiates a new RestGetWorkflowStateAction * @param flowFrameworkFeatureEnabledSetting Whether this API is enabled */ - public RestGetWorkflowAction(FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting) { + public RestGetWorkflowStateAction(FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting) { this.flowFrameworkFeatureEnabledSetting = flowFrameworkFeatureEnabledSetting; } @Override public String getName() { - return GET_WORKFLOW_ACTION; + return GET_WORKFLOW_STATE_ACTION; } @Override @@ -77,8 +77,8 @@ protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request } boolean all = request.paramAsBoolean("all", false); - GetWorkflowRequest getWorkflowRequest = new GetWorkflowRequest(workflowId, all); - return channel -> client.execute(GetWorkflowAction.INSTANCE, getWorkflowRequest, ActionListener.wrap(response -> { + GetWorkflowStateRequest getWorkflowRequest = new GetWorkflowStateRequest(workflowId, all); + return channel -> client.execute(GetWorkflowStateAction.INSTANCE, getWorkflowRequest, ActionListener.wrap(response -> { XContentBuilder builder = response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS); channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder)); }, exception -> { @@ -103,7 +103,6 @@ protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request @Override public List routes() { return ImmutableList.of( - // Provision workflow from indexed use case template new Route(RestRequest.Method.GET, String.format(Locale.ROOT, "%s/{%s}/%s", WORKFLOW_URI, WORKFLOW_ID, "_status")) ); } diff --git a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateAction.java similarity index 62% rename from src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateAction.java index 6abee3867..99c521362 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateAction.java @@ -13,15 +13,15 @@ import static org.opensearch.flowframework.common.CommonValue.TRANSPORT_ACTION_NAME_PREFIX; /** - * External Action for public facing RestGetWorkflowAction + * External Action for public facing RestGetWorkflowStateAction */ -public class GetWorkflowAction extends ActionType { +public class GetWorkflowStateAction extends ActionType { /** The name of this action */ - public static final String NAME = TRANSPORT_ACTION_NAME_PREFIX + "workflow/get"; + public static final String NAME = TRANSPORT_ACTION_NAME_PREFIX + "workflowstate/get"; /** An instance of this action */ - public static final GetWorkflowAction INSTANCE = new GetWorkflowAction(); + public static final GetWorkflowStateAction INSTANCE = new GetWorkflowStateAction(); - private GetWorkflowAction() { - super(NAME, GetWorkflowResponse::new); + private GetWorkflowStateAction() { + super(NAME, GetWorkflowStateResponse::new); } } diff --git a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowRequest.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateRequest.java similarity index 88% rename from src/main/java/org/opensearch/flowframework/transport/GetWorkflowRequest.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateRequest.java index c7594eb77..36a9ccf6c 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowRequest.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateRequest.java @@ -17,9 +17,9 @@ import java.io.IOException; /** - * Transport Request to get a workflow or workflow status + * Transport Request to get a workflow state */ -public class GetWorkflowRequest extends ActionRequest { +public class GetWorkflowStateRequest extends ActionRequest { /** * The documentId of the workflow entry within the Global Context index @@ -37,7 +37,7 @@ public class GetWorkflowRequest extends ActionRequest { * @param workflowId the documentId of the workflow * @param all whether the get request is looking for all fields in status */ - public GetWorkflowRequest(@Nullable String workflowId, boolean all) { + public GetWorkflowStateRequest(@Nullable String workflowId, boolean all) { this.workflowId = workflowId; this.all = all; } @@ -47,7 +47,7 @@ public GetWorkflowRequest(@Nullable String workflowId, boolean all) { * @param in The input stream to read from * @throws IOException If the stream cannot be read properly */ - public GetWorkflowRequest(StreamInput in) throws IOException { + public GetWorkflowStateRequest(StreamInput in) throws IOException { super(in); this.workflowId = in.readString(); this.all = in.readBoolean(); diff --git a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateResponse.java similarity index 89% rename from src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateResponse.java index 922a8a3f5..ec24aa2cd 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateResponse.java @@ -20,7 +20,7 @@ /** * Transport Response from getting a workflow status */ -public class GetWorkflowResponse extends ActionResponse implements ToXContentObject { +public class GetWorkflowStateResponse extends ActionResponse implements ToXContentObject { /** The workflow state */ public WorkflowState workflowState; @@ -32,7 +32,7 @@ public class GetWorkflowResponse extends ActionResponse implements ToXContentObj * @param in the input stream to read from * @throws IOException if the workflowId cannot be read from the input stream */ - public GetWorkflowResponse(StreamInput in) throws IOException { + public GetWorkflowStateResponse(StreamInput in) throws IOException { super(in); workflowState = new WorkflowState(in); allStatus = in.readBoolean(); @@ -43,7 +43,7 @@ public GetWorkflowResponse(StreamInput in) throws IOException { * @param workflowState the workflow state object * @param allStatus whether to return all fields in state index */ - public GetWorkflowResponse(WorkflowState workflowState, boolean allStatus) { + public GetWorkflowStateResponse(WorkflowState workflowState, boolean allStatus) { if (allStatus) { this.workflowState = workflowState; } else { diff --git a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportAction.java similarity index 87% rename from src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportAction.java index f3bc1dd9e..57fcc2b89 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportAction.java @@ -38,34 +38,34 @@ * Transport Action to get a specific workflow. Currently, we only support the action with _status * in the API path but will add the ability to get the workflow and not just the status in the future */ -public class GetWorkflowTransportAction extends HandledTransportAction { +public class GetWorkflowStateTransportAction extends HandledTransportAction { - private final Logger logger = LogManager.getLogger(GetWorkflowTransportAction.class); + private final Logger logger = LogManager.getLogger(GetWorkflowStateTransportAction.class); private final Client client; private final NamedXContentRegistry xContentRegistry; /** - * Intantiates a new CreateWorkflowTransportAction + * Intantiates a new GetWorkflowStateTransportAction * @param transportService The TransportService * @param actionFilters action filters * @param client The client used to make the request to OS * @param xContentRegistry contentRegister to parse get response */ @Inject - public GetWorkflowTransportAction( + public GetWorkflowStateTransportAction( TransportService transportService, ActionFilters actionFilters, Client client, NamedXContentRegistry xContentRegistry ) { - super(GetWorkflowAction.NAME, transportService, actionFilters, GetWorkflowRequest::new); + super(GetWorkflowStateAction.NAME, transportService, actionFilters, GetWorkflowStateRequest::new); this.client = client; this.xContentRegistry = xContentRegistry; } @Override - protected void doExecute(Task task, GetWorkflowRequest request, ActionListener listener) { + protected void doExecute(Task task, GetWorkflowStateRequest request, ActionListener listener) { String workflowId = request.getWorkflowId(); User user = ParseUtils.getUserContext(client); GetRequest getRequest = new GetRequest(WORKFLOW_STATE_INDEX).id(workflowId); @@ -75,7 +75,7 @@ protected void doExecute(Task task, GetWorkflowRequest request, ActionListener response; + private ActionListener response; private Task task; @Override @@ -52,7 +52,7 @@ public void setUp() throws Exception { super.setUp(); this.client = mock(Client.class); this.threadPool = mock(ThreadPool.class); - this.getWorkflowTransportAction = new GetWorkflowTransportAction( + this.getWorkflowTransportAction = new GetWorkflowStateTransportAction( mock(TransportService.class), mock(ActionFilters.class), client, @@ -65,9 +65,9 @@ public void setUp() throws Exception { when(client.threadPool()).thenReturn(clientThreadPool); when(clientThreadPool.getThreadContext()).thenReturn(threadContext); - response = new ActionListener() { + response = new ActionListener() { @Override - public void onResponse(GetWorkflowResponse getResponse) { + public void onResponse(GetWorkflowStateResponse getResponse) { assertTrue(true); } @@ -78,21 +78,21 @@ public void onFailure(Exception e) {} } public void testGetTransportAction() throws IOException { - GetWorkflowRequest getWorkflowRequest = new GetWorkflowRequest("1234", false); + GetWorkflowStateRequest getWorkflowRequest = new GetWorkflowStateRequest("1234", false); getWorkflowTransportAction.doExecute(task, getWorkflowRequest, response); } public void testGetAction() { - Assert.assertNotNull(GetWorkflowAction.INSTANCE.name()); - Assert.assertEquals(GetWorkflowAction.INSTANCE.name(), GetWorkflowAction.NAME); + Assert.assertNotNull(GetWorkflowStateAction.INSTANCE.name()); + Assert.assertEquals(GetWorkflowStateAction.INSTANCE.name(), GetWorkflowStateAction.NAME); } public void testGetAnomalyDetectorRequest() throws IOException { - GetWorkflowRequest request = new GetWorkflowRequest("1234", false); + GetWorkflowStateRequest request = new GetWorkflowStateRequest("1234", false); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); StreamInput input = out.bytes().streamInput(); - GetWorkflowRequest newRequest = new GetWorkflowRequest(input); + GetWorkflowStateRequest newRequest = new GetWorkflowStateRequest(input); Assert.assertEquals(request.getWorkflowId(), newRequest.getWorkflowId()); Assert.assertEquals(request.getAll(), newRequest.getAll()); Assert.assertNull(newRequest.validate()); @@ -113,10 +113,10 @@ public void testGetAnomalyDetectorResponse() throws IOException { Collections.emptyList() ); - GetWorkflowResponse response = new GetWorkflowResponse(workFlowState, false); + GetWorkflowStateResponse response = new GetWorkflowStateResponse(workFlowState, false); response.writeTo(out); NamedWriteableAwareStreamInput input = new NamedWriteableAwareStreamInput(out.bytes().streamInput(), writableRegistry()); - GetWorkflowResponse newResponse = new GetWorkflowResponse(input); + GetWorkflowStateResponse newResponse = new GetWorkflowStateResponse(input); XContentBuilder builder = TestHelpers.builder(); Assert.assertNotNull(newResponse.toXContent(builder, ToXContent.EMPTY_PARAMS)); From 4b113ba3813dd46d024916b54c013a1add10603f Mon Sep 17 00:00:00 2001 From: Joshua Palis Date: Mon, 11 Dec 2023 20:23:59 +0000 Subject: [PATCH 5/5] Renaming GetTemplate API to GetWorkflow API Signed-off-by: Joshua Palis --- .../flowframework/FlowFrameworkPlugin.java | 10 +++++----- ...Action.java => RestGetWorkflowAction.java} | 14 ++++++------- ...lateAction.java => GetWorkflowAction.java} | 12 +++++------ ...Response.java => GetWorkflowResponse.java} | 10 +++++----- ...n.java => GetWorkflowTransportAction.java} | 14 ++++++------- ...s.java => RestGetWorkflowActionTests.java} | 18 ++++++++--------- .../rest/RestGetWorkflowStateActionTests.java | 18 ++++++++--------- .../GetWorkflowStateTransportActionTests.java | 4 ++-- ...a => GetWorkflowTransportActionTests.java} | 20 +++++++++---------- 9 files changed, 60 insertions(+), 60 deletions(-) rename src/main/java/org/opensearch/flowframework/rest/{RestGetTemplateAction.java => RestGetWorkflowAction.java} (91%) rename src/main/java/org/opensearch/flowframework/transport/{GetTemplateAction.java => GetWorkflowAction.java} (65%) rename src/main/java/org/opensearch/flowframework/transport/{GetTemplateResponse.java => GetWorkflowResponse.java} (84%) rename src/main/java/org/opensearch/flowframework/transport/{GetTemplateTransportAction.java => GetWorkflowTransportAction.java} (88%) rename src/test/java/org/opensearch/flowframework/rest/{RestGetTemplateActionTests.java => RestGetWorkflowActionTests.java} (87%) rename src/test/java/org/opensearch/flowframework/transport/{GetTemplateTransportActionTests.java => GetWorkflowTransportActionTests.java} (91%) diff --git a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java index 8614a0be7..ce6510fbd 100644 --- a/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java +++ b/src/main/java/org/opensearch/flowframework/FlowFrameworkPlugin.java @@ -28,16 +28,16 @@ import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; import org.opensearch.flowframework.indices.FlowFrameworkIndicesHandler; import org.opensearch.flowframework.rest.RestCreateWorkflowAction; -import org.opensearch.flowframework.rest.RestGetTemplateAction; +import org.opensearch.flowframework.rest.RestGetWorkflowAction; import org.opensearch.flowframework.rest.RestGetWorkflowStateAction; import org.opensearch.flowframework.rest.RestProvisionWorkflowAction; import org.opensearch.flowframework.rest.RestSearchWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowAction; import org.opensearch.flowframework.transport.CreateWorkflowTransportAction; -import org.opensearch.flowframework.transport.GetTemplateAction; -import org.opensearch.flowframework.transport.GetTemplateTransportAction; +import org.opensearch.flowframework.transport.GetWorkflowAction; import org.opensearch.flowframework.transport.GetWorkflowStateAction; import org.opensearch.flowframework.transport.GetWorkflowStateTransportAction; +import org.opensearch.flowframework.transport.GetWorkflowTransportAction; import org.opensearch.flowframework.transport.ProvisionWorkflowAction; import org.opensearch.flowframework.transport.ProvisionWorkflowTransportAction; import org.opensearch.flowframework.transport.SearchWorkflowAction; @@ -129,7 +129,7 @@ public List getRestHandlers( new RestProvisionWorkflowAction(flowFrameworkFeatureEnabledSetting), new RestSearchWorkflowAction(flowFrameworkFeatureEnabledSetting), new RestGetWorkflowStateAction(flowFrameworkFeatureEnabledSetting), - new RestGetTemplateAction(flowFrameworkFeatureEnabledSetting) + new RestGetWorkflowAction(flowFrameworkFeatureEnabledSetting) ); } @@ -140,7 +140,7 @@ public List getRestHandlers( new ActionHandler<>(ProvisionWorkflowAction.INSTANCE, ProvisionWorkflowTransportAction.class), new ActionHandler<>(SearchWorkflowAction.INSTANCE, SearchWorkflowTransportAction.class), new ActionHandler<>(GetWorkflowStateAction.INSTANCE, GetWorkflowStateTransportAction.class), - new ActionHandler<>(GetTemplateAction.INSTANCE, GetTemplateTransportAction.class) + new ActionHandler<>(GetWorkflowAction.INSTANCE, GetWorkflowTransportAction.class) ); } diff --git a/src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java b/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java similarity index 91% rename from src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java rename to src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java index bbacaa16f..d2b44f74d 100644 --- a/src/main/java/org/opensearch/flowframework/rest/RestGetTemplateAction.java +++ b/src/main/java/org/opensearch/flowframework/rest/RestGetWorkflowAction.java @@ -19,7 +19,7 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.flowframework.common.FlowFrameworkFeatureEnabledSetting; import org.opensearch.flowframework.exception.FlowFrameworkException; -import org.opensearch.flowframework.transport.GetTemplateAction; +import org.opensearch.flowframework.transport.GetWorkflowAction; import org.opensearch.flowframework.transport.WorkflowRequest; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; @@ -36,23 +36,23 @@ /** * Rest Action to facilitate requests to get a stored template */ -public class RestGetTemplateAction extends BaseRestHandler { +public class RestGetWorkflowAction extends BaseRestHandler { - private static final String GET_TEMPLATE_ACTION = "get_template"; - private static final Logger logger = LogManager.getLogger(RestGetTemplateAction.class); + private static final String GET_WORKFLOW_ACTION = "get_workflow"; + private static final Logger logger = LogManager.getLogger(RestGetWorkflowAction.class); private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; /** * Instantiates a new RestGetWorkflowAction * @param flowFrameworkFeatureEnabledSetting Whether this API is enabled */ - public RestGetTemplateAction(FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting) { + public RestGetWorkflowAction(FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting) { this.flowFrameworkFeatureEnabledSetting = flowFrameworkFeatureEnabledSetting; } @Override public String getName() { - return GET_TEMPLATE_ACTION; + return GET_WORKFLOW_ACTION; } @Override @@ -82,7 +82,7 @@ protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request } WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); - return channel -> client.execute(GetTemplateAction.INSTANCE, workflowRequest, ActionListener.wrap(response -> { + return channel -> client.execute(GetWorkflowAction.INSTANCE, workflowRequest, ActionListener.wrap(response -> { XContentBuilder builder = response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS); channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder)); }, exception -> { diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java similarity index 65% rename from src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java index 8fc3dc7a5..6abee3867 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetTemplateAction.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowAction.java @@ -13,15 +13,15 @@ import static org.opensearch.flowframework.common.CommonValue.TRANSPORT_ACTION_NAME_PREFIX; /** - * External Action for public facing RestGetTemplateAction + * External Action for public facing RestGetWorkflowAction */ -public class GetTemplateAction extends ActionType { +public class GetWorkflowAction extends ActionType { /** The name of this action */ - public static final String NAME = TRANSPORT_ACTION_NAME_PREFIX + "template/get"; + public static final String NAME = TRANSPORT_ACTION_NAME_PREFIX + "workflow/get"; /** An instance of this action */ - public static final GetTemplateAction INSTANCE = new GetTemplateAction(); + public static final GetWorkflowAction INSTANCE = new GetWorkflowAction(); - private GetTemplateAction() { - super(NAME, GetTemplateResponse::new); + private GetWorkflowAction() { + super(NAME, GetWorkflowResponse::new); } } diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java similarity index 84% rename from src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java index 6d9f99068..db70d2cb2 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetTemplateResponse.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowResponse.java @@ -20,26 +20,26 @@ /** * Transport Response from getting a template */ -public class GetTemplateResponse extends ActionResponse implements ToXContentObject { +public class GetWorkflowResponse extends ActionResponse implements ToXContentObject { /** The template */ private Template template; /** - * Instantiates a new GetTemplateResponse from an input stream + * Instantiates a new GetWorkflowResponse from an input stream * @param in the input stream to read from * @throws IOException if the template json cannot be read from the input stream */ - public GetTemplateResponse(StreamInput in) throws IOException { + public GetWorkflowResponse(StreamInput in) throws IOException { super(in); this.template = Template.parse(in.readString()); } /** - * Instantiates a new GetTemplateResponse + * Instantiates a new GetWorkflowResponse * @param template the template */ - public GetTemplateResponse(Template template) { + public GetWorkflowResponse(Template template) { this.template = template; } diff --git a/src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java similarity index 88% rename from src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java rename to src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java index 7dfd94c85..e2a9b1931 100644 --- a/src/main/java/org/opensearch/flowframework/transport/GetTemplateTransportAction.java +++ b/src/main/java/org/opensearch/flowframework/transport/GetWorkflowTransportAction.java @@ -30,33 +30,33 @@ /** * Transport action to retrieve a use case template within the Global Context */ -public class GetTemplateTransportAction extends HandledTransportAction { +public class GetWorkflowTransportAction extends HandledTransportAction { - private final Logger logger = LogManager.getLogger(GetTemplateTransportAction.class); + private final Logger logger = LogManager.getLogger(GetWorkflowTransportAction.class); private final FlowFrameworkIndicesHandler flowFrameworkIndicesHandler; private final Client client; /** - * Instantiates a new GetTempltateTransportAction instance + * Instantiates a new GetWorkflowTransportAction instance * @param transportService the transport service * @param actionFilters action filters * @param flowFrameworkIndicesHandler The Flow Framework indices handler * @param client the Opensearch Client */ @Inject - public GetTemplateTransportAction( + public GetWorkflowTransportAction( TransportService transportService, ActionFilters actionFilters, FlowFrameworkIndicesHandler flowFrameworkIndicesHandler, Client client ) { - super(GetTemplateAction.NAME, transportService, actionFilters, WorkflowRequest::new); + super(GetWorkflowAction.NAME, transportService, actionFilters, WorkflowRequest::new); this.flowFrameworkIndicesHandler = flowFrameworkIndicesHandler; this.client = client; } @Override - protected void doExecute(Task task, WorkflowRequest request, ActionListener listener) { + protected void doExecute(Task task, WorkflowRequest request, ActionListener listener) { if (flowFrameworkIndicesHandler.doesIndexExist(GLOBAL_CONTEXT_INDEX)) { String workflowId = request.getWorkflowId(); @@ -75,7 +75,7 @@ protected void doExecute(Task task, WorkflowRequest request, ActionListener { logger.error("Failed to retrieve template from global context.", exception); diff --git a/src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java b/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowActionTests.java similarity index 87% rename from src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java rename to src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowActionTests.java index 7ed2e1a64..3a51f1a9e 100644 --- a/src/test/java/org/opensearch/flowframework/rest/RestGetTemplateActionTests.java +++ b/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowActionTests.java @@ -26,8 +26,8 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class RestGetTemplateActionTests extends OpenSearchTestCase { - private RestGetTemplateAction restGetTemplateAction; +public class RestGetWorkflowActionTests extends OpenSearchTestCase { + private RestGetWorkflowAction restGetWorkflowAction; private String getPath; private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; private NodeClient nodeClient; @@ -39,17 +39,17 @@ public void setUp() throws Exception { this.getPath = String.format(Locale.ROOT, "%s/{%s}", WORKFLOW_URI, "workflow_id"); flowFrameworkFeatureEnabledSetting = mock(FlowFrameworkFeatureEnabledSetting.class); when(flowFrameworkFeatureEnabledSetting.isFlowFrameworkEnabled()).thenReturn(true); - this.restGetTemplateAction = new RestGetTemplateAction(flowFrameworkFeatureEnabledSetting); + this.restGetWorkflowAction = new RestGetWorkflowAction(flowFrameworkFeatureEnabledSetting); this.nodeClient = mock(NodeClient.class); } public void testRestGetWorkflowActionName() { - String name = restGetTemplateAction.getName(); - assertEquals("get_template", name); + String name = restGetWorkflowAction.getName(); + assertEquals("get_workflow", name); } public void testRestGetWorkflowActionRoutes() { - List routes = restGetTemplateAction.routes(); + List routes = restGetWorkflowAction.routes(); assertEquals(1, routes.size()); assertEquals(RestRequest.Method.GET, routes.get(0).getMethod()); assertEquals(this.getPath, routes.get(0).getPath()); @@ -63,7 +63,7 @@ public void testInvalidRequestWithContent() { FakeRestChannel channel = new FakeRestChannel(request, false, 1); IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> { - restGetTemplateAction.handleRequest(request, channel, nodeClient); + restGetWorkflowAction.handleRequest(request, channel, nodeClient); }); assertEquals("request [POST /_plugins/_flow_framework/workflow/{workflow_id}] does not support having a body", ex.getMessage()); } @@ -76,7 +76,7 @@ public void testNullWorkflowId() throws Exception { .build(); FakeRestChannel channel = new FakeRestChannel(request, true, 1); - restGetTemplateAction.handleRequest(request, channel, nodeClient); + restGetWorkflowAction.handleRequest(request, channel, nodeClient); assertEquals(1, channel.errors().get()); assertEquals(RestStatus.BAD_REQUEST, channel.capturedResponse().status()); @@ -89,7 +89,7 @@ public void testFeatureFlagNotEnabled() throws Exception { .withPath(this.getPath) .build(); FakeRestChannel channel = new FakeRestChannel(request, false, 1); - restGetTemplateAction.handleRequest(request, channel, nodeClient); + restGetWorkflowAction.handleRequest(request, channel, nodeClient); assertEquals(RestStatus.FORBIDDEN, channel.capturedResponse().status()); assertTrue(channel.capturedResponse().content().utf8ToString().contains("This API is disabled.")); } diff --git a/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowStateActionTests.java b/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowStateActionTests.java index 1d0b7ae4a..dc605a5cd 100644 --- a/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowStateActionTests.java +++ b/src/test/java/org/opensearch/flowframework/rest/RestGetWorkflowStateActionTests.java @@ -27,7 +27,7 @@ import static org.mockito.Mockito.when; public class RestGetWorkflowStateActionTests extends OpenSearchTestCase { - private RestGetWorkflowStateAction restGetWorkflowAction; + private RestGetWorkflowStateAction restGetWorkflowStateAction; private String getPath; private NodeClient nodeClient; private FlowFrameworkFeatureEnabledSetting flowFrameworkFeatureEnabledSetting; @@ -39,7 +39,7 @@ public void setUp() throws Exception { this.getPath = String.format(Locale.ROOT, "%s/{%s}/%s", WORKFLOW_URI, "workflow_id", "_status"); flowFrameworkFeatureEnabledSetting = mock(FlowFrameworkFeatureEnabledSetting.class); when(flowFrameworkFeatureEnabledSetting.isFlowFrameworkEnabled()).thenReturn(true); - this.restGetWorkflowAction = new RestGetWorkflowStateAction(flowFrameworkFeatureEnabledSetting); + this.restGetWorkflowStateAction = new RestGetWorkflowStateAction(flowFrameworkFeatureEnabledSetting); this.nodeClient = mock(NodeClient.class); } @@ -48,13 +48,13 @@ public void testConstructor() { assertNotNull(getWorkflowAction); } - public void testRestGetWorkflowActionName() { - String name = restGetWorkflowAction.getName(); + public void testRestGetWorkflowStateActionName() { + String name = restGetWorkflowStateAction.getName(); assertEquals("get_workflow_state", name); } - public void testRestGetWorkflowActionRoutes() { - List routes = restGetWorkflowAction.routes(); + public void testRestGetWorkflowStateActionRoutes() { + List routes = restGetWorkflowStateAction.routes(); assertEquals(1, routes.size()); assertEquals(RestRequest.Method.GET, routes.get(0).getMethod()); assertEquals(this.getPath, routes.get(0).getPath()); @@ -68,7 +68,7 @@ public void testNullWorkflowId() throws Exception { .build(); FakeRestChannel channel = new FakeRestChannel(request, true, 1); - restGetWorkflowAction.handleRequest(request, channel, nodeClient); + restGetWorkflowStateAction.handleRequest(request, channel, nodeClient); assertEquals(1, channel.errors().get()); assertEquals(RestStatus.BAD_REQUEST, channel.capturedResponse().status()); @@ -83,7 +83,7 @@ public void testInvalidRequestWithContent() { FakeRestChannel channel = new FakeRestChannel(request, false, 1); IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> { - restGetWorkflowAction.handleRequest(request, channel, nodeClient); + restGetWorkflowStateAction.handleRequest(request, channel, nodeClient); }); assertEquals( "request [POST /_plugins/_flow_framework/workflow/{workflow_id}/_status] does not support having a body", @@ -97,7 +97,7 @@ public void testFeatureFlagNotEnabled() throws Exception { .withPath(this.getPath) .build(); FakeRestChannel channel = new FakeRestChannel(request, false, 1); - restGetWorkflowAction.handleRequest(request, channel, nodeClient); + restGetWorkflowStateAction.handleRequest(request, channel, nodeClient); assertEquals(RestStatus.FORBIDDEN, channel.capturedResponse().status()); assertTrue(channel.capturedResponse().content().utf8ToString().contains("This API is disabled.")); } diff --git a/src/test/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportActionTests.java b/src/test/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportActionTests.java index bc114c46b..a21389550 100644 --- a/src/test/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportActionTests.java +++ b/src/test/java/org/opensearch/flowframework/transport/GetWorkflowStateTransportActionTests.java @@ -87,7 +87,7 @@ public void testGetAction() { Assert.assertEquals(GetWorkflowStateAction.INSTANCE.name(), GetWorkflowStateAction.NAME); } - public void testGetAnomalyDetectorRequest() throws IOException { + public void testGetWorkflowStateRequest() throws IOException { GetWorkflowStateRequest request = new GetWorkflowStateRequest("1234", false); BytesStreamOutput out = new BytesStreamOutput(); request.writeTo(out); @@ -98,7 +98,7 @@ public void testGetAnomalyDetectorRequest() throws IOException { Assert.assertNull(newRequest.validate()); } - public void testGetAnomalyDetectorResponse() throws IOException { + public void testGetWorkflowStateResponse() throws IOException { BytesStreamOutput out = new BytesStreamOutput(); String workflowId = randomAlphaOfLength(5); WorkflowState workFlowState = new WorkflowState( diff --git a/src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java b/src/test/java/org/opensearch/flowframework/transport/GetWorkflowTransportActionTests.java similarity index 91% rename from src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java rename to src/test/java/org/opensearch/flowframework/transport/GetWorkflowTransportActionTests.java index 948e1bbd0..d7db8a2c9 100644 --- a/src/test/java/org/opensearch/flowframework/transport/GetTemplateTransportActionTests.java +++ b/src/test/java/org/opensearch/flowframework/transport/GetWorkflowTransportActionTests.java @@ -45,11 +45,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -public class GetTemplateTransportActionTests extends OpenSearchTestCase { +public class GetWorkflowTransportActionTests extends OpenSearchTestCase { private ThreadPool threadPool; private Client client; - private GetTemplateTransportAction getTemplateTransportAction; + private GetWorkflowTransportAction getTemplateTransportAction; private FlowFrameworkIndicesHandler flowFrameworkIndicesHandler; private Template template; @@ -59,7 +59,7 @@ public void setUp() throws Exception { this.threadPool = mock(ThreadPool.class); this.client = mock(Client.class); this.flowFrameworkIndicesHandler = mock(FlowFrameworkIndicesHandler.class); - this.getTemplateTransportAction = new GetTemplateTransportAction( + this.getTemplateTransportAction = new GetWorkflowTransportAction( mock(TransportService.class), mock(ActionFilters.class), flowFrameworkIndicesHandler, @@ -94,11 +94,11 @@ public void setUp() throws Exception { } - public void testGetTemplateNoGlobalContext() { + public void testGetWorkflowNoGlobalContext() { when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(false); @SuppressWarnings("unchecked") - ActionListener listener = mock(ActionListener.class); + ActionListener listener = mock(ActionListener.class); WorkflowRequest workflowRequest = new WorkflowRequest("1", null); getTemplateTransportAction.doExecute(mock(Task.class), workflowRequest, listener); @@ -107,10 +107,10 @@ public void testGetTemplateNoGlobalContext() { assertTrue(exceptionCaptor.getValue().getMessage().contains("There are no templates in the global_context")); } - public void testGetTemplateSuccess() { + public void testGetWorkflowSuccess() { String workflowId = "12345"; @SuppressWarnings("unchecked") - ActionListener listener = mock(ActionListener.class); + ActionListener listener = mock(ActionListener.class); WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(true); @@ -129,15 +129,15 @@ public void testGetTemplateSuccess() { getTemplateTransportAction.doExecute(mock(Task.class), workflowRequest, listener); - ArgumentCaptor templateCaptor = ArgumentCaptor.forClass(GetTemplateResponse.class); + ArgumentCaptor templateCaptor = ArgumentCaptor.forClass(GetWorkflowResponse.class); verify(listener, times(1)).onResponse(templateCaptor.capture()); assertEquals(this.template.name(), templateCaptor.getValue().getTemplate().name()); } - public void testGetTemplateFailure() { + public void testGetWorkflowFailure() { String workflowId = "12345"; @SuppressWarnings("unchecked") - ActionListener listener = mock(ActionListener.class); + ActionListener listener = mock(ActionListener.class); WorkflowRequest workflowRequest = new WorkflowRequest(workflowId, null); when(flowFrameworkIndicesHandler.doesIndexExist(anyString())).thenReturn(true);