From fb354894b0927809ebd8209e16c8728118142a85 Mon Sep 17 00:00:00 2001 From: Renaud Hartert Date: Wed, 14 Aug 2024 14:10:41 +0200 Subject: [PATCH 1/3] Cut dependency to openapi. --- bundle/schema/docs.go | 3 +- bundle/schema/openapi.go | 3 +- bundle/schema/openapi_test.go | 19 ++- bundle/schema/spec.go | 210 ++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 bundle/schema/spec.go diff --git a/bundle/schema/docs.go b/bundle/schema/docs.go index 5b960ea557..6e9289f924 100644 --- a/bundle/schema/docs.go +++ b/bundle/schema/docs.go @@ -9,7 +9,6 @@ import ( "github.com/databricks/cli/bundle/config" "github.com/databricks/cli/libs/jsonschema" - "github.com/databricks/databricks-sdk-go/openapi" ) // A subset of Schema struct @@ -63,7 +62,7 @@ func UpdateBundleDescriptions(openapiSpecPath string) (*Docs, error) { if err != nil { return nil, err } - spec := &openapi.Specification{} + spec := &Specification{} err = json.Unmarshal(openapiSpec, spec) if err != nil { return nil, err diff --git a/bundle/schema/openapi.go b/bundle/schema/openapi.go index 1756d51656..0d896b87ca 100644 --- a/bundle/schema/openapi.go +++ b/bundle/schema/openapi.go @@ -6,12 +6,11 @@ import ( "strings" "github.com/databricks/cli/libs/jsonschema" - "github.com/databricks/databricks-sdk-go/openapi" ) type OpenapiReader struct { // OpenAPI spec to read schemas from. - OpenapiSpec *openapi.Specification + OpenapiSpec *Specification // In-memory cache of schemas read from the OpenAPI spec. memo map[string]jsonschema.Schema diff --git a/bundle/schema/openapi_test.go b/bundle/schema/openapi_test.go index 359b1e58a9..4d393cf371 100644 --- a/bundle/schema/openapi_test.go +++ b/bundle/schema/openapi_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/databricks/cli/libs/jsonschema" - "github.com/databricks/databricks-sdk-go/openapi" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -45,7 +44,7 @@ func TestReadSchemaForObject(t *testing.T) { } } ` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -103,7 +102,7 @@ func TestReadSchemaForArray(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -149,7 +148,7 @@ func TestReadSchemaForMap(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -198,7 +197,7 @@ func TestRootReferenceIsResolved(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -248,7 +247,7 @@ func TestSelfReferenceLoopErrors(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -282,7 +281,7 @@ func TestCrossReferenceLoopErrors(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -327,7 +326,7 @@ func TestReferenceResolutionForMapInObject(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -397,7 +396,7 @@ func TestReferenceResolutionForArrayInObject(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), @@ -460,7 +459,7 @@ func TestReferenceResolutionDoesNotOverwriteDescriptions(t *testing.T) { } } }` - spec := &openapi.Specification{} + spec := &Specification{} reader := &OpenapiReader{ OpenapiSpec: spec, memo: make(map[string]jsonschema.Schema), diff --git a/bundle/schema/spec.go b/bundle/schema/spec.go new file mode 100644 index 0000000000..b32c5522b6 --- /dev/null +++ b/bundle/schema/spec.go @@ -0,0 +1,210 @@ +package schema + +import ( + "encoding/json" + "fmt" + "strings" +) + +type Node struct { + Description string `json:"description,omitempty"` + Preview string `json:"x-databricks-preview,omitempty"` + Ref string `json:"$ref,omitempty"` + + // Currently it is only defined for top level schemas + JsonPath string `json:"-"` +} + +type Specification struct { + Node + Paths map[string]Path `json:"paths"` + Components *Components `json:"components"` + Tags []Tag `json:"tags"` +} + +type PathStyle string + +const ( + // PathStyleRpc indicates that the endpoint is an RPC-style endpoint. + // The endpoint path is an action, and the entity to act on is specified + // in the request body. + PathStyleRpc PathStyle = "rpc" + + // PathStyleRest indicates that the endpoint is a REST-style endpoint. + // The endpoint path is a resource, and the operation to perform on the + // resource is specified in the HTTP method. + PathStyleRest PathStyle = "rest" +) + +func (r *PathStyle) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return fmt.Errorf("cannot unmarshal RequestStyle: %w", err) + } + switch s { + case "rpc", "rest": + *r = PathStyle(s) + default: + return fmt.Errorf("invalid RequestStyle: %s", s) + } + return nil +} + +type Tag struct { + Node + Package string `json:"x-databricks-package"` + PathStyle PathStyle `json:"x-databricks-path-style"` + Service string `json:"x-databricks-service"` + ParentService string `json:"x-databricks-parent-service"` + ControlPlaneService string `json:"x-databricks-controlplane"` + IsAccounts bool `json:"x-databricks-is-accounts"` + Name string `json:"name"` +} + +type Path struct { + Node + Parameters []Parameter `json:"parameters,omitempty"` + Get *Operation `json:"get,omitempty"` + Head *Operation `json:"head,omitempty"` + Post *Operation `json:"post,omitempty"` + Put *Operation `json:"put,omitempty"` + Patch *Operation `json:"patch,omitempty"` + Delete *Operation `json:"delete,omitempty"` +} + +type fieldPath []string + +func (fp fieldPath) String() string { + return strings.Join(fp, ".") +} + +// Operation is the equivalent of method +type Operation struct { + Node + Wait *Wait `json:"x-databricks-wait,omitempty"` + Pagination *Pagination `json:"x-databricks-pagination,omitempty"` + DataPlane *DataPlane `json:"x-databricks-dataplane,omitempty"` + Shortcut bool `json:"x-databricks-shortcut,omitempty"` + Crud string `json:"x-databricks-crud,omitempty"` + JsonOnly bool `json:"x-databricks-cli-json-only,omitempty"` + + // The x-databricks-path-style field indicates whether the operation has a + // RESTful path style or a RPC style. When specified, this overrides the + // service-level setting. Valid values are "rest" and "rpc". "rest" means + // that the operation has a RESTful path style, i.e. the path represents + // a resource and the HTTP method represents an action on the resource. + // "rpc" means that the operation has a RPC style, i.e. the path represents + // an action and the request body represents the resource. + PathStyle PathStyle `json:"x-databricks-path-style,omitempty"` + + // The x-databricks-request-type-name field defines the name to use for + // the request type in the generated client. This may be specified only + // if the operation does NOT have a request body, thus only uses a request + // type to encapsulate path and query parameters. + RequestTypeName string `json:"x-databricks-request-type-name,omitempty"` + + // For list APIs, the path to the field in the response entity that contains + // the resource ID. + IdField fieldPath `json:"x-databricks-id,omitempty"` + + // For list APIs, the path to the field in the response entity that contains + // the user-friendly name of the resource. + NameField fieldPath `json:"x-databricks-name,omitempty"` + + Summary string `json:"summary,omitempty"` + OperationId string `json:"operationId"` + Tags []string `json:"tags"` + Parameters []Parameter `json:"parameters,omitempty"` + Responses map[string]*Body `json:"responses"` + RequestBody *Body `json:"requestBody,omitempty"` +} + +type Components struct { + Node + Parameters map[string]*Parameter `json:"parameters,omitempty"` + Responses map[string]*Body `json:"responses,omitempty"` + Schemas map[string]*Schema `json:"schemas,omitempty"` +} + +type Schema struct { + Node + IsComputed bool `json:"x-databricks-computed,omitempty"` + IsAny bool `json:"x-databricks-any,omitempty"` + Type string `json:"type,omitempty"` + Enum []string `json:"enum,omitempty"` + AliasEnum []string `json:"x-databricks-alias-enum,omitempty"` + EnumDescriptions map[string]string `json:"x-databricks-enum-descriptions,omitempty"` + Default any `json:"default,omitempty"` + Example any `json:"example,omitempty"` + Format string `json:"format,omitempty"` + Required []string `json:"required,omitempty"` + Properties map[string]*Schema `json:"properties,omitempty"` + ArrayValue *Schema `json:"items,omitempty"` + MapValue *Schema `json:"additionalProperties,omitempty"` +} + +type Parameter struct { + Node + Required bool `json:"required,omitempty"` + In string `json:"in,omitempty"` + Name string `json:"name,omitempty"` + MultiSegment bool `json:"x-databricks-multi-segment,omitempty"` + Schema *Schema `json:"schema,omitempty"` +} + +type MediaType struct { + Node + Schema *Schema `json:"schema,omitempty"` +} + +type MimeType string + +const ( + MimeTypeJson MimeType = "application/json" + MimeTypeOctetStream MimeType = "application/octet-stream" + MimeTypeTextPlain MimeType = "text/plain" +) + +type Body struct { + Node + Required bool `json:"required,omitempty"` + Content map[string]MediaType `json:"content,omitempty"` + Headers map[string]*Parameter `json:"headers,omitempty"` +} + +// Pagination is the Databricks OpenAPI Extension for retrieving +// lists of entities through multiple API calls +type Pagination struct { + Offset string `json:"offset,omitempty"` + Limit string `json:"limit,omitempty"` + Results string `json:"results,omitempty"` + Increment int `json:"increment,omitempty"` + Inline bool `json:"inline,omitempty"` + Token *Binding `json:"token,omitempty"` +} + +// Wait is the Databricks OpenAPI Extension for long-running result polling +type Wait struct { + Poll string `json:"poll"` + Bind string `json:"bind"` + BindResponse string `json:"bindResponse,omitempty"` + Binding map[string]Binding `json:"binding,omitempty"` + Field []string `json:"field"` + Message []string `json:"message"` + Success []string `json:"success"` + Failure []string `json:"failure"` + Timeout int `json:"timeout,omitempty"` +} + +// Binding is a relationship between request and/or response +type Binding struct { + Request string `json:"request,omitempty"` + Response string `json:"response,omitempty"` +} + +// DataPlane is the Databricks OpenAPI Extension for direct access to DataPlane APIs +type DataPlane struct { + ConfigMethod string `json:"configMethod"` + Fields []string `json:"field"` +} From 87e4f0d6aa1f0f3b9ff388a9bc526b490b92796f Mon Sep 17 00:00:00 2001 From: Renaud Hartert Date: Wed, 14 Aug 2024 17:38:24 +0200 Subject: [PATCH 2/3] Remove unneeded structs --- bundle/schema/spec.go | 179 +++--------------------------------------- 1 file changed, 11 insertions(+), 168 deletions(-) diff --git a/bundle/schema/spec.go b/bundle/schema/spec.go index b32c5522b6..910dd5fc17 100644 --- a/bundle/schema/spec.go +++ b/bundle/schema/spec.go @@ -1,10 +1,6 @@ package schema -import ( - "encoding/json" - "fmt" - "strings" -) +import "github.com/databricks/cli/libs/jsonschema" type Node struct { Description string `json:"description,omitempty"` @@ -17,145 +13,28 @@ type Node struct { type Specification struct { Node - Paths map[string]Path `json:"paths"` - Components *Components `json:"components"` - Tags []Tag `json:"tags"` -} - -type PathStyle string - -const ( - // PathStyleRpc indicates that the endpoint is an RPC-style endpoint. - // The endpoint path is an action, and the entity to act on is specified - // in the request body. - PathStyleRpc PathStyle = "rpc" - - // PathStyleRest indicates that the endpoint is a REST-style endpoint. - // The endpoint path is a resource, and the operation to perform on the - // resource is specified in the HTTP method. - PathStyleRest PathStyle = "rest" -) - -func (r *PathStyle) UnmarshalJSON(data []byte) error { - var s string - err := json.Unmarshal(data, &s) - if err != nil { - return fmt.Errorf("cannot unmarshal RequestStyle: %w", err) - } - switch s { - case "rpc", "rest": - *r = PathStyle(s) - default: - return fmt.Errorf("invalid RequestStyle: %s", s) - } - return nil -} - -type Tag struct { - Node - Package string `json:"x-databricks-package"` - PathStyle PathStyle `json:"x-databricks-path-style"` - Service string `json:"x-databricks-service"` - ParentService string `json:"x-databricks-parent-service"` - ControlPlaneService string `json:"x-databricks-controlplane"` - IsAccounts bool `json:"x-databricks-is-accounts"` - Name string `json:"name"` -} - -type Path struct { - Node - Parameters []Parameter `json:"parameters,omitempty"` - Get *Operation `json:"get,omitempty"` - Head *Operation `json:"head,omitempty"` - Post *Operation `json:"post,omitempty"` - Put *Operation `json:"put,omitempty"` - Patch *Operation `json:"patch,omitempty"` - Delete *Operation `json:"delete,omitempty"` -} - -type fieldPath []string - -func (fp fieldPath) String() string { - return strings.Join(fp, ".") -} - -// Operation is the equivalent of method -type Operation struct { - Node - Wait *Wait `json:"x-databricks-wait,omitempty"` - Pagination *Pagination `json:"x-databricks-pagination,omitempty"` - DataPlane *DataPlane `json:"x-databricks-dataplane,omitempty"` - Shortcut bool `json:"x-databricks-shortcut,omitempty"` - Crud string `json:"x-databricks-crud,omitempty"` - JsonOnly bool `json:"x-databricks-cli-json-only,omitempty"` - - // The x-databricks-path-style field indicates whether the operation has a - // RESTful path style or a RPC style. When specified, this overrides the - // service-level setting. Valid values are "rest" and "rpc". "rest" means - // that the operation has a RESTful path style, i.e. the path represents - // a resource and the HTTP method represents an action on the resource. - // "rpc" means that the operation has a RPC style, i.e. the path represents - // an action and the request body represents the resource. - PathStyle PathStyle `json:"x-databricks-path-style,omitempty"` - - // The x-databricks-request-type-name field defines the name to use for - // the request type in the generated client. This may be specified only - // if the operation does NOT have a request body, thus only uses a request - // type to encapsulate path and query parameters. - RequestTypeName string `json:"x-databricks-request-type-name,omitempty"` - - // For list APIs, the path to the field in the response entity that contains - // the resource ID. - IdField fieldPath `json:"x-databricks-id,omitempty"` - - // For list APIs, the path to the field in the response entity that contains - // the user-friendly name of the resource. - NameField fieldPath `json:"x-databricks-name,omitempty"` - - Summary string `json:"summary,omitempty"` - OperationId string `json:"operationId"` - Tags []string `json:"tags"` - Parameters []Parameter `json:"parameters,omitempty"` - Responses map[string]*Body `json:"responses"` - RequestBody *Body `json:"requestBody,omitempty"` + Components *Components `json:"components"` } type Components struct { Node - Parameters map[string]*Parameter `json:"parameters,omitempty"` - Responses map[string]*Body `json:"responses,omitempty"` - Schemas map[string]*Schema `json:"schemas,omitempty"` -} - -type Schema struct { - Node - IsComputed bool `json:"x-databricks-computed,omitempty"` - IsAny bool `json:"x-databricks-any,omitempty"` - Type string `json:"type,omitempty"` - Enum []string `json:"enum,omitempty"` - AliasEnum []string `json:"x-databricks-alias-enum,omitempty"` - EnumDescriptions map[string]string `json:"x-databricks-enum-descriptions,omitempty"` - Default any `json:"default,omitempty"` - Example any `json:"example,omitempty"` - Format string `json:"format,omitempty"` - Required []string `json:"required,omitempty"` - Properties map[string]*Schema `json:"properties,omitempty"` - ArrayValue *Schema `json:"items,omitempty"` - MapValue *Schema `json:"additionalProperties,omitempty"` + Parameters map[string]*Parameter `json:"parameters,omitempty"` + Responses map[string]*Body `json:"responses,omitempty"` + Schemas map[string]*jsonschema.Schema `json:"schemas,omitempty"` } type Parameter struct { Node - Required bool `json:"required,omitempty"` - In string `json:"in,omitempty"` - Name string `json:"name,omitempty"` - MultiSegment bool `json:"x-databricks-multi-segment,omitempty"` - Schema *Schema `json:"schema,omitempty"` + Required bool `json:"required,omitempty"` + In string `json:"in,omitempty"` + Name string `json:"name,omitempty"` + MultiSegment bool `json:"x-databricks-multi-segment,omitempty"` + Schema *jsonschema.Schema `json:"schema,omitempty"` } type MediaType struct { Node - Schema *Schema `json:"schema,omitempty"` + Schema *jsonschema.Schema `json:"schema,omitempty"` } type MimeType string @@ -172,39 +51,3 @@ type Body struct { Content map[string]MediaType `json:"content,omitempty"` Headers map[string]*Parameter `json:"headers,omitempty"` } - -// Pagination is the Databricks OpenAPI Extension for retrieving -// lists of entities through multiple API calls -type Pagination struct { - Offset string `json:"offset,omitempty"` - Limit string `json:"limit,omitempty"` - Results string `json:"results,omitempty"` - Increment int `json:"increment,omitempty"` - Inline bool `json:"inline,omitempty"` - Token *Binding `json:"token,omitempty"` -} - -// Wait is the Databricks OpenAPI Extension for long-running result polling -type Wait struct { - Poll string `json:"poll"` - Bind string `json:"bind"` - BindResponse string `json:"bindResponse,omitempty"` - Binding map[string]Binding `json:"binding,omitempty"` - Field []string `json:"field"` - Message []string `json:"message"` - Success []string `json:"success"` - Failure []string `json:"failure"` - Timeout int `json:"timeout,omitempty"` -} - -// Binding is a relationship between request and/or response -type Binding struct { - Request string `json:"request,omitempty"` - Response string `json:"response,omitempty"` -} - -// DataPlane is the Databricks OpenAPI Extension for direct access to DataPlane APIs -type DataPlane struct { - ConfigMethod string `json:"configMethod"` - Fields []string `json:"field"` -} From 2f5ea5ebf0bc2be1a78e4fe5b950f5131292f8f0 Mon Sep 17 00:00:00 2001 From: Renaud Hartert Date: Wed, 14 Aug 2024 17:48:27 +0200 Subject: [PATCH 3/3] Remove even more unused code --- bundle/schema/spec.go | 44 +------------------------------------------ 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/bundle/schema/spec.go b/bundle/schema/spec.go index 910dd5fc17..fdc31a4ca5 100644 --- a/bundle/schema/spec.go +++ b/bundle/schema/spec.go @@ -2,52 +2,10 @@ package schema import "github.com/databricks/cli/libs/jsonschema" -type Node struct { - Description string `json:"description,omitempty"` - Preview string `json:"x-databricks-preview,omitempty"` - Ref string `json:"$ref,omitempty"` - - // Currently it is only defined for top level schemas - JsonPath string `json:"-"` -} - type Specification struct { - Node Components *Components `json:"components"` } type Components struct { - Node - Parameters map[string]*Parameter `json:"parameters,omitempty"` - Responses map[string]*Body `json:"responses,omitempty"` - Schemas map[string]*jsonschema.Schema `json:"schemas,omitempty"` -} - -type Parameter struct { - Node - Required bool `json:"required,omitempty"` - In string `json:"in,omitempty"` - Name string `json:"name,omitempty"` - MultiSegment bool `json:"x-databricks-multi-segment,omitempty"` - Schema *jsonschema.Schema `json:"schema,omitempty"` -} - -type MediaType struct { - Node - Schema *jsonschema.Schema `json:"schema,omitempty"` -} - -type MimeType string - -const ( - MimeTypeJson MimeType = "application/json" - MimeTypeOctetStream MimeType = "application/octet-stream" - MimeTypeTextPlain MimeType = "text/plain" -) - -type Body struct { - Node - Required bool `json:"required,omitempty"` - Content map[string]MediaType `json:"content,omitempty"` - Headers map[string]*Parameter `json:"headers,omitempty"` + Schemas map[string]*jsonschema.Schema `json:"schemas,omitempty"` }