Skip to content

Commit

Permalink
[Backport 2.x] Moved workflow-steps.json to Enum (#529)
Browse files Browse the repository at this point in the history
Moved workflow-steps.json to Enum (#523)

* Created enum for workflow steps json



* Added getters for enum and rest of the enums



* Removed workflow-steps.json entries and the file completely



* Fixed tests



* Added entry to CHANGELOG.md



* Addressed PR comments and removed the map



* Updated CHANGELOG.md



---------


(cherry picked from commit be0df19)

Signed-off-by: Owais Kazi <[email protected]>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 21eeb95 commit 4446fb4
Show file tree
Hide file tree
Showing 15 changed files with 552 additions and 410 deletions.
39 changes: 20 additions & 19 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
CHANGELOG

# CHANGELOG
All notable changes to this project are documented in this file.

Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)

2.12.0 Initial Release
## [Unreleased]
### Added
- Github workflow for changelog verification ([#440](https://github.com/opensearch-project/flow-framework/pull/440))

### Changed

### Deprecated

### Removed

### Fixed

### Security


[Unreleased]: https://github.com/opensearch-project/flow-framework/compare/2.x...HEAD
## [Unreleased 3.0](https://github.com/opensearch-project/flow-framework/compare/2.x...HEAD)
### Features
### Enhancements
### Bug Fixes
### Infrastructure
### Documentation
### Maintenance
### Refactoring

## [Unreleased 2.x](https://github.com/opensearch-project/flow-framework/compare/2.12...2.x)
### Features
### Enhancements
### Bug Fixes
### Infrastructure
### Documentation
### Maintenance
### Refactoring
- Moved workflow-steps.json to Enum ([#523](https://github.com/opensearch-project/flow-framework/pull/523))
2 changes: 1 addition & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ To add functionality to workflows, add new Workflow Steps to the [`org.opensearc
1. Implement the [Workflow](https://github.com/opensearch-project/flow-framework/blob/main/src/main/java/org/opensearch/flowframework/workflow/WorkflowStep.java) interface. See existing steps for examples for input, output, and API execution.
2. Choose a unique name for the step which is not used by other steps. This will align with the `step_type` field in the templates and should be descriptive of what the step does.
3. Add a constructor and call it from the [WorkflowStepFactory](https://github.com/opensearch-project/flow-framework/blob/main/src/main/java/org/opensearch/flowframework/workflow/WorkflowStepFactory.java).
4. Add a configuration to the [`workflow-steps.json`](https://github.com/opensearch-project/flow-framework/blob/main/src/main/resources/mappings/workflow-steps.json) file specifying required inputs, outputs, required plugins, and optionally a different timeout than the default.
4. Add an entry to the [WorkflowStepFactory](https://github.com/opensearch-project/flow-framework/blob/main/src/main/java/org/opensearch/flowframework/workflow/WorkflowStepFactory.java) enum specifying required inputs, outputs, required plugins, and optionally a different timeout than the default.
5. If your step provisions a resource that should be deprovisioned, create the corresponding step and add both steps to the [`WorkflowResources`](https://github.com/opensearch-project/flow-framework/blob/main/src/main/java/org/opensearch/flowframework/common/WorkflowResources.java) enum.
6. Write unit and integration tests.
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,6 @@ private CommonValue() {}
public static final String RESOURCE_TYPE = "resource_type";
/** The field name for the resource id */
public static final String RESOURCE_ID = "resource_id";
/** The field name for the opensearch-ml plugin */
public static final String OPENSEARCH_ML = "opensearch-ml";
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.flowframework.exception.FlowFrameworkException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken;

/**
* This represents an object of workflow steps json which maps each step to expected inputs and outputs
*/
Expand All @@ -39,81 +33,34 @@ public class WorkflowStepValidator implements ToXContentObject {
/** Timeout field name */
private static final String TIMEOUT = "timeout";

private String workflowStep;
private List<String> inputs;
private List<String> outputs;
private List<String> requiredPlugins;
private TimeValue timeout;

/**
* Instantiate the object representing a Workflow Step validator
* @param workflowStep name of the workflow step
* @param inputs the workflow step inputs
* @param outputs the workflow step outputs
* @param requiredPlugins the required plugins for this workflow step
* @param timeout the timeout for this workflow step
*/
public WorkflowStepValidator(List<String> inputs, List<String> outputs, List<String> requiredPlugins, TimeValue timeout) {
public WorkflowStepValidator(
String workflowStep,
List<String> inputs,
List<String> outputs,
List<String> requiredPlugins,
TimeValue timeout
) {
this.workflowStep = workflowStep;
this.inputs = inputs;
this.outputs = outputs;
this.requiredPlugins = requiredPlugins;
this.timeout = timeout;
}

/**
* Parse raw json content into a WorkflowStepValidator instance
* @param parser json based content parser
* @return an instance of the WorkflowStepValidator
* @throws IOException if the content cannot be parsed correctly
*/
public static WorkflowStepValidator parse(XContentParser parser) throws IOException {
List<String> parsedInputs = new ArrayList<>();
List<String> parsedOutputs = new ArrayList<>();
List<String> requiredPlugins = new ArrayList<>();
TimeValue timeout = null;

ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
String fieldName = parser.currentName();
parser.nextToken();
switch (fieldName) {
case INPUTS_FIELD:
ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
parsedInputs.add(parser.text());
}
break;
case OUTPUTS_FIELD:
ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
parsedOutputs.add(parser.text());
}
break;
case REQUIRED_PLUGINS:
ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
requiredPlugins.add(parser.text());
}
break;
case TIMEOUT:
try {
timeout = TimeValue.parseTimeValue(parser.text(), TIMEOUT);
} catch (IllegalArgumentException e) {
logger.error("Failed to parse TIMEOUT value for field [{}]", fieldName, e);
throw new FlowFrameworkException(
"Failed to parse workflow-step.json file for field [" + fieldName + "]",
RestStatus.INTERNAL_SERVER_ERROR
);
}
break;
default:
throw new FlowFrameworkException(
"Unable to parse field [" + fieldName + "] in a WorkflowStepValidator object.",
RestStatus.BAD_REQUEST
);
}
}
return new WorkflowStepValidator(parsedInputs, parsedOutputs, requiredPlugins, timeout);
}

/**
* Get the required inputs
* @return the inputs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@
import org.opensearch.common.xcontent.json.JsonXContent;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.flowframework.util.ParseUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken;

/**
* This represents the workflow steps json which maps each step to expected inputs and outputs
*/
Expand All @@ -35,37 +30,6 @@ public WorkflowValidator(Map<String, WorkflowStepValidator> workflowStepValidato
this.workflowStepValidators = workflowStepValidators;
}

/**
* Parse raw json content into a WorkflowValidator instance
* @param parser json based content parser
* @return an instance of the WorkflowValidator
* @throws IOException if the content cannot be parsed correctly
*/
public static WorkflowValidator parse(XContentParser parser) throws IOException {

Map<String, WorkflowStepValidator> workflowStepValidators = new HashMap<>();

ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
String type = parser.currentName();
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
workflowStepValidators.put(type, WorkflowStepValidator.parse(parser));
}
return new WorkflowValidator(workflowStepValidators);
}

/**
* Parse a workflow step JSON file into a WorkflowValidator object
*
* @param file the file name of the workflow step json
* @return A {@link WorkflowValidator} represented by the JSON
* @throws IOException on failure to read and parse the json file
*/
public static WorkflowValidator parse(String file) throws IOException {
String json = ParseUtils.resourceToString("/" + file);
return parse(ParseUtils.jsonToParser(json));
}

/**
* Output this object in a compact JSON string.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.flowframework.model.WorkflowValidator;
import org.opensearch.flowframework.workflow.WorkflowStepFactory;

import java.io.IOException;

Expand All @@ -23,6 +24,7 @@
public class GetWorkflowStepResponse extends ActionResponse implements ToXContentObject {

private WorkflowValidator workflowValidator;
private WorkflowStepFactory workflowStepFactory;

/**
* Instantiates a new GetWorkflowStepResponse from an input stream
Expand All @@ -31,7 +33,7 @@ public class GetWorkflowStepResponse extends ActionResponse implements ToXConten
*/
public GetWorkflowStepResponse(StreamInput in) throws IOException {
super(in);
this.workflowValidator = WorkflowValidator.parse(in.readString());
this.workflowValidator = this.workflowStepFactory.getWorkflowValidator();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.opensearch.core.action.ActionListener;
import org.opensearch.flowframework.exception.FlowFrameworkException;
import org.opensearch.flowframework.model.WorkflowValidator;
import org.opensearch.flowframework.workflow.WorkflowStepFactory;
import org.opensearch.tasks.Task;
import org.opensearch.transport.TransportService;

Expand All @@ -27,21 +28,29 @@
public class GetWorkflowStepTransportAction extends HandledTransportAction<ActionRequest, GetWorkflowStepResponse> {

private final Logger logger = LogManager.getLogger(GetWorkflowStepTransportAction.class);
private final WorkflowStepFactory workflowStepFactory;

/**
* Instantiates a new GetWorkflowStepTransportAction instance
* @param transportService the transport service
* @param actionFilters action filters
* @param workflowStepFactory The factory instantiating workflow steps
*/
@Inject
public GetWorkflowStepTransportAction(TransportService transportService, ActionFilters actionFilters) {
public GetWorkflowStepTransportAction(
TransportService transportService,
ActionFilters actionFilters,
WorkflowStepFactory workflowStepFactory
) {
super(GetWorkflowStepAction.NAME, transportService, actionFilters, WorkflowRequest::new);
this.workflowStepFactory = workflowStepFactory;
}

@Override
protected void doExecute(Task task, ActionRequest request, ActionListener<GetWorkflowStepResponse> listener) {
try {
listener.onResponse(new GetWorkflowStepResponse(WorkflowValidator.parse("mappings/workflow-steps.json")));
WorkflowValidator workflowValidator = this.workflowStepFactory.getWorkflowValidator();
listener.onResponse(new GetWorkflowStepResponse(workflowValidator));
} catch (Exception e) {
logger.error("Failed to retrieve workflow step json.", e);
listener.onFailure(new FlowFrameworkException(e.getMessage(), ExceptionsHelper.status(e)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ private Map<String, String> getToolsParametersMap(
Map<String, String> previousNodeInputs,
Map<String, WorkflowData> outputs
) {
@SuppressWarnings("unchecked")
Map<String, String> parametersMap = (Map<String, String>) parameters;
Optional<String> previousNodeModel = previousNodeInputs.entrySet()
.stream()
Expand Down
Loading

0 comments on commit 4446fb4

Please sign in to comment.