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

DataInputSchema can only be a string and not an object #196

Merged
merged 5 commits into from
May 8, 2024

Conversation

spolti
Copy link
Member

@spolti spolti commented Nov 29, 2023

fixes #194

Many thanks for submitting your Pull Request ❤️!

What this PR does / why we need it:

Special notes for reviewers:

Additional information (if needed):

@spolti
Copy link
Member Author

spolti commented Nov 29, 2023

@ricardozanini PTAL.

there is one test specific that I left a comment, we would need to revisit that later.

model/workflow.go Outdated Show resolved Hide resolved
model/workflow_validator_test.go Outdated Show resolved Hide resolved
@ricardozanini
Copy link
Member

@ribeiromiranda wanna take a look?

model/workflow.go Outdated Show resolved Hide resolved
parser/parser_test.go Outdated Show resolved Hide resolved
model/workflow_test.go Outdated Show resolved Hide resolved
@ricardozanini
Copy link
Member

@spolti can you rebase and review @ribeiromiranda's comment?

Copy link

github-actions bot commented Feb 2, 2024

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@ricardozanini
Copy link
Member

@spolti are you still on this? :D

@spolti
Copy link
Member Author

spolti commented Feb 8, 2024

Yes, sry, will try to revisit it this or next week.

Copy link

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@spolti
Copy link
Member Author

spolti commented Apr 3, 2024

@ribeiromiranda hi,
Just got it using your tool, the version in the go.mod does not looks correct.
https://github.com/galgotech/builder-gen/blob/main/go.mod#L3C1-L3C11?

go: github.com/galgotech/builder-gen@latest (in github.com/galgotech/builder-gen@v0.0.0-20231121195112-e44977c5b75f): go.mod:3: invalid go version '1.20.11': must match format 1.23

Makefile Outdated Show resolved Hide resolved
@spolti
Copy link
Member Author

spolti commented Apr 3, 2024

There is a small issue on a third party lib, please take a look in the comments.

Copy link
Member

@ricardozanini ricardozanini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ribeiromiranda can you downgrade your library's Go version?

@ribeiromiranda
Copy link
Collaborator

There is a small issue on a third party lib, please take a look in the comments.

Changed version to 1.19

@ricardozanini
Copy link
Member

@spolti ^

@spolti
Copy link
Member Author

spolti commented Apr 5, 2024

updated. Thanks @ribeiromiranda

@ricardozanini
Copy link
Member

@ribeiromiranda can you please review?

@ribeiromiranda
Copy link
Collaborator

ribeiromiranda commented Apr 6, 2024

@ricardozanini @spolti Are all inputs valid?

id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: "file://testdata/datainputschema.json"
...
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: "{}"
...
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema:
  schema: "file://testdata/datainputschema.json"
...
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema:
  schema: "{}"
...

@ricardozanini
Copy link
Member

@ribeiromiranda yes, it should.

@spolti
Copy link
Member Author

spolti commented Apr 25, 2024

Option 2 should be invalid, since we check the schema field

if d.Schema != nil && d.Schema.Type == String {

@spolti
Copy link
Member Author

spolti commented Apr 25, 2024

are we clear to merge this one?

@ribeiromiranda
Copy link
Collaborator

@ricardozanini @spolti
Another question, it wasn't clear to me in the specification.

Which is right, JSON with or without quotes?

1.
```yaml
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: "{ \"test\": \"value\" }"
...
2.
```yaml
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: {
  "test": "value"
}
...

@ribeiromiranda
Copy link
Collaborator

ribeiromiranda commented May 4, 2024

@ricardozanini @spolti With the patch all cases below will work.

dataInputSchema: "{\"key\": \"value\"}"
dataInputSchema: {"key": "value"}
dataInputSchema: file://...
dataInputSchema:
  schema: "{\"key\": \"value\"}"
  failOnValidationErrors: true
dataInputSchema:
  schema: {"key": "value"}
  failOnValidationErrors: true
dataInputSchema:
  schema: file://...
  failOnValidationErrors: true 
diff --git a/model/workflow.go b/model/workflow.go
index d0ac4c7..aa72d1f 100644
--- a/model/workflow.go
+++ b/model/workflow.go
@@ -15,8 +15,9 @@
 package model
 
 import (
+	"bytes"
 	"encoding/json"
-	"regexp"
+	"errors"
 
 	"github.com/serverlessworkflow/sdk-go/v2/util"
 )
@@ -522,33 +523,41 @@ type dataInputSchemaUnmarshal DataInputSchema
 // UnmarshalJSON implements json.Unmarshaler
 func (d *DataInputSchema) UnmarshalJSON(data []byte) error {
 	d.ApplyDefault()
-	err := util.UnmarshalObject("dataInputSchema", data, (*dataInputSchemaUnmarshal)(d))
+
+	// expected: data = "{\"key\": \"value\"}"
+	//           data = {"key": "value"}
+	//	         data = "file://..."
+	//           data = { "schema": "{\"key\": \"value\"}", "failOnValidationErrors": true }
+	//           data = { "schema": {"key": "value"}, "failOnValidationErrors": true }
+	//           data = { "schema": "file://...", "failOnValidationErrors": true }
+
+	schemaString := ""
+	err := util.UnmarshalPrimitiveOrObject("dataInputSchema", data, &schemaString, (*dataInputSchemaUnmarshal)(d))
 	if err != nil {
 		return err
 	}
 
-	if d.Schema != nil && d.Schema.Type == String {
-		// Define the regex pattern to match the prefixes
-		pattern := `^(http|https|file)`
-		regex := regexp.MustCompile(pattern)
-		// if it is not external, treat as JSON object
-		if !regex.MatchString(d.Schema.StringValue) {
-			point := FromString(d.Schema.StringValue)
-			d.Schema = &point
+	if d.Schema != nil {
+		if d.Schema.Type == Map {
 			return nil
-		}
 
-		data, err := util.LoadExternalResource(d.Schema.StringValue)
-		if err != nil {
-			return err
+		} else if d.Schema.Type == String {
+			schemaString = d.Schema.StringValue
+
+		} else {
+			return errors.New("invalid dataInputSchema must be a string or object")
 		}
+	}
 
-		er := util.UnmarshalObject("schema", data, &d.Schema)
-		// clean the string value to avoid the json URI being appended
-		d.Schema.StringValue = ""
-		return er
+	if schemaString != "" {
+		data = []byte(schemaString)
+		if bytes.TrimSpace(data)[0] != '{' {
+			data = []byte("\"" + schemaString + "\"")
+		}
 	}
-	return nil
+
+	d.Schema = new(Object)
+	return util.UnmarshalObjectOrFile("schema", data, &d.Schema)
 }
 
 // ApplyDefault set the default values for Data Input Schema
diff --git a/model/workflow_test.go b/model/workflow_test.go
index 70aa2d8..a5aa42a 100644
--- a/model/workflow_test.go
+++ b/model/workflow_test.go
@@ -499,7 +499,11 @@ func TestTransitionUnmarshalJSON(t *testing.T) {
 
 func TestDataInputSchemaUnmarshalJSON(t *testing.T) {
 
-	schemaName := FromString("schema name")
+	var schemaName Object
+	err := json.Unmarshal([]byte("{\"key\": \"value\"}"), &schemaName)
+	if !assert.NoError(t, err) {
+		return
+	}
 
 	type testCase struct {
 		desp   string
@@ -511,16 +515,25 @@ func TestDataInputSchemaUnmarshalJSON(t *testing.T) {
 	testCases := []testCase{
 		{
 			desp: "string success",
-			data: `"schema name"`,
+			data: "{\"key\": \"value\"}",
 			expect: DataInputSchema{
 				Schema:                 &schemaName,
 				FailOnValidationErrors: true,
 			},
-			err: `dataInputSchema must be string or object`,
+			err: ``,
 		},
 		{
-			desp: `object success`,
-			data: `{"schema": "schema name"}`,
+			desp: "string fail",
+			data: "{\"key\": }",
+			expect: DataInputSchema{
+				Schema:                 &schemaName,
+				FailOnValidationErrors: true,
+			},
+			err: `invalid character '}' looking for beginning of value`,
+		},
+		{
+			desp: `object success (without quotes)`,
+			data: `{"key": "value"}`,
 			expect: DataInputSchema{
 				Schema:                 &schemaName,
 				FailOnValidationErrors: true,
@@ -528,22 +541,32 @@ func TestDataInputSchemaUnmarshalJSON(t *testing.T) {
 			err: ``,
 		},
 		{
-			desp: `object fail`,
-			data: `{"schema": "schema name}`,
+			desp: `schema object success`,
+			data: `{"schema": "{\"key\": \"value\"}"}`,
 			expect: DataInputSchema{
 				Schema:                 &schemaName,
 				FailOnValidationErrors: true,
 			},
-			err: `unexpected end of JSON input`,
+			err: ``,
 		},
 		{
-			desp: `object key invalid`,
-			data: `{"schema_invalid": "schema name"}`,
+			desp: `schema object success (without quotes)`,
+			data: `{"schema": {"key": "value"}}`,
 			expect: DataInputSchema{
+				Schema:                 &schemaName,
 				FailOnValidationErrors: true,
 			},
 			err: ``,
 		},
+		{
+			desp: `schema object fail`,
+			data: `{"schema": "schema name}`,
+			expect: DataInputSchema{
+				Schema:                 &schemaName,
+				FailOnValidationErrors: true,
+			},
+			err: `unexpected end of JSON input`,
+		},
 	}
 	for _, tc := range testCases {
 		t.Run(tc.desp, func(t *testing.T) {
@@ -551,13 +574,14 @@ func TestDataInputSchemaUnmarshalJSON(t *testing.T) {
 			err := json.Unmarshal([]byte(tc.data), &v)
 
 			if tc.err != "" {
-				assert.Error(t, err)
-				assert.Regexp(t, tc.err, err)
+				assert.Error(t, err, tc.desp)
+				assert.Regexp(t, tc.err, err, tc.desp)
 				return
 			}
 
-			assert.NoError(t, err)
-			assert.Equal(t, tc.expect, v)
+			assert.NoError(t, err, tc.desp)
+			assert.Equal(t, tc.expect.Schema, v.Schema, tc.desp)
+			assert.Equal(t, tc.expect.FailOnValidationErrors, v.FailOnValidationErrors, tc.desp)
 		})
 	}
 }
diff --git a/util/unmarshal.go b/util/unmarshal.go
index 9d5b1c2..d00e9d2 100644
--- a/util/unmarshal.go
+++ b/util/unmarshal.go
@@ -221,7 +221,7 @@ func UnmarshalObjectOrFile[U any](parameterName string, data []byte, valObject *
 	}
 
 	data = bytes.TrimSpace(data)
-	if data[0] == '{' && parameterName != "constants" && parameterName != "timeouts" {
+	if data[0] == '{' && parameterName != "constants" && parameterName != "timeouts" && parameterName != "schema" {
 		extractData := map[string]json.RawMessage{}
 		err = json.Unmarshal(data, &extractData)
 		if err != nil {

@ricardozanini
Copy link
Member

@ricardozanini @spolti Another question, it wasn't clear to me in the specification.

Which is right, JSON with or without quotes?

1.
```yaml
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: "{ \"test\": \"value\" }"
...
2.
```yaml
id: Valid DataInputSchema
version: '1.0'
specVersion: '0.8'
start: Start
dataInputSchema: {
  "test": "value"
}
...

If we can convert the { "test": "value" } into a valid JSON Schema, both are.

@ricardozanini
Copy link
Member

@spolti can you apply @ribeiromiranda's patch?

spolti added 5 commits May 8, 2024 11:28
fixes serverlessworkflow#194

Signed-off-by: Spolti <filippespolti@gmail.com>
Signed-off-by: Spolti <filippespolti@gmail.com>
Signed-off-by: Spolti <filippespolti@gmail.com>
Signed-off-by: Spolti <filippespolti@gmail.com>
Signed-off-by: Spolti <filippespolti@gmail.com>
@spolti
Copy link
Member Author

spolti commented May 8, 2024

Done.

Thanks @ribeiromiranda

@spolti
Copy link
Member Author

spolti commented May 8, 2024

Codecov is complaining about rate limit:
Rate limit reached. Please upload with the Codecov repository upload token to resolve issue.

@ricardozanini
Copy link
Member

@spolti I'll merge and solve this issue later.

@ricardozanini ricardozanini merged commit bb89ed0 into serverlessworkflow:main May 8, 2024
5 of 6 checks passed
@spolti spolti deleted the issue194 branch May 9, 2024 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DataInputSchema can only be a string and not an object
3 participants