Merge branch 'master' into feature/pubsub-batching

This commit is contained in:
Mukundan Sundararajan 2022-09-28 09:14:03 +05:30 committed by GitHub
commit eab68d1a7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1434 additions and 8 deletions

3
.build-tools/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Compiled files
components-contrib-build-tools
components-contrib-build-tools.exe

18
.build-tools/README.md Normal file
View File

@ -0,0 +1,18 @@
# dapr/components-contrib build-tools CLI
This folder contains a CLI that implements a number of build tools used by dapr/components-contrib.
The CLI is written in Go and based on the [cobra](https://github.com/spf13/cobra) framework. In order to use it, Go (1.18+) must be installed on your system.
## Running the CLI
You have two ways to run the CLI:
1. Within the `build-tools` directly, you can run the CLI with `go run .` directly. For example `go run . help` shows the help page.
2. You can build a pre-compiled binary by running `make compile-build-tools` in the root folder of this repository. This will build an executable called `build-tools` (or `build-tools.exe` on Windows) in the `build-tools` folder. You can then run the command directly, for example `./build-tools help`
## Available commands
The list of available commands in this CLI is dynamic and is subject to change at any time. Each command, including the "root" one (no sub-command), are self-documented in the CLI, and you can read the help page by adding `--help`.
For example, `./build-tools --help` shows the full list of commands the CLI offers.

View File

@ -0,0 +1,83 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"encoding/json"
"fmt"
"os"
"time"
"github.com/spf13/cobra"
"github.com/dapr/components-contrib/build-tools/pkg/componentmetadata"
"github.com/dapr/components-contrib/build-tools/pkg/metadataschema"
)
// bundleComponentMetadataCmd represents the bundle-component-metadata command
var bundleComponentMetadataCmd = &cobra.Command{
Use: "bundle-component-metadata",
Short: "Generates the component metadata bundle",
Long: `Generates the component metadata bundle as a JSON files, and outputs it to stdout.`,
Run: func(cmd *cobra.Command, args []string) {
// Navigate to the root of the repo
err := cwdToRepoRoot()
if err != nil {
panic(err)
}
// Create a parser that also loads the JSON schema
parser, err := componentmetadata.NewParserWithSchemaFile("component-metadata-schema.json")
if err != nil {
panic(err)
}
// Find all components
list, err := componentmetadata.FindComponents(ComponentFolders, ExcludeFolders)
if err != nil {
panic(err)
}
// Load the metadata for all components
bundle := metadataschema.Bundle{
SchemaVersion: "v1",
Date: time.Now().Format("20060102150405"),
Components: make([]*metadataschema.ComponentMetadata, 0, len(list)),
}
for _, component := range list {
componentMetadata, err := parser.LoadForComponent(component)
if err != nil {
panic(fmt.Errorf("Failed to load metadata for component %s: %w", component, err))
}
if componentMetadata == nil {
fmt.Fprintln(os.Stderr, "Info: metadata file not found in component "+component)
continue
}
bundle.Components = append(bundle.Components, componentMetadata)
}
// Write to stdout
enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
err = enc.Encode(bundle)
if err != nil {
panic(fmt.Errorf("Failed to encode bundle to JSON: %w", err))
}
},
}
func init() {
rootCmd.AddCommand(bundleComponentMetadataCmd)
}

View File

@ -0,0 +1,51 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"encoding/json"
"os"
"github.com/invopop/jsonschema"
"github.com/spf13/cobra"
"github.com/dapr/components-contrib/build-tools/pkg/metadataschema"
)
// genComponentSchemaCmd represents the genComponentSchema command
var genComponentSchemaCmd = &cobra.Command{
Use: "gen-component-schema",
Short: "Generates the schema for the metadata.yaml / metadata.json files",
Long: `Generates the schema for the metadata.yaml / metadata.json files by parsing the model in pkg/schema.
The result is written to stdout.`,
Run: func(cmd *cobra.Command, args []string) {
// Generate the schema from the struct
reflector := &jsonschema.Reflector{}
reflector.ExpandedStruct = true
err := reflector.AddGoComments("github.com/dapr/components-contrib/build-tools", "./pkg/metadataschema")
if err != nil {
panic(err)
}
res := reflector.Reflect(&metadataschema.ComponentMetadata{})
res.Title = "ComponentMetadata"
// Print resut to stdout
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(res)
},
}
func init() {
rootCmd.AddCommand(genComponentSchemaCmd)
}

35
.build-tools/cmd/root.go Normal file
View File

@ -0,0 +1,35 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"os"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "components-contrib-build-tools",
Short: "Build tools for dapr/components-contrib",
Long: `A collection of commands and tools used to build dapr/components-contrib`,
}
// Execute adds all child commands to the root command and sets flags appropriately.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

44
.build-tools/cmd/utils.go Normal file
View File

@ -0,0 +1,44 @@
package cmd
import (
"errors"
"os"
"path/filepath"
)
// Globals
var (
// List of folders containing components
ComponentFolders []string
// Paths within ComponentFolders to ignore
ExcludeFolders []string
)
// Navigate to the root of the repo
func cwdToRepoRoot() error {
cwd, err := os.Getwd()
if err != nil {
return err
}
cwd, err = filepath.Abs(cwd)
if err != nil {
return err
}
for {
stat, err := os.Stat(filepath.Join(cwd, ".git"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
if err == nil && stat != nil && stat.IsDir() {
return os.Chdir(cwd)
}
// Go one level up
cwd = filepath.Dir(cwd)
if cwd == "" || cwd == "." || cwd == string(filepath.Separator) {
return errors.New("could not find the repository's root")
}
}
}

View File

@ -0,0 +1,41 @@
{
"componentFolders": [
"bindings",
"configuration",
"lock",
"middleware/http",
"nameresolution",
"pubsub",
"secretstores",
"state"
],
"excludeFolders": [
"bindings/alicloud",
"bindings/aws",
"bindings/azure",
"bindings/gcp",
"bindings/huawei",
"bindings/rethinkdb",
"bindings/twilio",
"bindings/zeebe",
"configuration/azure",
"configuration/redis/internal",
"pubsub/aws",
"pubsub/azure",
"pubsub/gcp",
"secretstores/alicloud",
"secretstores/aws",
"secretstores/azure",
"secretstores/gcp",
"secretstores/hashicorp",
"secretstores/huaweicloud",
"secretstores/local",
"state/alicloud",
"state/aws",
"state/azure",
"state/gcp",
"state/hashicorp",
"state/oci",
"state/utils"
]
}

20
.build-tools/go.mod Normal file
View File

@ -0,0 +1,20 @@
module github.com/dapr/components-contrib/build-tools
go 1.19
require (
github.com/invopop/jsonschema v0.6.0
github.com/spf13/cobra v1.5.0
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

39
.build-tools/go.sum Normal file
View File

@ -0,0 +1,39 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/invopop/jsonschema v0.6.0 h1:8e+xY8ZEn8gDHUYylSlLHy22P+SLeIRIHv3nM3hCbmY=
github.com/invopop/jsonschema v0.6.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5 h1:ImnGIsrcG8vwbovhYvvSY8fagVV6QhCWSWXfzwGDLVs=
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

42
.build-tools/main.go Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
_ "embed"
"encoding/json"
"github.com/dapr/components-contrib/build-tools/cmd"
)
//go:embed component-folders.json
var componentFoldersJSON []byte
func init() {
parsed := struct {
ComponentFolders []string `json:"componentFolders"`
ExcludeFolders []string `json:"excludeFolders"`
}{}
err := json.Unmarshal(componentFoldersJSON, &parsed)
if err != nil {
panic(err)
}
cmd.ComponentFolders = parsed.ComponentFolders
cmd.ExcludeFolders = parsed.ExcludeFolders
}
func main() {
cmd.Execute()
}

View File

@ -0,0 +1,68 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package componentmetadata
import (
"fmt"
"os"
"path/filepath"
)
// FindComponents finds all component folders and returns their paths.
func FindComponents(folders []string, skip []string) ([]string, error) {
skipMap := map[string]struct{}{}
for _, v := range skip {
// Normalize all slashes
v = filepath.Clean(v)
skipMap[v] = struct{}{}
}
res := []string{}
for _, folder := range folders {
folder = filepath.Clean(folder)
err := findInDirectory(folder, skipMap, &res)
if err != nil {
return nil, err
}
}
return res, nil
}
func findInDirectory(dir string, skip map[string]struct{}, res *[]string) error {
read, err := os.ReadDir(dir)
if err != nil {
return err
}
for _, e := range read {
// Ignore anything but directories
if !e.IsDir() {
continue
}
path := filepath.Join(dir, e.Name())
// Add the directory if not skipped
if _, ok := skip[path]; !ok {
*res = append(*res, path)
} else {
fmt.Fprintln(os.Stderr, "Info: skipped folder "+path)
}
// Read the directory recursively
findInDirectory(path, skip, res)
}
return nil
}

View File

@ -0,0 +1,121 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package componentmetadata
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"github.com/dapr/components-contrib/build-tools/pkg/metadataschema"
"github.com/xeipuuv/gojsonschema"
"sigs.k8s.io/yaml"
)
// Parser used to parse and validate component metadata YAML or JSON files.
type Parser struct {
validator *gojsonschema.Schema
}
// NewParserWithSchema creates a new Parser object with the schema read from the file.
func NewParserWithSchemaFile(file string) (*Parser, error) {
read, err := os.ReadFile("component-metadata-schema.json")
if err != nil {
return nil, fmt.Errorf("failed to read component-metadata-schema.json: %w", err)
}
return NewParserWithSchema(read)
}
// NewParserWithSchema creates a new Parser object with the schema passed as JSON-encoded data.
func NewParserWithSchema(schema []byte) (*Parser, error) {
schemaLoader := gojsonschema.NewBytesLoader(schema)
validator, err := gojsonschema.NewSchema(schemaLoader)
if err != nil {
return nil, fmt.Errorf("failed to create schema validator: %w", err)
}
return &Parser{
validator: validator,
}, nil
}
// LoadForComponent loads the metadata.yaml / metadata.json for the component, parses it, and validates it.
func (p *Parser) LoadForComponent(componentPath string) (*metadataschema.ComponentMetadata, error) {
var (
read []byte
err error
)
// Try with YAML first
read, err = os.ReadFile(filepath.Join(componentPath, "metadata.yaml"))
if errors.Is(err, os.ErrNotExist) {
// IT'S YAML NOT YML
// (Insert GIF of "It's leviOsa, not levioSA!")
read, err = os.ReadFile(filepath.Join(componentPath, "metadata.yml"))
if errors.Is(err, os.ErrNotExist) {
// JSON anyone?
read, err = os.ReadFile(filepath.Join(componentPath, "metadata.json"))
}
}
if errors.Is(err, os.ErrNotExist) {
return nil, nil
} else if err != nil {
panic(err)
}
// Parse the YAML (and also JSON)
componentMetadata, err := p.Parse(read)
if err != nil {
return nil, fmt.Errorf("Failed to parse metadata file for component %s: %w", componentPath, err)
}
return componentMetadata, nil
}
// Parse a YAML (or JSON) file, already read, and returns the ComponentMetadata object.
// Automatically validates the metadata against the schema
func (p *Parser) Parse(read []byte) (*metadataschema.ComponentMetadata, error) {
componentMetadata := &metadataschema.ComponentMetadata{}
// Converts to JSON if it's YAML
// Since JSON is a subset of YAML, this accepts JSON files too
readJSON, err := yaml.YAMLToJSONStrict(read)
if err != nil {
return nil, fmt.Errorf("failed to parse metadata file: %w", err)
}
err = json.Unmarshal(readJSON, componentMetadata)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal metadata: %w", err)
}
// Validate against the schema
res, err := p.validator.Validate(gojsonschema.NewGoLoader(componentMetadata))
if err != nil {
return nil, fmt.Errorf("metadata failed validation: %w", err)
}
if !res.Valid() {
return nil, fmt.Errorf("metadata is not valid: %v", res.Errors())
}
// Perform extra validation
err = componentMetadata.IsValid()
if err != nil {
return nil, err
}
return componentMetadata, nil
}

