Skip to content
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

[BUG] TypeCast issue for Create Connector #123

Closed
owaiskazi19 opened this issue Oct 30, 2023 · 1 comment · Fixed by #127
Closed

[BUG] TypeCast issue for Create Connector #123

owaiskazi19 opened this issue Oct 30, 2023 · 1 comment · Fixed by #127
Assignees
Labels
bug Something isn't working

Comments

@owaiskazi19
Copy link
Member

What is the bug?

When invoking create connector workflow step using execute API it fails with the below

[2023-10-30T20:35:21,118][ERROR][o.o.f.t.ProvisionWorkflowTransportAction] [ip-172-31-56-214] Provisioning failed for workflow wG5LgosB1lilWaNu-qh2 : org.opensearch.flowframework.exception.FlowFrameworkException: java.lang.ClassCastException: class [Ljava.util.Map; cannot be cast to class java.util.List ([Ljava.util.Map; and java.util.List are in module java.base of loader 'bootstrap')

The issue on casting the content object to List<ConnectorActions> here.

How can one reproduce the bug?

  1. Run OS cluster with ml-commons and flow-framework plugin installed.
  2. Hit the execute API
curl -XPOST --insecure -u 'admin:admin' -H "Content-Type: application/json" 'http://localhost:9200/_plugins/_flow_framework/workflow' -d '{"name":"deploy-register-model","description":"test case","use_case":"SEMANTIC_SEARCH","version":{"template":"1.0.0","compatibility":["2.12.0","3.0.0"]},"workflows":{"provision":{"nodes":[{"id":"workflow_step_1","type":"create_connector","inputs":{"name":"OpenAI Chat Connector","description":"The connector to public OpenAI model service for GPT 3.5","version":"1","protocol":"http","parameters":{"endpoint":"api.openai.com","model":"gpt-3.5-turbo"},"credential":{"openAI_key":"..."},"actions":[{"action_type":"predict","method":"POST","url":"https://${parameters.endpoint}/v1/chat/completions"}]}},{"id":"workflow_step_2","type":"deploy_model","inputs":{"model_id":{}}}],"edges":[{"source":"workflow_step_1","dest":"workflow_step_2"}]}}}'
  1. Invoke the provision API:
curl -XPOST --insecure -u 'admin:admin' -H "Content-Type: application/json" 'http://localhost:9200/_plugins/_flow_framework/workflow/<workflow ID from previous step>/_provision'

What is the expected behavior?

A connector should be created.

What is your host/environment?

Ubuntu

Do you have any screenshots?

If applicable, add screenshots to help explain your problem.

Do you have any additional context?

Add any other context about the problem.

@dbwiddis
Copy link
Member

The WorkflowData is just a Map<String,Object> where there needs to be a strong understanding of what type of object a particular key represents. In this case we are associating the "actions" key with a List<ConnectorAction>:
https://github.com/opensearch-project/opensearch-ai-flow-framework/blob/bcd53e1ded659146913a7c30d5b08a6f34194352/src/main/java/org/opensearch/flowframework/workflow/CreateConnectorStep.java#L114-L115

(Side note 1: this generates a compiler warning as an unchecked cast and probably should be handled in a separate getter method that validates the typecast.)

(Side note 2: we are iterating an entrySet() so using get() on the original connection should be replaced by entry.getValue().)

Actions comes from the initialization of the workflow step when it parses this:

"inputs":{
    "actions":[
        {
            "action_type":"predict",
            "method":"POST",
            "url":"https://${parameters.endpoint}/v1/chat/completions"
        }
    ]
}

So let's see where we use this ACTIONS_FIELD key to write that List:
https://github.com/search?q=repo%3Aopensearch-project/opensearch-ai-flow-framework%20ACTIONS_FIELD&type=code

Hmmm, wait. We didn't use it. Well that would explain why we can't parse it. Where should we have used it? Let's look for where we output the parent INPUTS_FIELD key:
https://github.com/search?q=repo%3Aopensearch-project%2Fopensearch-ai-flow-framework%20INPUTS_FIELD&type=code

Aha! So that leads us here, were we have special treatment when it sees an array for creating a list of PROCESSORS_FIELD:
https://github.com/opensearch-project/opensearch-ai-flow-framework/blob/bcd53e1ded659146913a7c30d5b08a6f34194352/src/main/java/org/opensearch/flowframework/model/WorkflowNode.java#L134-L147

But nothing there for ACTIONS_FIELD so it falls into the else clause and creates a List<Map<String, String>> which is then cast to a Map[] array as the value for inputs field. That's passed to our initial WorkflowData element here:
https://github.com/opensearch-project/opensearch-ai-flow-framework/blob/4106cbae2904d210659d4a6646574a2e51f71984/src/main/java/org/opensearch/flowframework/workflow/WorkflowProcessSorter.java#L68

So the object retrieved in content.get(ACTIONS_FIELD) is an array of Map<String, String>, not a List<ConnectorAction>.

TLDR: nowhere prior to this cast do we even see the ConnectorAction class. This object should be properly cast to the array of maps that it is, and iterated to produce the ConnectorAction list in a helper method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants