Skip to content

Commit

Permalink
chore: reintroduce nonempty object validation (instill-ai#104)
Browse files Browse the repository at this point in the history
Because

- We want to avoid empty objects in our definitions if possible.
- New **Connection** section is empty for some connectors.

This commit

- **chore: reintroduce nonempty object validation**
- **fix: remove connection section if empty**

---------

Co-authored-by: Chang, Hui-Tang <[email protected]>
  • Loading branch information
jvallesm and donch1989 authored Apr 25, 2024
1 parent b7d7cd5 commit c848e47
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 45 deletions.
23 changes: 15 additions & 8 deletions pkg/base/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (c *BaseConnector) LoadConnectorDefinition(definitionJSONBytes []byte, task
if err != nil {
return err
}
renderedTasksJSON, nil := RenderJSON(tasksJSONBytes, additionalJSONBytes)
renderedTasksJSON, err := RenderJSON(tasksJSONBytes, additionalJSONBytes)
if err != nil {
return nil
}
Expand Down Expand Up @@ -130,6 +130,9 @@ func (c *BaseConnector) LoadConnectorDefinition(definitionJSONBytes []byte, task

c.definition.Name = fmt.Sprintf("connector-definitions/%s", c.definition.Id)
c.definition.Tasks = tasks
if c.definition.Spec == nil {
c.definition.Spec = &pipelinePB.ConnectorSpec{}
}
c.definition.Spec.ComponentSpecification, err = generateComponentSpec(c.definition.Title, tasks, taskStructs)
if err != nil {
return err
Expand All @@ -140,15 +143,19 @@ func (c *BaseConnector) LoadConnectorDefinition(definitionJSONBytes []byte, task
if err != nil {
return err
}
connection, err := c.refineResourceSpec(raw.Fields["spec"].GetStructValue().Fields["connection_specification"].GetStructValue())
if err != nil {
return err
// TODO: Avoid using structpb traversal here.
if _, ok := raw.Fields["spec"]; ok {
if v, ok := raw.Fields["spec"].GetStructValue().Fields["connection_specification"]; ok {
connection, err := c.refineResourceSpec(v.GetStructValue())
if err != nil {
return err
}
connectionPropStruct := &structpb.Struct{Fields: map[string]*structpb.Value{}}
connectionPropStruct.Fields["connection"] = structpb.NewStructValue(connection)
c.definition.Spec.ComponentSpecification.Fields["properties"] = structpb.NewStructValue(connectionPropStruct)
}
}

connectionPropStruct := &structpb.Struct{Fields: map[string]*structpb.Value{}}
connectionPropStruct.Fields["connection"] = structpb.NewStructValue(connection)
c.definition.Spec.ComponentSpecification.Fields["properties"] = structpb.NewStructValue(connectionPropStruct)

c.definition.Spec.DataSpecifications, err = generateDataSpecs(taskStructs)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/base/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (o *BaseOperator) LoadOperatorDefinition(definitionJSONBytes []byte, tasksJ
if err != nil {
return err
}
renderedTasksJSON, nil := RenderJSON(tasksJSONBytes, additionalJSONBytes)
renderedTasksJSON, err := RenderJSON(tasksJSONBytes, additionalJSONBytes)
if err != nil {
return nil
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/connector/instill/v0/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ It can carry out the following tasks:

The component configuration is defined and maintained [here](https://github.com/instill-ai/component/blob/main/pkg/connector/instill/v0/config/definition.json).

## Connection

## Supported Tasks

### Classification
Expand Down
9 changes: 0 additions & 9 deletions pkg/connector/instill/v0/config/definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@
"icon_url": "",
"id": "instill-model",
"public": true,
"spec": {
"connection_specification": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": true,
"properties": {},
"title": "Instill Model Connector",
"type": "object"
}
},
"title": "Instill Model",
"description": "Connect the AI models served on the Instill Model Platform",
"tombstone": false,
Expand Down
2 changes: 0 additions & 2 deletions pkg/connector/website/v0/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ It can carry out the following tasks:

The component configuration is defined and maintained [here](https://github.com/instill-ai/component/blob/main/pkg/connector/website/v0/config/definition.json).

## Connection

## Supported Tasks

### Scrape Website
Expand Down
10 changes: 0 additions & 10 deletions pkg/connector/website/v0/config/definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@
"icon_url": "",
"id": "website",
"public": true,
"spec": {
"connection_specification": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": true,
"properties": {},
"required": [],
"title": "Website Connector Resource",
"type": "object"
}
},
"title": "Website",
"description": "Scrape websites",
"type": "CONNECTOR_TYPE_DATA",
Expand Down
12 changes: 12 additions & 0 deletions tools/compogen/pkg/gen/definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ func TestDefinition_Validate(t *testing.T) {
},
wantErr: "SourceURL field must be a valid URL",
},
{
// This validates the omitnil tag and the nested validation.
// Resource specification validation details are covered in a
// separate test.
name: "nok - resource specification must be valid if present",
modifier: func(d *definition) {
d.Spec = spec{
ConnectionSpecification: &objectSchema{},
}
},
wantErr: "Properties field doesn't reach the minimum value / number of elements",
},
{
name: "nok - multiple errors",
modifier: func(d *definition) {
Expand Down
14 changes: 7 additions & 7 deletions tools/compogen/pkg/gen/resources/templates/readme.mdx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ It can carry out the following tasks:
## Configuration

The component configuration is defined and maintained [here]({{ .SourceURL }}/config/definition.json).
{{ if .ComponentType.HasConnectionConfig}}
{{ if and .ComponentType.HasConnectionConfig ( or .ConnectionConfig.Prerequisites .ConnectionConfig.Properties ) }}
## Connection
{{ if .ConnectionConfig.Prerequisites}}
<InfoBlock type="info" title="Prerequisites">{{ .ConnectionConfig.Prerequisites }}</InfoBlock>
{{ end }}{{ if .ConnectionConfig.Properties }}
{{ with .ConnectionConfig.Prerequisites}}
<InfoBlock type="info" title="Prerequisites">{{ . }}</InfoBlock>
{{ end }}{{ with .ConnectionConfig.Properties }}
| Field | Field ID | Type | Note |
| :--- | :--- | :--- | :--- |{{ range .ConnectionConfig.Properties }}
| :--- | :--- | :--- | :--- |{{ range . }}
| {{ .Title }}{{ if .Required }} (required){{ end }} | `{{ .ID }}` | {{ .Type }} | {{ .Description }} |{{ end }}
{{ end }}{{ end }}
## Supported Tasks{{ range $i, $task := .Tasks}}

### {{ $task.Title }}
{{ if $task.Description }}
{{ $task.Description }}
{{ with $task.Description }}
{{ . }}
{{ end }}{{ if $task.Input }}
| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
Expand Down
8 changes: 2 additions & 6 deletions tools/compogen/pkg/gen/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ type property struct {
}

type objectSchema struct {
Required []string `json:"required"`

// TODO we could validate gt=0 here to avoid empty objects. At this moment
// there's a connector (Instill Model) that requires this, but if we
// overcome that limitation nonempty objects should be enforced.
Properties map[string]property `json:"properties" validate:"dive"`
Properties map[string]property `json:"properties" validate:"gt=0,dive"`
Required []string `json:"required"`
}
7 changes: 7 additions & 0 deletions tools/compogen/pkg/gen/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ func TestObjectSchema_Validate(t *testing.T) {
modifier func(*objectSchema)
wantErr string
}{
{
name: "nok - no properties",
modifier: func(rs *objectSchema) {
rs.Properties = map[string]property{}
},
wantErr: "Properties field doesn't reach the minimum value / number of elements",
},
{
name: "nok - no title",
modifier: func(rs *objectSchema) {
Expand Down

0 comments on commit c848e47

Please sign in to comment.