View File

@ -0,0 +1,24 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metadataschema
// Bundle is the type for the component metadata bundle.
type Bundle struct {
// Version of the component bundle schema.
SchemaVersion string `json:"schemaVersion" jsonschema:"enum=v1"`
// Date the bundle was generated, in format `20060102150405`
Date string `json:"date"`
// Component list.
Components []*ComponentMetadata `json:"components"`
}

View File

@ -0,0 +1,116 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package metadataschema contains the data structures for the schema of metadata.yaml / metadata.json files.
// Schemas are built using github.com/invopop/jsonschema .
package metadataschema
// ComponentMetadata is the schema for the metadata.yaml / metadata.json files.
type ComponentMetadata struct {
// Version of the component metadata schema.
SchemaVersion string `json:"schemaVersion" jsonschema:"enum=v1"`
// Component type, of one of the allowed values.
Type string `json:"type" jsonschema:"enum=bindings,enum=state,enum=secretstores,enum=pubsub,enum=configuration,enum=lock,enum=middleware"`
// Name of the component (without the inital type, e.g. "http" instead of "bindings.http").
Name string `json:"name"`
// Version of the component, with the leading "v", e.g. "v1".
Version string `json:"version"`
// Component status.
Status string `json:"status" jsonschema:"enum=stable,enum=beta,enum=alpha,enum=development-only"`
// Title of the component, e.g. "HTTP".
Title string `json:"title"`
// Additional description for the component, optional.
Description string `json:"description,omitempty"`
// URLs with additional resources for the component, such as docs.
URLs []URL `json:"urls"`
// Properties for bindings only.
// This should not present unless "type" is "bindings".
Binding *Binding `json:"binding,omitempty"`
// Component capabilities.
// For state stores, the presence of "actorStateStore" implies that the metadata property "actorStateStore" can be set. In that case, do not manually specify "actorStateStore" as metadata option.
Capabilities []string `json:"capabilities,omitempty"`
// Authentication profiles for the component.
AuthenticationProfiles []AuthenticationProfile `json:"authenticationProfiles,omitempty"`
// Metadata options for the component.
Metadata []Metadata `json:"metadata,omitempty"`
}
// URL represents one URL with additional resources.
type URL struct {
// Title of the URL.
Title string `json:"title"`
// URL.
URL string `json:"url"`
}
// Binding represents properties that are specific to bindings
type Binding struct {
// If "true", the binding can be used as input binding.
Input bool `json:"input,omitempty"`
// If "true", the binding can be used as output binding.
Output bool `json:"output,omitempty"`
// List of operations that the output binding support.
// Required in output bindings, and not allowed in input-only bindings.
Operations []BindingOperation `json:"operations"`
}
// BindingOperation represents an operation offered by an output binding.
type BindingOperation struct {
// Name of the operation, such as "create", "post", "delete", etc.
Name string `json:"name"`
// Descrption of the operation.
Description string `json:"description"`
}
// Metadata property.
type Metadata struct {
// Name of the metadata property.
Name string `json:"name"`
// Description of the property.
Description string `json:"description"`
// If "true", the property is required
Required bool `json:"required,omitempty"`
// If "true", the property represents a sensitive value such as a password.
Sensitive bool `json:"sensitive,omitempty"`
// Type of the property.
// If this is empty, it's interpreted as "string".
Type string `json:"type,omitempty" jsonschema:"enum=string,enum=number,enum=bool,enum=duration"`
// Default value for the property.
// If it's a string, don't forget to add quotes.
Default string `json:"default,omitempty"`
// Example value.
Example string `json:"example"`
// If set, forces the value to be one of those specified in this allowlist.
AllowedValues []string `json:"allowedValues,omitempty"`
// If set, specifies that the property is only applicable to bindings of the type specified below.
// At least one of "input" and "output" must be "true".
Binding *MetadataBinding `json:"binding,omitempty"`
}
// MetadataBinding is the type for the "binding" property in the "metadata" object.
type MetadataBinding struct {
// If "true", the property can be used with the binding as input binding only.
Input bool `json:"input,omitempty"`
// If "true", the property can be used with the binding as output binding only.
Output bool `json:"output,omitempty"`
}
// AuthenticationProfile is the type for an authentication profile.
type AuthenticationProfile struct {
// Title of the authentication profile.
Title string `json:"title"`
// Additional description for the authentication profile, optional.
Description string `json:"description"`
// Metadata options applicable when using this authentication profile.
Metadata []Metadata `json:"metadata,omitempty"`
}

View File

@ -0,0 +1,49 @@
/*
Copyright 2022 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metadataschema
import (
"errors"
"strings"
)
// IsValid performs additional validation and returns true if the object is valid.
func (c ComponentMetadata) IsValid() error {
// Sanity check for bindings
if c.Type == "" {
return errors.New("type is empty")
}
if c.Type == "bindings" && c.Binding == nil {
return errors.New("property binding is required for components of type 'bindings'")
}
if c.Type != "bindings" && c.Binding != nil {
return errors.New("property binding is not allowed in components that are not of type 'bindings'")
}
// Ensure that there's a URL called Reference to the Dapr docs
if len(c.URLs) < 1 {
return errors.New("property urls must contain at least one URL to the Dapr docs with title 'Reference'")
}
hasReferenceUrl := false
for _, u := range c.URLs {
if u.Title == "Reference" && strings.HasPrefix(u.URL, "https://docs.dapr.io/reference/components-reference/") {
hasReferenceUrl = true
}
}
if !hasReferenceUrl {
return errors.New("property urls must a link to the Dapr docs with title 'Reference' and URL starting with 'https://docs.dapr.io/reference/components-reference/'")
}
return nil
}

View File

@ -91,6 +91,9 @@ jobs:
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ env.GOVER }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ env.GOVER }}-
- name: Check components-schema
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && steps.skip_check.outputs.should_skip != 'true'
run: make check-component-metadata-schema-diff
- name: Run golangci-lint
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && steps.skip_check.outputs.should_skip != 'true'
uses: golangci/golangci-lint-action@v3.2.0
@ -100,7 +103,7 @@ jobs:
args: --timeout 15m
- name: Run go mod tidy check diff
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && steps.skip_check.outputs.should_skip != 'true'
run: make modtidy-all check-diff
run: make modtidy-all check-mod-diff
# - name: Run Go Vulnerability Check
# if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && steps.skip_check.outputs.should_skip != 'true'
# run: |

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ vendor
go.work
go.work.sum
.DS_Store
component-metadata-bundle.json

View File

@ -67,6 +67,17 @@ else
INSTALLED_LINT_VERSION=v$(shell $(LINTER_BINARY) version | grep -Eo '([0-9]+\.)+[0-9]+' - || "")
endif
# Build tools
ifeq ($(TARGET_OS_LOCAL),windows)
BUILD_TOOLS_BIN ?= components-contrib-build-tools.exe
BUILD_TOOLS ?= ./.build-tools/$(BUILD_TOOLS_BIN)
RUN_BUILD_TOOLS ?= cd .build-tools; go.exe run .
else
BUILD_TOOLS_BIN ?= components-contrib-build-tools
BUILD_TOOLS ?= ./.build-tools/$(BUILD_TOOLS_BIN)
RUN_BUILD_TOOLS ?= cd .build-tools; go run .
endif
################################################################################
# Linter targets #
################################################################################
@ -139,13 +150,40 @@ modtidy:
go mod tidy
################################################################################
# Target: check-diff #
# Target: check-mod-diff #
################################################################################
.PHONY: check-diff
check-diff:
.PHONY: check-mod-diff
check-mod-diff:
git diff --exit-code -- '*go.mod' # check no changes
git diff --exit-code -- '*go.sum' # check no changes
################################################################################
# Target: compile-build-tools #
################################################################################
.PHONY: compile-build-tools
compile-build-tools:
ifeq (,$(wildcard $(BUILD_TOOLS)))
cd .build-tools; CGO_ENABLED=$(CGO) GOOS=$(TARGET_OS_LOCAL) GOARCH=$(TARGET_ARCH_LOCAL) go build -o $(BUILD_TOOLS_BIN) .
endif
################################################################################
# Components schema targets #
################################################################################
.PHONY: component-metadata-schema
component-metadata-schema:
$(RUN_BUILD_TOOLS) gen-component-schema > ../component-metadata-schema.json
.PHONY: check-component-metadata-schema-diff
check-component-metadata-schema-diff: component-metadata-schema
git diff --exit-code -- component-metadata-schema.json # check no changes
################################################################################
# Component metadata bundle targets #
################################################################################
.PHONY: bundle-component-metadata
bundle-component-metadata:
$(RUN_BUILD_TOOLS) bundle-component-metadata > ../component-metadata-bundle.json
################################################################################
# Target: conf-tests #
################################################################################
@ -154,8 +192,6 @@ conf-tests:
CGO_ENABLED=$(CGO) go test -v -tags=conftests -count=1 ./tests/conformance
################################################################################
# Target: e2e-tests-zeebe #
# Target: e2e #
################################################################################
.PHONY: e2e-tests-zeebe
e2e-tests-zeebe:
CGO_ENABLED=$(CGO) go test -v -tags=e2etests -count=1 ./tests/e2e/bindings/zeebe/...
include tests/e2e/e2e_tests.mk

View File

@ -0,0 +1,169 @@
# yaml-language-server: $schema=../../../component-metadata-schema.json
schemaVersion: v1
type: bindings
name: azure.servicebusqueues
version: v1
status: stable
title: "Azure Service Bus Queues"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-bindings/servicebusqueues/
binding:
output: true
input: true
operations:
- name: create
description: "Publish a new message in the queue."
capabilities: []
authenticationProfiles:
- title: "Connection string"
description: "Authenticate using a connection string."
metadata:
- name: connectionString
required: true
sensitive: true
description: "The Service Bus connection string."
example: '"Endpoint=sb://************"'
# If omitted, uses the same values as "<root>.binding"
binding:
output: true
input: true
- title: "Azure AD: Managed identity"
description: "Authenticate using Azure AD and a managed identity."
metadata:
- name: namespaceName
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
example: '"namespace.servicebus.windows.net"'
required: true
binding:
output: true
input: true
- name: azureClientId
required: false
description: "Client ID (application ID). Required if the service has multiple identities assigned."
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- title: "Azure AD: Client credentials"
description: "Authenticate using Azure AD with client credentials, also known as \"service principals\"."
metadata:
- name: namespaceName
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
example: '"namespace.servicebus.windows.net"'
required: true
binding:
output: true
input: true
- name: azureTenantId
required: true
description: "ID of the Azure AD tenant"
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
- name: azureClientId
required: true
description: "Client ID (application ID)"
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- name: azureClientSecret
sensitive: true
required: true
description: "Client secret (application password)"
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
- title: "Azure AD: Client certificate"
description: "Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of azureCertificate and azureCertificateFile is required."
metadata:
- name: namespaceName
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
example: '"namespace.servicebus.windows.net"'
required: true
binding:
output: true
input: true
- name: azureTenantId
required: true
description: "ID of the Azure AD tenant."
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
- name: azureClientId
required: true
description: "Client ID (application ID)."
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- name: azureCertificate
sensitive: true
required: false
description: "Certificate and private key (in PFX/PKCS#12 format)."
example: |
"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----"
- name: azureCertificateFile
sensitive: true
required: false
description: "Path to PFX/PKCS#12 file on disk, containing the certificate and private key."
example: "/path/to/file.pem"
- name: azureCertificatePassword
sensitive: true
required: false
description: "Password for the certificate if encrypted."
example: "password"
metadata:
- name: queueName
required: true
description: "The Service Bus queue name. Queue names are case-insensitive and will always be forced to lowercase."
# string is the default type if omitted
type: string
example: '"queuename"'
binding:
output: true
input: true
- name: ttlInSeconds
description: "Parameter to set the default message time to live. If this parameter is omitted, messages will expire after 14 days (the built-in default value in Azure Sevice Bus)."
type: number
example: '86400'
binding:
# input is omitted so it's assumed as false
output: true
- name: maxRetriableErrorsPerSec
description: "Maximum number of retriable errors that are processed per second. If a message fails to be processed with a retriable error, the component adds a delay before it starts processing another message, to avoid immediately re-processing messages that have failed"
type: number
default: '10'
example: '2'
binding:
# output is omitted so it's assumed as false
input: true
- name: minConnectionRecoveryInSec
description: "Minimum interval (in seconds) to wait before attempting to reconnect to Azure Service Bus in case of a connection failure."
type: number
default: '2'
example: '5'
binding:
# output is omitted so it's assumed as false
input: true
- name: maxConnectionRecoveryInSec
description: "Maximum interval (in seconds) to wait before attempting to reconnect to Azure Service Bus in case of a connection failure. After each attempt, the binding waits a random number of seconds, increasing every time, between the minimum and the maximum. Default is 300 seconds (5 minutes)."
type: number
default: '300'
example: '600'
binding:
# output is omitted so it's assumed as false
input: true
- name: maxActiveMessages
description: "Defines the maximum number of messages to be processing or in the buffer at once. This should be at least as big as the \"maxConcurrentHandlers\"."
type: number
default: '1'
example: '8'
binding:
input: true
- name: maxConcurrentHandlers
description: "Defines the maximum number of concurrent message handlers."
type: number
default: '1'
example: '5'
binding:
input: true
- name: lockRenewalInSec
description: "Defines the frequency at which buffered message locks will be renewed."
type: number
default: '20'
example: '10'
binding:
input: true
- name: timeoutInSec
description: "Timeout for all invocations to the Azure Service Bus endpoint, in seconds. Note that this option impacts network calls and it's unrelated to the TTL applies to messages."
type: number
default: '60'
example: '30'
# binding is not specified so it's the same as <root>.binding

View File

@ -0,0 +1,41 @@
# yaml-language-server: $schema=../../component-metadata-schema.json
schemaVersion: v1
type: bindings
name: http
version: v1
status: stable
title: "HTTP"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-bindings/http/
binding:
output: true
input: false
operations:
- name: create
description: "Alias for \"post\", for backwards-compatibility."
- name: get
description: "Read data/records."
- name: head
description: "Identical to get except that the server does not return a response body."
- name: post
description: "Typically used to create records or send commands."
- name: put
description: "Update data/records."
- name: patch
description: "Sometimes used to update a subset of fields of a record."
- name: delete
description: "Delete a data/record."
- name: options
description: "Requests for information about the communication options available (not commonly used)."
- name: trace
description: "Used to invoke a remote, application-layer loop-back of the request message (not commonly used)."
capabilities: []
metadata:
- name: url
required: true
description: "The base URL of the HTTP endpoint to invoke"
example: '"http://host:port/path", "http://myservice:8000/customer"'
# If omitted, uses the same values as "<root>.binding"
binding:
output: true

View File

@ -0,0 +1,260 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/dapr/components-contrib/build-tools/pkg/metadataschema/component-metadata",
"$defs": {
"AuthenticationProfile": {
"properties": {
"title": {
"type": "string",
"description": "Title of the authentication profile."
},
"description": {
"type": "string",
"description": "Additional description for the authentication profile, optional."
},
"metadata": {
"items": {
"$ref": "#/$defs/Metadata"
},
"type": "array",
"description": "Metadata options applicable when using this authentication profile."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"title",
"description"
],
"description": "AuthenticationProfile is the type for an authentication profile."
},
"Binding": {
"properties": {
"input": {
"type": "boolean",
"description": "If \"true\", the binding can be used as input binding."
},
"output": {
"type": "boolean",
"description": "If \"true\", the binding can be used as output binding."
},
"operations": {
"items": {
"$ref": "#/$defs/BindingOperation"
},
"type": "array",
"description": "List of operations that the output binding support.\nRequired in output bindings, and not allowed in input-only bindings."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"operations"
],
"description": "Binding represents properties that are specific to bindings"
},
"BindingOperation": {
"properties": {
"name": {
"type": "string",
"description": "Name of the operation, such as \"create\", \"post\", \"delete\", etc."
},
"description": {
"type": "string",
"description": "Descrption of the operation."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"description"
],
"description": "BindingOperation represents an operation offered by an output binding."
},
"Metadata": {
"properties": {
"name": {
"type": "string",
"description": "Name of the metadata property."
},
"description": {
"type": "string",
"description": "Description of the property."
},
"required": {
"type": "boolean",
"description": "If \"true\", the property is required"
},
"sensitive": {
"type": "boolean",
"description": "If \"true\", the property represents a sensitive value such as a password."
},
"type": {
"type": "string",
"enum": [
"string",
"number",
"bool",
"duration"
],
"description": "Type of the property.\nIf this is empty, it's interpreted as \"string\"."
},
"default": {
"type": "string",
"description": "Default value for the property.\nIf it's a string, don't forget to add quotes."
},
"example": {
"type": "string",
"description": "Example value."
},
"allowedValues": {
"items": {
"type": "string"
},
"type": "array",
"description": "If set, forces the value to be one of those specified in this allowlist."
},
"binding": {
"$ref": "#/$defs/MetadataBinding",
"description": "If set, specifies that the property is only applicable to bindings of the type specified below.\nAt least one of \"input\" and \"output\" must be \"true\"."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"description",
"example"
],
"description": "Metadata property."
},
"MetadataBinding": {
"properties": {
"input": {
"type": "boolean",
"description": "If \"true\", the property can be used with the binding as input binding only."
},
"output": {
"type": "boolean",
"description": "If \"true\", the property can be used with the binding as output binding only."
}
},
"additionalProperties": false,
"type": "object",
"description": "MetadataBinding is the type for the \"binding\" property in the \"metadata\" object."
},
"URL": {
"properties": {
"title": {
"type": "string",
"description": "Title of the URL."
},
"url": {
"type": "string",
"description": "URL."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"title",
"url"
],
"description": "URL represents one URL with additional resources."
}
},
"properties": {
"schemaVersion": {
"type": "string",
"enum": [
"v1"
],
"description": "Version of the component metadata schema."
},
"type": {
"type": "string",
"enum": [
"bindings",
"state",
"secretstores",
"pubsub",
"configuration",
"lock",
"middleware"
],
"description": "Component type, of one of the allowed values."
},
"name": {
"type": "string",
"description": "Name of the component (without the inital type, e.g. \"http\" instead of \"bindings.http\")."
},
"version": {
"type": "string",
"description": "Version of the component, with the leading \"v\", e.g. \"v1\"."
},
"status": {
"type": "string",
"enum": [
"stable",
"beta",
"alpha",
"development-only"
],
"description": "Component status."
},
"title": {
"type": "string",
"description": "Title of the component, e.g. \"HTTP\"."
},
"description": {
"type": "string",
"description": "Additional description for the component, optional."
},
"urls": {
"items": {
"$ref": "#/$defs/URL"
},
"type": "array",
"description": "URLs with additional resources for the component, such as docs."
},
"binding": {
"$ref": "#/$defs/Binding",
"description": "Properties for bindings only.\nThis should not present unless \"type\" is \"bindings\"."
},
"capabilities": {
"items": {
"type": "string"
},
"type": "array",
"description": "Component capabilities.\nFor state stores, the presence of \"actorStateStore\" implies that the metadata property \"actorStateStore\" can be set. In that case, do not manually specify \"actorStateStore\" as metadata option."
},
"authenticationProfiles": {
"items": {
"$ref": "#/$defs/AuthenticationProfile"
},
"type": "array",
"description": "Authentication profiles for the component."
},
"metadata": {
"items": {
"$ref": "#/$defs/Metadata"
},
"type": "array",
"description": "Metadata options for the component."
}
},
"additionalProperties": false,
"type": "object",
"required": [
"schemaVersion",
"type",
"name",
"version",
"status",
"title",
"urls"
],
"title": "ComponentMetadata",
"description": "ComponentMetadata is the schema for the metadata.yaml / metadata.json files."
}

View File

@ -0,0 +1,90 @@
# yaml-language-server: $schema=../../../component-metadata-schema.json
schemaVersion: v1
type: state
name: azure.cosmosdb
version: v1
status: stable
title: "Azure Cosmos DB (SQL API)"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-state-stores/setup-azure-cosmosdb/
capabilities:
# If actorStateStore is present, the metadata key actorStateStore can be used
- actorStateStore
- crud
- transactional
- etag
- ttl
- query
authenticationProfiles:
- title: "Master key"
description: "Authenticate using a pre-shared \"master key\"."
metadata:
- name: masterKey
required: true
sensitive: true
description: "The key to authenticate to the Cosmos DB account."
example: '"my-secret-key"'
- title: "Azure AD: Managed identity"
description: "Authenticate using Azure AD and a managed identity."
metadata:
- name: azureClientId
required: false
description: "Client ID (application ID). Required if the service has multiple identities assigned."
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- title: "Azure AD: Client credentials"
description: "Authenticate using Azure AD with client credentials, also known as \"service principals\"."
metadata:
- name: azureTenantId
required: true
description: "ID of the Azure AD tenant"
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
- name: azureClientId
required: true
description: "Client ID (application ID)"
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- name: azureClientSecret
required: true
sensitive: true
description: "Client secret (application password)"
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
- title: "Azure AD: Client certificate"
description: "Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of azureCertificate and azureCertificateFile is required."
metadata:
- name: azureTenantId
required: true
description: "ID of the Azure AD tenant."
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
- name: azureClientId
required: true
description: "Client ID (application ID)."
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
- name: azureCertificate
required: false
sensitive: true
description: "Certificate and private key (in PFX/PKCS#12 format)."
example: |
"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----"
- name: azureCertificateFile
required: false
sensitive: true
description: "Path to PFX/PKCS#12 file on disk, containing the certificate and private key."
example: "/path/to/file.pem"
- name: azureCertificatePassword
required: false
sensitive: true
description: "Password for the certificate if encrypted."
example: "password"
metadata:
- name: url
required: true
description: "The Cosmos DB url."
example: '"https://******.documents.azure.com:443/"'
- name: database
required: true
description: "The name of the database."
example: '"db"'
- name: collection
required: true
description: "The name of the collection (container)."
example: '"collection"'

View File

@ -0,0 +1,66 @@
# yaml-language-server: $schema=../../component-metadata-schema.json
schemaVersion: v1
type: state
name: mongodb
version: v1
status: stable
title: "MongoDB"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-state-stores/setup-mongodb/
- title: Connection options
url: https://www.mongodb.com/docs/manual/reference/connection-string/#std-label-connections-connection-options
capabilities:
# If actorStateStore is present, the metadata key actorStateStore can be used
- actorStateStore
- crud
- transactional
- etag
- query
metadata:
- name: server
# Required if host is not set
required: false
description: "The server to connect to, when using DNS SRV record. One of \"server\" and \"host\" is required."
example: '"server.example.com"'
- name: host
# Required if server is not set
required: false
description: "The host to connect to. One of \"server\" and \"host\" is required."
example: '"mongo-mongodb.default.svc.cluster.local:27017"'
- name: username
description: "The username of the user to connect with (applicable in conjunction with \"host\")"
example: '"admin"'
- name: password
sensitive: true
description: "The password of the user (applicable in conjunction with \"host\")"
example: '"password"'
- name: databaseName
description: "The name of the database to use."
default: '"daprStore"'
example: '"daprStore"'
- name: collectionName
description: "The name of the collection to use."
default: '"daprCollection"'
example: '"daprCollection"'
- name: writeconcern
description: "The write concern to use"
example: '"majority", "2"'
- name: readconcern
description: "The read concern to use"
type: string
allowedValues:
- "available"
- "local"
- "linearizable"
- "majority"
- "snapshot"
example: '"local"'
- name: operationTimeout
description: "The timeout for the operation."
type: duration
default: '"5s"'
example: '"10s"'
- name: params
description: "Additional parameters to use when connecting. The params field accepts a query string that specifies connection specific options as \"<name>=<value>\" pairs, separated by \"&\" and prefixed with \"?\". See the MongoDB manual for the list of available options and their use cases."
example: '"?authSource=daprStore&ssl=true"'

6
tests/e2e/e2e_tests.mk Normal file
View File

@ -0,0 +1,6 @@
################################################################################
# Target: e2e-tests-zeebe #
################################################################################
.PHONY: e2e-tests-zeebe
e2e-tests-zeebe:
CGO_ENABLED=$(CGO) go test -v -tags=e2etests -count=1 ./tests/e2e/bindings/zeebe/...