From 1121b562d0cbd03518c3640cd913ad0c182b493d Mon Sep 17 00:00:00 2001 From: Yaron Schneider Date: Mon, 28 Oct 2019 13:38:47 -0700 Subject: [PATCH 1/3] Update with exporters section (#68) --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 8b6725b2f..3ba7b6811 100644 --- a/Readme.md +++ b/Readme.md @@ -11,6 +11,7 @@ Available component types: * [Pub Sub](pubsub/Readme.md) * [State Stores](state/Readme.md) * [Secret Stores](secretstores/Readme.md) +* [Tracing Exporters](exporters/Readme.md) For documentation on how components are being used in Dapr in a language/platform agnostic way, visit [Dapr Docs](https://github.com/dapr/docs). From 8adf323961492c41c9b810564fe3aeffddef955c Mon Sep 17 00:00:00 2001 From: sayboras Date: Tue, 29 Oct 2019 09:39:48 +1100 Subject: [PATCH 2/3] Add github action for CI (#59) * Initial commit * Fixed all linting error * Used prepared query instead of string format * Enabled linter for test Enabled below linters - gochecknoglobals - gochecknoinits * Enabled below linters - godox - interfacer - maligned * Revert name change for StateStore in pkg state * Incorporate review comments * Cleanup the github ci * Correct typo * Add golangci-lint version in github ci step * Update Readme.md --- .github/workflows/components-contrib.yml | 61 ++++++ .gitignore | 2 + .golangci.yml | 228 ++++++++++++++++++++ Makefile | 62 ++++++ Readme.md | 8 +- bindings/blobstorage/blobstorage.go | 2 +- bindings/cosmosdb/cosmosdb.go | 14 +- bindings/eventhubs/eventhubs.go | 4 +- bindings/http/http.go | 1 + bindings/http/http_test.go | 1 - bindings/kafka/kafka.go | 12 +- bindings/kubernetes/kubernetes_test.go | 4 +- bindings/mqtt/mqtt.go | 6 +- bindings/rabbitmq/rabbitmq_test.go | 1 - bindings/redis/redis.go | 3 +- exporters/exporter.go | 22 +- exporters/metadata.go | 24 +-- exporters/native/native_exporter.go | 132 ++++++------ exporters/native/native_exporter_test.go | 44 ++-- exporters/stringexporter/string_exporter.go | 82 +++---- exporters/zipkin/zipkin_exporter.go | 139 ++++++------ exporters/zipkin/zipkin_exporter_test.go | 44 ++-- go.mod | 15 +- go.sum | 19 ++ state/cassandra/cassandra.go | 11 +- state/cosmosdb/cosmosdb.go | 16 +- state/etcd/etcd.go | 14 +- state/redis/redis.go | 3 +- state/redis/redis_test.go | 172 +++++++-------- state/retry.go | 196 ++++++++--------- state/retry_test.go | 177 ++++++++------- state/state_store.go | 1 + 32 files changed, 954 insertions(+), 566 deletions(-) create mode 100644 .github/workflows/components-contrib.yml create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 Makefile diff --git a/.github/workflows/components-contrib.yml b/.github/workflows/components-contrib.yml new file mode 100644 index 000000000..665df69f0 --- /dev/null +++ b/.github/workflows/components-contrib.yml @@ -0,0 +1,61 @@ +# ------------------------------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------------------------------ + +name: components-contrib + +on: + push: + branches: + - master + - release-* + tags: + - v* + pull_request: + branches: + - master + - release-* +jobs: + build: + name: Build ${{ matrix.target_os }}_${{ matrix.target_arch }} binaries + runs-on: ${{ matrix.os }} + env: + GOVER: 1.13.3 + GOOS: ${{ matrix.target_os }} + GOARCH: ${{ matrix.target_arch }} + GOPROXY: https://proxy.golang.org + GOLANGCI_LINT_VER: v1.21.0 + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + target_arch: [arm, amd64] + include: + - os: ubuntu-latest + target_os: linux + - os: windows-latest + target_os: windows + - os: macOS-latest + target_os: darwin + exclude: + - os: windows-latest + target_arch: arm + - os: macOS-latest + target_arch: arm + steps: + - name: Set up Go ${{ env.GOVER }} + uses: actions/setup-go@v1 + with: + go-version: ${{ env.GOVER }} + - name: Check out code into the Go module directory + uses: actions/checkout@v1 + - name: Install golangci-lint ${{ env.GOLANGCI_LINT_VER }} + if: matrix.target_arch != 'arm' + run: | + curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${{ env.GOROOT }}/bin" "${{ env.GOLANGCI_LINT_VER }}" + - name: Run make lint + if: matrix.target_arch != 'arm' + run: make lint + - name: Run make test + if: matrix.target_arch != 'arm' + run: make test \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..56839acf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/dist +.idea \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..8b2d54a0d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,228 @@ +# options for analysis running +run: + # default concurrency is a available CPU number + concurrency: 4 + + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 5m + + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + + # include test files or not, default is true + tests: true + + # list of build tags, all linters use it. Default is empty list. + #build-tags: + # - mytag + + # which dirs to skip: they won't be analyzed; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but next dirs are always skipped independently + # from this option's value: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs: + - ^vendor$ + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + skip-files: + # - ".*\\.my\\.go$" + # - lib/bad.go + +# output configuration options +output: + # colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number" + format: tab + + # print lines of code with issue, default is true + print-issued-lines: true + + # print linter name in the end of issue text, default is true + print-linter-name: true + + +# all available settings of specific linters +linters-settings: + errcheck: + # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + + # [deprecated] comma-separated list of pairs of the form pkg:regex + # the regex is used to ignore names within pkg. (default "fmt:.*"). + # see https://github.com/kisielk/errcheck#the-deprecated-method for details + ignore: fmt:.*,io/ioutil:^Read.* + + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + exclude: + + funlen: + lines: 60 + statements: 40 + + govet: + # report about shadowed variables + check-shadowing: true + + # settings per analyzer + settings: + printf: # analyzer name, run `go tool vet help` to see all analyzers + funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + + # enable or disable analyzers by name + enable: + - atomicalign + enable-all: false + disable: + - shadow + disable-all: false + golint: + # minimal confidence for issues, default is 0.8 + min-confidence: 0.8 + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + goimports: + # put imports beginning with prefix after 3rd-party packages; + # it's a comma-separated list of prefixes + local-prefixes: + gocyclo: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 10 + gocognit: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 10 + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + dupl: + # tokens count to trigger issue, 150 by default + threshold: 100 + goconst: + # minimal length of string constant, 3 by default + min-len: 3 + # minimal occurrences count to trigger, 3 by default + min-occurrences: 3 + depguard: + list-type: blacklist + include-go-root: false + packages: + - github.com/sirupsen/logrus + packages-with-error-messages: + # specify an error message to output when a blacklisted package is used + github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: default + ignore-words: + - someword + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 120 + # tab width in spaces. Default to 1. + tab-width: 1 + unused: + # treat code as a program (not a library) and report unused exported identifiers; default is false. + # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find funcs usages. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + nakedret: + # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + max-func-lines: 30 + prealloc: + # XXX: we don't recommend using this linter before doing performance profiling. + # For most programs usage of prealloc will be a premature optimization. + + # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. + # True by default. + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + gocritic: + # Which checks should be enabled; can't be combined with 'disabled-checks'; + # See https://go-critic.github.io/overview#checks-overview + # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` + # By default list of stable checks is used. + enabled-checks: + + # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty + disabled-checks: + - regexpMust + - rangeValCopy + - hugeParam + - ifElseChain + - singleCaseSwitch + + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + enabled-tags: + - performance + + settings: # settings passed to gocritic + captLocal: # must be valid enabled check name + paramsOnly: true + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + - NOTE + - OPTIMIZE # marks code that should be optimized before merging + - HACK # marks hack-arounds that should be removed before merging + dogsled: + # checks assignments with too many blank identifiers; default is 2 + max-blank-identifiers: 2 + + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + + wsl: + # If true append is only allowed to be cuddled if appending value is + # matching variables, fields or types on line above. Default is true. + strict-append: true + # Allow calls and assignments to be cuddled as long as the lines have any + # matching variables, fields or types. Default is true. + allow-assign-and-call: true + # Allow multiline assignments to be cuddled. Default is true. + allow-multiline-assign: true + # Allow case blocks to end with a whitespace. + allow-case-traling-whitespace: true + # Allow declarations (var) to be cuddled. + allow-cuddle-declarations: false + +linters: + fast: false + enable-all: true + disable: + # TODO Enforce the below linters later + - dupl + - errcheck + - funlen + - gocyclo + - gocognit + - lll + - scopelint + - unparam + - wsl \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..6b20d3fc6 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +# ------------------------------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------------------------------ + +################################################################################ +# Variables # +################################################################################ + +export GO111MODULE ?= on +export GOPROXY ?= https://proxy.golang.org +export GOSUMDB ?= sum.golang.org + +GIT_COMMIT = $(shell git rev-list -1 HEAD) +GIT_VERSION = $(shell git describe --always --abbrev=7 --dirty) +# By default, disable CGO_ENABLED. See the details on https://golang.org/cmd/cgo +CGO ?= 0 + +LOCAL_ARCH := $(shell uname -m) +ifeq ($(LOCAL_ARCH),x86_64) + TARGET_ARCH_LOCAL=amd64 +else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 5),armv8) + TARGET_ARCH_LOCAL=arm64 +else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 4),armv) + TARGET_ARCH_LOCAL=arm +else + TARGET_ARCH_LOCAL=amd64 +endif +export GOARCH ?= $(TARGET_ARCH_LOCAL) + +LOCAL_OS := $(shell uname) +ifeq ($(LOCAL_OS),Linux) + TARGET_OS_LOCAL = linux +else ifeq ($(LOCAL_OS),Darwin) + TARGET_OS_LOCAL = darwin +else + TARGET_OS_LOCAL ?= windows +endif +export GOOS ?= $(TARGET_OS_LOCAL) + +ifeq ($(GOOS),windows) +BINARY_EXT_LOCAL:=.exe +GOLANGCI_LINT:=golangci-lint.exe +else +BINARY_EXT_LOCAL:= +GOLANGCI_LINT:=golangci-lint +endif + +################################################################################ +# Target: test # +################################################################################ +.PHONY: test +test: + go test ./... -mod=vendor + +################################################################################ +# Target: lint # +################################################################################ +.PHONY: lint +lint: + # Due to https://github.com/golangci/golangci-lint/issues/580, we need to add --fix for windows + $(GOLANGCI_LINT) run --fix \ No newline at end of file diff --git a/Readme.md b/Readme.md index 3ba7b6811..7ecd03fe1 100644 --- a/Readme.md +++ b/Readme.md @@ -37,5 +37,11 @@ git clone https://github.com/dapr/components-contrib.git github.com/dapr/compone ### Running tests ```bash -go test ./... +make test ``` + +### Running linting + +```bash +make lint +``` \ No newline at end of file diff --git a/bindings/blobstorage/blobstorage.go b/bindings/blobstorage/blobstorage.go index d857d0986..b38c5089a 100644 --- a/bindings/blobstorage/blobstorage.go +++ b/bindings/blobstorage/blobstorage.go @@ -49,7 +49,7 @@ func (a *AzureBlobStorage) Init(metadata bindings.Metadata) error { a.metadata = m credential, err := azblob.NewSharedKeyCredential(m.StorageAccount, m.StorageAccessKey) if err != nil { - return fmt.Errorf("Invalid credentials with error: %s", err.Error()) + return fmt.Errorf("invalid credentials with error: %s", err.Error()) } p := azblob.NewPipeline(credential, azblob.PipelineOptions{}) diff --git a/bindings/cosmosdb/cosmosdb.go b/bindings/cosmosdb/cosmosdb.go index 30be0e7a4..dfa334da0 100644 --- a/bindings/cosmosdb/cosmosdb.go +++ b/bindings/cosmosdb/cosmosdb.go @@ -49,22 +49,28 @@ func (c *CosmosDB) Init(metadata bindings.Metadata) error { }) dbs, err := client.QueryDatabases(&documentdb.Query{ - Query: fmt.Sprintf("SELECT * FROM ROOT r WHERE r.id='%s'", m.Database), + Query: "SELECT * FROM ROOT r WHERE r.id=@id", + Parameters: []documentdb.Parameter{ + {Name: "@id", Value: m.Database}, + }, }) if err != nil { return err } else if len(dbs) == 0 { - return fmt.Errorf("Database %s for CosmosDB state store not found", m.Database) + return fmt.Errorf("database %s for CosmosDB state store not found", m.Database) } c.db = &dbs[0] colls, err := client.QueryCollections(c.db.Self, &documentdb.Query{ - Query: fmt.Sprintf("SELECT * FROM ROOT r WHERE r.id='%s'", m.Collection), + Query: "SELECT * FROM ROOT r WHERE r.id=@id", + Parameters: []documentdb.Parameter{ + {Name: "@id", Value: m.Collection}, + }, }) if err != nil { return err } else if len(colls) == 0 { - return fmt.Errorf("Collection %s for CosmosDB state store not found", m.Collection) + return fmt.Errorf("collection %s for CosmosDB state store not found", m.Collection) } c.collection = &colls[0] diff --git a/bindings/eventhubs/eventhubs.go b/bindings/eventhubs/eventhubs.go index 4b6bc68a7..f64d65d5d 100644 --- a/bindings/eventhubs/eventhubs.go +++ b/bindings/eventhubs/eventhubs.go @@ -10,6 +10,7 @@ import ( "encoding/json" "os" "os/signal" + "syscall" "time" eventhub "github.com/Azure/azure-event-hubs-go" @@ -111,7 +112,6 @@ func (a *AzureEventHubs) Read(handler func(*bindings.ReadResponse) error) error if a.metadata.ConsumerGroup != "" { log.Infof("eventhubs: using consumer group %s", a.metadata.ConsumerGroup) ops = append(ops, eventhub.ReceiveWithConsumerGroup(a.metadata.ConsumerGroup)) - } for _, partitionID := range runtimeInfo.PartitionIDs { @@ -122,7 +122,7 @@ func (a *AzureEventHubs) Read(handler func(*bindings.ReadResponse) error) error } signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, os.Interrupt, os.Kill) + signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) <-signalChan a.hub.Close(context.Background()) diff --git a/bindings/http/http.go b/bindings/http/http.go index a9de8b079..fd79a61b1 100644 --- a/bindings/http/http.go +++ b/bindings/http/http.go @@ -16,6 +16,7 @@ import ( ) // HTTPSource is a binding for an http url endpoint invocation +// nolint:golint type HTTPSource struct { metadata httpMetadata } diff --git a/bindings/http/http_test.go b/bindings/http/http_test.go index c3b8583ae..b46c34780 100644 --- a/bindings/http/http_test.go +++ b/bindings/http/http_test.go @@ -20,5 +20,4 @@ func TestInit(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "a", hs.metadata.URL) assert.Equal(t, "a", hs.metadata.Method) - } diff --git a/bindings/kafka/kafka.go b/bindings/kafka/kafka.go index 6978390ef..ff7117446 100644 --- a/bindings/kafka/kafka.go +++ b/bindings/kafka/kafka.go @@ -127,7 +127,7 @@ func (k *Kafka) Read(handler func(*bindings.ReadResponse) error) error { config := sarama.NewConfig() config.Version = sarama.V1_0_0_0 - consumer := consumer{ + c := consumer{ callback: handler, ready: make(chan bool), } @@ -144,18 +144,18 @@ func (k *Kafka) Read(handler func(*bindings.ReadResponse) error) error { go func() { defer wg.Done() for { - if err = client.Consume(ctx, k.topics, &consumer); err != nil { - log.Errorf("error from consumer: %s", err) + if err = client.Consume(ctx, k.topics, &c); err != nil { + log.Errorf("error from c: %s", err) } - // check if context was cancelled, signaling that the consumer should stop + // check if context was cancelled, signaling that the c should stop if ctx.Err() != nil { return } - consumer.ready = make(chan bool) + c.ready = make(chan bool) } }() - <-consumer.ready + <-c.ready sigterm := make(chan os.Signal, 1) signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM) diff --git a/bindings/kubernetes/kubernetes_test.go b/bindings/kubernetes/kubernetes_test.go index 272bbcc9f..f03f6aa7f 100644 --- a/bindings/kubernetes/kubernetes_test.go +++ b/bindings/kubernetes/kubernetes_test.go @@ -17,8 +17,6 @@ import ( "github.com/stretchr/testify/assert" ) -func makerFn() interface{} { return &client.V1Namespace{} } - type staticHandler struct { Code int Body string @@ -64,7 +62,7 @@ func TestReadItem(t *testing.T) { } count := 0 i.Read(func(res *bindings.ReadResponse) error { - count = count + 1 + count++ result := client.Result{} json.Unmarshal(res.Data, &result) diff --git a/bindings/mqtt/mqtt.go b/bindings/mqtt/mqtt.go index 1a8511300..4016f0a22 100644 --- a/bindings/mqtt/mqtt.go +++ b/bindings/mqtt/mqtt.go @@ -72,12 +72,12 @@ func (m *MQTT) getMQTTMetadata(metadata bindings.Metadata) (*mqttMetadata, error return nil, err } - var mqttMetadata mqttMetadata - err = json.Unmarshal(b, &mqttMetadata) + var mMetadata mqttMetadata + err = json.Unmarshal(b, &mMetadata) if err != nil { return nil, err } - return &mqttMetadata, nil + return &mMetadata, nil } func (m *MQTT) Write(req *bindings.WriteRequest) error { diff --git a/bindings/rabbitmq/rabbitmq_test.go b/bindings/rabbitmq/rabbitmq_test.go index 6a5a8b48e..f1c9b15a2 100644 --- a/bindings/rabbitmq/rabbitmq_test.go +++ b/bindings/rabbitmq/rabbitmq_test.go @@ -22,5 +22,4 @@ func TestParseMetadata(t *testing.T) { assert.Equal(t, "a", rm.Host) assert.Equal(t, true, rm.DeleteWhenUnused) assert.Equal(t, true, rm.Durable) - } diff --git a/bindings/redis/redis.go b/bindings/redis/redis.go index d84093e18..1333e84b5 100644 --- a/bindings/redis/redis.go +++ b/bindings/redis/redis.go @@ -9,7 +9,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "github.com/dapr/components-contrib/bindings" @@ -70,7 +69,7 @@ func (r *Redis) parseMetadata(metadata bindings.Metadata) (*redisMetadata, error func (r *Redis) Write(req *bindings.WriteRequest) error { if val, ok := req.Metadata["key"]; ok && val != "" { - key := fmt.Sprintf(val) + key := val res := r.client.Do(context.Background(), "SET", key, req.Data) if err := redis.AsError(res); err != nil { return err diff --git a/exporters/exporter.go b/exporters/exporter.go index 4bf13fa68..571b35f2b 100644 --- a/exporters/exporter.go +++ b/exporters/exporter.go @@ -1,11 +1,11 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package exporters - -// Exporter is the interface for tracing exporter wrappers -type Exporter interface { - Init(daprID string, hostAddress string, metadata Metadata) error -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package exporters + +// Exporter is the interface for tracing exporter wrappers +type Exporter interface { + Init(daprID string, hostAddress string, metadata Metadata) error +} diff --git a/exporters/metadata.go b/exporters/metadata.go index d2b38adf4..50141da8f 100644 --- a/exporters/metadata.go +++ b/exporters/metadata.go @@ -1,12 +1,12 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package exporters - -// Metadata represents a set of exporter specific properties -type Metadata struct { - Properties map[string]string `json:"properties"` - Buffer *string `json:"-"` -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package exporters + +// Metadata represents a set of exporter specific properties +type Metadata struct { + Properties map[string]string `json:"properties"` + Buffer *string `json:"-"` +} diff --git a/exporters/native/native_exporter.go b/exporters/native/native_exporter.go index e0dfb74be..9053501d8 100644 --- a/exporters/native/native_exporter.go +++ b/exporters/native/native_exporter.go @@ -1,66 +1,66 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package native - -import ( - "encoding/json" - "strconv" - - "contrib.go.opencensus.io/exporter/ocagent" - "github.com/dapr/components-contrib/exporters" - "go.opencensus.io/trace" -) - -// Metadata is the native exporter config -type nativeExporterMetadata struct { - AgentEndpoint string `json:"agentEndpoint"` - Enabled string `json:"enabled"` -} - -// NewNativeExporter returns a new native exporter instance -func NewNativeExporter() *Exporter { - return &Exporter{} -} - -// Exporter is an OpenCensus native exporter -type Exporter struct { -} - -// Init creates a new native endpoint and reporter -func (l *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { - meta, err := l.getNativeMetadata(metadata) - if err != nil { - return err - } - - enabled, _ := strconv.ParseBool(meta.Enabled) - if !enabled { - return nil - } - - exporter, err := ocagent.NewExporter(ocagent.WithInsecure(), ocagent.WithServiceName(daprID), ocagent.WithAddress(meta.AgentEndpoint)) - if err != nil { - return err - } - - trace.RegisterExporter(exporter) - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) - return nil -} - -func (l *Exporter) getNativeMetadata(metadata exporters.Metadata) (*nativeExporterMetadata, error) { - b, err := json.Marshal(metadata.Properties) - if err != nil { - return nil, err - } - - var nativeExporterMetadata nativeExporterMetadata - err = json.Unmarshal(b, &nativeExporterMetadata) - if err != nil { - return nil, err - } - return &nativeExporterMetadata, nil -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package native + +import ( + "encoding/json" + "strconv" + + "contrib.go.opencensus.io/exporter/ocagent" + "github.com/dapr/components-contrib/exporters" + "go.opencensus.io/trace" +) + +// Metadata is the native exporter config +type nativeExporterMetadata struct { + AgentEndpoint string `json:"agentEndpoint"` + Enabled string `json:"enabled"` +} + +// NewNativeExporter returns a new native exporter instance +func NewNativeExporter() *Exporter { + return &Exporter{} +} + +// Exporter is an OpenCensus native exporter +type Exporter struct { +} + +// Init creates a new native endpoint and reporter +func (l *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { + meta, err := l.getNativeMetadata(metadata) + if err != nil { + return err + } + + enabled, _ := strconv.ParseBool(meta.Enabled) + if !enabled { + return nil + } + + exporter, err := ocagent.NewExporter(ocagent.WithInsecure(), ocagent.WithServiceName(daprID), ocagent.WithAddress(meta.AgentEndpoint)) + if err != nil { + return err + } + + trace.RegisterExporter(exporter) + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + return nil +} + +func (l *Exporter) getNativeMetadata(metadata exporters.Metadata) (*nativeExporterMetadata, error) { + b, err := json.Marshal(metadata.Properties) + if err != nil { + return nil, err + } + + var nExporterMetadata nativeExporterMetadata + err = json.Unmarshal(b, &nExporterMetadata) + if err != nil { + return nil, err + } + return &nExporterMetadata, nil +} diff --git a/exporters/native/native_exporter_test.go b/exporters/native/native_exporter_test.go index 7015ea058..d3d83ccbc 100644 --- a/exporters/native/native_exporter_test.go +++ b/exporters/native/native_exporter_test.go @@ -1,22 +1,22 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package native - -import ( - "testing" - - "github.com/dapr/components-contrib/exporters" - "github.com/stretchr/testify/assert" -) - -func TestParseMetadata(t *testing.T) { - m := exporters.Metadata{} - m.Properties = map[string]string{"agentEndpoint": "c"} - exporter := NewNativeExporter() - metadata, err := exporter.getNativeMetadata(m) - assert.Nil(t, err) - assert.Equal(t, "c", metadata.AgentEndpoint) -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package native + +import ( + "testing" + + "github.com/dapr/components-contrib/exporters" + "github.com/stretchr/testify/assert" +) + +func TestParseMetadata(t *testing.T) { + m := exporters.Metadata{} + m.Properties = map[string]string{"agentEndpoint": "c"} + exporter := NewNativeExporter() + metadata, err := exporter.getNativeMetadata(m) + assert.Nil(t, err) + assert.Equal(t, "c", metadata.AgentEndpoint) +} diff --git a/exporters/stringexporter/string_exporter.go b/exporters/stringexporter/string_exporter.go index e4991f318..3ebf89359 100644 --- a/exporters/stringexporter/string_exporter.go +++ b/exporters/stringexporter/string_exporter.go @@ -1,41 +1,41 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package stringexporter - -import ( - "strconv" - - "github.com/dapr/components-contrib/exporters" - "go.opencensus.io/trace" -) - -// Metadata is the string exporter config -type stringExporterMetadata struct { - Buffer *string -} - -// NewStringExporter returns a new string exporter instance -func NewStringExporter() *Exporter { - return &Exporter{} -} - -// Exporter is an OpenCensus string exporter -type Exporter struct { - Buffer *string -} - -// ExportSpan exports span content to the buffer -func (se *Exporter) ExportSpan(sd *trace.SpanData) { - *se.Buffer = strconv.Itoa(int(sd.Status.Code)) -} - -// Init creates a new string exporter endpoint and reporter -func (se *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { - se.Buffer = metadata.Buffer - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) - trace.RegisterExporter(se) - return nil -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package stringexporter + +import ( + "strconv" + + "github.com/dapr/components-contrib/exporters" + "go.opencensus.io/trace" +) + +// Metadata is the string exporter config +type Metadata struct { + Buffer *string +} + +// NewStringExporter returns a new string exporter instance +func NewStringExporter() *Exporter { + return &Exporter{} +} + +// Exporter is an OpenCensus string exporter +type Exporter struct { + Buffer *string +} + +// ExportSpan exports span content to the buffer +func (se *Exporter) ExportSpan(sd *trace.SpanData) { + *se.Buffer = strconv.Itoa(int(sd.Status.Code)) +} + +// Init creates a new string exporter endpoint and reporter +func (se *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { + se.Buffer = metadata.Buffer + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + trace.RegisterExporter(se) + return nil +} diff --git a/exporters/zipkin/zipkin_exporter.go b/exporters/zipkin/zipkin_exporter.go index d9e8b7db1..a2ee5c0ad 100644 --- a/exporters/zipkin/zipkin_exporter.go +++ b/exporters/zipkin/zipkin_exporter.go @@ -1,70 +1,69 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package zipkin - -import ( - "encoding/json" - "strconv" - - "contrib.go.opencensus.io/exporter/zipkin" - "github.com/dapr/components-contrib/exporters" - openzipkin "github.com/openzipkin/zipkin-go" - zipkinHTTP "github.com/openzipkin/zipkin-go/reporter/http" - "go.opencensus.io/trace" -) - -// Metadata is the zipkin config -type zipkinMetadata struct { - ExporterAddress string `json:"exporterAddress"` - Enabled string `json:"enabled"` -} - -// NewZipkinExporter returns a new zipkin exporter instance -func NewZipkinExporter() *Exporter { - return &Exporter{} -} - -// Exporter is an OpenCensus zipkin exporter -type Exporter struct { -} - -// Init creates a new zipkin endpoint and reporter -func (z *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { - - meta, err := z.getZipkinMetadata(metadata) - if err != nil { - return err - } - - enabled, _ := strconv.ParseBool(meta.Enabled) - if !enabled { - return nil - } - - localEndpoint, err := openzipkin.NewEndpoint(daprID, hostAddress) - if err != nil { - return err - } - reporter := zipkinHTTP.NewReporter(meta.ExporterAddress) - ze := zipkin.NewExporter(reporter, localEndpoint) - trace.RegisterExporter(ze) - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) - return nil -} - -func (z *Exporter) getZipkinMetadata(metadata exporters.Metadata) (*zipkinMetadata, error) { - b, err := json.Marshal(metadata.Properties) - if err != nil { - return nil, err - } - - var zipkinMeta zipkinMetadata - err = json.Unmarshal(b, &zipkinMeta) - if err != nil { - return nil, err - } - return &zipkinMeta, nil -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package zipkin + +import ( + "encoding/json" + "strconv" + + "contrib.go.opencensus.io/exporter/zipkin" + "github.com/dapr/components-contrib/exporters" + openzipkin "github.com/openzipkin/zipkin-go" + zipkinHTTP "github.com/openzipkin/zipkin-go/reporter/http" + "go.opencensus.io/trace" +) + +// Metadata is the zipkin config +type zipkinMetadata struct { + ExporterAddress string `json:"exporterAddress"` + Enabled string `json:"enabled"` +} + +// NewZipkinExporter returns a new zipkin exporter instance +func NewZipkinExporter() *Exporter { + return &Exporter{} +} + +// Exporter is an OpenCensus zipkin exporter +type Exporter struct { +} + +// Init creates a new zipkin endpoint and reporter +func (z *Exporter) Init(daprID string, hostAddress string, metadata exporters.Metadata) error { + meta, err := z.getZipkinMetadata(metadata) + if err != nil { + return err + } + + enabled, _ := strconv.ParseBool(meta.Enabled) + if !enabled { + return nil + } + + localEndpoint, err := openzipkin.NewEndpoint(daprID, hostAddress) + if err != nil { + return err + } + reporter := zipkinHTTP.NewReporter(meta.ExporterAddress) + ze := zipkin.NewExporter(reporter, localEndpoint) + trace.RegisterExporter(ze) + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + return nil +} + +func (z *Exporter) getZipkinMetadata(metadata exporters.Metadata) (*zipkinMetadata, error) { + b, err := json.Marshal(metadata.Properties) + if err != nil { + return nil, err + } + + var zipkinMeta zipkinMetadata + err = json.Unmarshal(b, &zipkinMeta) + if err != nil { + return nil, err + } + return &zipkinMeta, nil +} diff --git a/exporters/zipkin/zipkin_exporter_test.go b/exporters/zipkin/zipkin_exporter_test.go index 34caf10a5..833d4fc32 100644 --- a/exporters/zipkin/zipkin_exporter_test.go +++ b/exporters/zipkin/zipkin_exporter_test.go @@ -1,22 +1,22 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package zipkin - -import ( - "testing" - - "github.com/dapr/components-contrib/exporters" - "github.com/stretchr/testify/assert" -) - -func TestParseMetadata(t *testing.T) { - m := exporters.Metadata{} - m.Properties = map[string]string{"exporterAddress": "c"} - exporter := NewZipkinExporter() - metadata, err := exporter.getZipkinMetadata(m) - assert.Nil(t, err) - assert.Equal(t, "c", metadata.ExporterAddress) -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package zipkin + +import ( + "testing" + + "github.com/dapr/components-contrib/exporters" + "github.com/stretchr/testify/assert" +) + +func TestParseMetadata(t *testing.T) { + m := exporters.Metadata{} + m.Properties = map[string]string{"exporterAddress": "c"} + exporter := NewZipkinExporter() + metadata, err := exporter.getZipkinMetadata(m) + assert.Nil(t, err) + assert.Equal(t, "c", metadata.ExporterAddress) +} diff --git a/go.mod b/go.mod index 41e2a72a8..77dda15d2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/dapr/components-contrib -go 1.12 +go 1.13 require ( cloud.google.com/go/pubsub v1.0.1 @@ -22,7 +22,9 @@ require ( github.com/Sirupsen/logrus v1.0.6 github.com/a8m/documentdb v1.2.0 github.com/aws/aws-sdk-go v1.25.0 + github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.17+incompatible // indirect + github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/creack/pty v1.1.9 // indirect @@ -32,13 +34,16 @@ require ( github.com/garyburd/redigo v1.6.0 // indirect github.com/go-redis/redis v6.15.5+incompatible github.com/gocql/gocql v0.0.0-20191018090344-07ace3bab0f8 - github.com/google/btree v1.0.0 // indirect github.com/google/pprof v0.0.0-20190908185732-236ed259b199 // indirect github.com/google/uuid v1.1.1 + github.com/gorilla/websocket v1.4.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.11.2 // indirect github.com/hashicorp/consul/api v1.2.0 github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jonboulle/clockwork v0.1.0 // indirect github.com/joomcode/errorx v1.0.0 // indirect github.com/joomcode/redispipe v0.9.0 github.com/json-iterator/go v1.1.7 @@ -53,13 +58,15 @@ require ( github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/rogpeppe/go-internal v1.4.0 // indirect github.com/satori/go.uuid v1.2.0 + github.com/soheilhy/cmux v0.1.4 // indirect github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 github.com/stretchr/testify v1.4.0 + github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/etcd v3.3.17+incompatible go.opencensus.io v0.22.1 - go.uber.org/atomic v1.4.0 // indirect go.uber.org/multierr v1.2.0 // indirect - go.uber.org/zap v1.10.0 // indirect golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad golang.org/x/exp v0.0.0-20190927203820-447a159532ef // indirect golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a // indirect diff --git a/go.sum b/go.sum index 33e562709..aa450cc4f 100644 --- a/go.sum +++ b/go.sum @@ -103,8 +103,10 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo= github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= @@ -156,6 +158,8 @@ github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415 h1:WSBJMqJbLxsn+bTCP github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -201,7 +205,10 @@ github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1: github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -249,6 +256,7 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/joomcode/errorx v1.0.0 h1:RJAKLTy1Sv2Tszhu14m5RZP4VGRlhXutG/XlL1En5VM= github.com/joomcode/errorx v1.0.0/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ= github.com/joomcode/redispipe v0.9.0 h1:NukwwIvxhg6r2lVxa1RJhEZXYPZZF/OX9WZJk+2cK1Q= @@ -261,8 +269,10 @@ github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62F github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -305,6 +315,7 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3 h1:EooPXg51Tn+xmWPXJUGCnJhJSpeuMlBmfJVcqIRmmv8= github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.1 h1:A/ADD6HaPnAKj3yS7HjGHRK77qi41Hi0DirOOIQAeIw= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6 h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtLXHPBo= @@ -339,6 +350,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg= github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw= @@ -352,8 +365,11 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v3.3.17+incompatible h1:g8iRku1SID8QAW8cDlV0L/PkZlw63LSiYEHYHoE6j/s= go.etcd.io/etcd v3.3.17+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= @@ -364,6 +380,7 @@ go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= @@ -449,6 +466,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -470,6 +488,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZe golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w= golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/state/cassandra/cassandra.go b/state/cassandra/cassandra.go index a6754d9d7..f536f93e1 100644 --- a/state/cassandra/cassandra.go +++ b/state/cassandra/cassandra.go @@ -194,8 +194,7 @@ func getCassandraMetadata(metadata state.Metadata) (*cassandraMetadata, error) { // Delete performs a delete operation func (c *Cassandra) Delete(req *state.DeleteRequest) error { - query := fmt.Sprintf("DELETE FROM %s WHERE key='%s'", c.table, req.Key) - return c.session.Query(query).Exec() + return c.session.Query("DELETE FROM ? WHERE key = ?", c.table, req.Key).Exec() } // BulkDelete performs a bulk delete operation @@ -212,8 +211,6 @@ func (c *Cassandra) BulkDelete(req []state.DeleteRequest) error { // Get retrieves state from cassandra with a key func (c *Cassandra) Get(req *state.GetRequest) (*state.GetResponse, error) { - query := fmt.Sprintf("SELECT value FROM %s WHERE key='%s'", c.table, req.Key) - session := c.session if req.Options.Consistency == state.Strong { @@ -232,7 +229,7 @@ func (c *Cassandra) Get(req *state.GetRequest) (*state.GetResponse, error) { session = sess } - results, err := session.Query(query).Iter().SliceMap() + results, err := session.Query("SELECT value FROM ? WHERE key = ?", c.table, req.Key).Iter().SliceMap() if err != nil { return nil, err } @@ -255,8 +252,6 @@ func (c *Cassandra) Set(req *state.SetRequest) error { bt, _ = jsoniter.ConfigFastest.Marshal(req.Value) } - query := fmt.Sprintf("INSERT INTO %s (key, value) VALUES (?, ?)", c.table) - session := c.session if req.Options.Consistency == state.Strong { @@ -275,7 +270,7 @@ func (c *Cassandra) Set(req *state.SetRequest) error { session = sess } - return session.Query(query, req.Key, bt).Exec() + return session.Query("INSERT INTO ? (key, value) VALUES (?, ?)", c.table, req.Key, bt).Exec() } func (c *Cassandra) createSession(consistency gocql.Consistency) (*gocql.Session, error) { diff --git a/state/cosmosdb/cosmosdb.go b/state/cosmosdb/cosmosdb.go index fc76dd8fc..e752528de 100644 --- a/state/cosmosdb/cosmosdb.go +++ b/state/cosmosdb/cosmosdb.go @@ -63,22 +63,28 @@ func (c *StateStore) Init(metadata state.Metadata) error { }) dbs, err := client.QueryDatabases(&documentdb.Query{ - Query: fmt.Sprintf("SELECT * FROM ROOT r WHERE r.id='%s'", creds.Database), + Query: "SELECT * FROM ROOT r WHERE r.id=@id", + Parameters: []documentdb.Parameter{ + {Name: "@id", Value: creds.Database}, + }, }) if err != nil { return err } else if len(dbs) == 0 { - return fmt.Errorf("Database %s for CosmosDB state store not found", creds.Database) + return fmt.Errorf("database %s for CosmosDB state store not found", creds.Database) } c.db = &dbs[0] colls, err := client.QueryCollections(c.db.Self, &documentdb.Query{ - Query: fmt.Sprintf("SELECT * FROM ROOT r WHERE r.id='%s'", creds.Collection), + Query: "SELECT * FROM ROOT r WHERE r.id=@id", + Parameters: []documentdb.Parameter{ + {Name: "@id", Value: creds.Collection}, + }, }) if err != nil { return err } else if len(colls) == 0 { - return fmt.Errorf("Collection %s for CosmosDB state store not found", creds.Collection) + return fmt.Errorf("collection %s for CosmosDB state store not found", creds.Collection) } c.collection = &colls[0] @@ -102,7 +108,7 @@ func (c *StateStore) Get(req *state.GetRequest) (*state.GetResponse, error) { _, err := c.client.QueryDocuments( c.collection.Self, - documentdb.NewQuery("SELECT * FROM ROOT r WHERE r.id=@id", documentdb.P{"@id", key}), + documentdb.NewQuery("SELECT * FROM ROOT r WHERE r.id=@id", documentdb.P{Name: "@id", Value: key}), &items, options..., ) diff --git a/state/etcd/etcd.go b/state/etcd/etcd.go index 839a530d7..7bed279c1 100644 --- a/state/etcd/etcd.go +++ b/state/etcd/etcd.go @@ -19,10 +19,10 @@ import ( "google.golang.org/grpc" ) -const defaultOperationTimeout = time.Duration(10 * time.Second) +const defaultOperationTimeout = 10 * time.Second const defaultSeparator = "," -var errMissingEndpoints = errors.New("Endpoints are required") +var errMissingEndpoints = errors.New("endpoints are required") var errInvalidDialTimeout = errors.New("DialTimeout is invalid") // ETCD is a state store @@ -126,7 +126,8 @@ func validateRequired(configProps *configProperties) error { // Get retrieves state from ETCD with a key func (r *ETCD) Get(req *state.GetRequest) (*state.GetResponse, error) { - ctx, _ := context.WithTimeout(context.Background(), r.operationTimeout) + ctx, cancel := context.WithTimeout(context.Background(), r.operationTimeout) + defer cancel() resp, err := r.client.Get(ctx, req.Key, clientv3.WithSort(clientv3.SortByVersion, clientv3.SortDescend)) if err != nil { return nil, err @@ -144,7 +145,8 @@ func (r *ETCD) Get(req *state.GetRequest) (*state.GetResponse, error) { // Delete performs a delete operation func (r *ETCD) Delete(req *state.DeleteRequest) error { - ctx, _ := context.WithTimeout(context.Background(), r.operationTimeout) + ctx, cancelFn := context.WithTimeout(context.Background(), r.operationTimeout) + defer cancelFn() _, err := r.client.Delete(ctx, req.Key) if err != nil { return err @@ -167,8 +169,8 @@ func (r *ETCD) BulkDelete(req []state.DeleteRequest) error { // Set saves state into ETCD func (r *ETCD) Set(req *state.SetRequest) error { - ctx, _ := context.WithTimeout(context.Background(), r.operationTimeout) - + ctx, cancelFn := context.WithTimeout(context.Background(), r.operationTimeout) + defer cancelFn() var vStr string b, ok := req.Value.([]byte) if ok { diff --git a/state/redis/redis.go b/state/redis/redis.go index 2ca61bb08..a6ca2e2fe 100644 --- a/state/redis/redis.go +++ b/state/redis/redis.go @@ -97,13 +97,12 @@ func (r *StateStore) getConnectedSlaves() (int, error) { } return r.parseConnectedSlaves(s), nil - } func (r *StateStore) parseConnectedSlaves(res string) int { infos := strings.Split(res, infoReplicationDelimiter) for _, info := range infos { - if strings.Index(info, connectedSlavesReplicas) >= 0 { + if strings.Contains(info, connectedSlavesReplicas) { parsedReplicas, _ := strconv.ParseUint(info[len(connectedSlavesReplicas):], 10, 32) return int(parsedReplicas) } diff --git a/state/redis/redis_test.go b/state/redis/redis_test.go index 7b685f0c8..ef65dd1ad 100644 --- a/state/redis/redis_test.go +++ b/state/redis/redis_test.go @@ -1,86 +1,86 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package redis - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGetKeyVersion(t *testing.T) { - store := NewRedisStateStore() - t.Run("With all required fields", func(t *testing.T) { - key, ver, err := store.getKeyVersion([]interface{}{"data", "TEST_KEY", "version", "TEST_VER"}) - assert.Equal(t, nil, err, "failed to read all fields") - assert.Equal(t, "TEST_KEY", key, "failed to read key") - assert.Equal(t, "TEST_VER", ver, "failed to read version") - }) - t.Run("With missing data", func(t *testing.T) { - _, _, err := store.getKeyVersion([]interface{}{"version", "TEST_VER"}) - assert.NotNil(t, err, "failed to respond to missing data field") - }) - t.Run("With missing version", func(t *testing.T) { - _, _, err := store.getKeyVersion([]interface{}{"data", "TEST_KEY"}) - assert.NotNil(t, err, "failed to respond to missing version field") - }) - t.Run("With all required fields - out of order", func(t *testing.T) { - key, ver, err := store.getKeyVersion([]interface{}{"version", "TEST_VER", "dragon", "TEST_DRAGON", "data", "TEST_KEY"}) - assert.Equal(t, nil, err, "failed to read all fields") - assert.Equal(t, "TEST_KEY", key, "failed to read key") - assert.Equal(t, "TEST_VER", ver, "failed to read version") - }) - t.Run("With no fields", func(t *testing.T) { - _, _, err := store.getKeyVersion([]interface{}{}) - assert.NotNil(t, err, "failed to respond to missing fields") - }) - t.Run("With wrong fields", func(t *testing.T) { - _, _, err := store.getKeyVersion([]interface{}{"dragon", "TEST_DRAGON"}) - assert.NotNil(t, err, "failed to respond to missing fields") - }) -} - -func TestParseEtag(t *testing.T) { - store := NewRedisStateStore() - t.Run("Empty ETag", func(t *testing.T) { - ver, err := store.parseETag("") - assert.Equal(t, nil, err, "failed to parse ETag") - assert.Equal(t, 0, ver, "default version should be 0") - }) - t.Run("Number ETag", func(t *testing.T) { - ver, err := store.parseETag("354") - assert.Equal(t, nil, err, "failed to parse ETag") - assert.Equal(t, 354, ver, "version should be 254") - }) - t.Run("String ETag", func(t *testing.T) { - _, err := store.parseETag("dragon") - assert.NotNil(t, err, "shouldn't recognize string ETag") - }) -} - -func TestParseConnectedSlavs(t *testing.T) { - store := NewRedisStateStore() - - t.Run("Empty info", func(t *testing.T) { - slaves := store.parseConnectedSlaves("") - assert.Equal(t, 0, slaves, "connected slaves must be 0") - }) - - t.Run("connectedSlaves property is not included", func(t *testing.T) { - slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\n") - assert.Equal(t, 0, slaves, "connected slaves must be 0") - }) - - t.Run("connectedSlaves is 2", func(t *testing.T) { - slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\nconnected_slaves:2\r\n") - assert.Equal(t, 2, slaves, "connected slaves must be 2") - }) - - t.Run("connectedSlaves is 1", func(t *testing.T) { - slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\nconnected_slaves:1") - assert.Equal(t, 1, slaves, "connected slaves must be 1") - }) -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package redis + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetKeyVersion(t *testing.T) { + store := NewRedisStateStore() + t.Run("With all required fields", func(t *testing.T) { + key, ver, err := store.getKeyVersion([]interface{}{"data", "TEST_KEY", "version", "TEST_VER"}) + assert.Equal(t, nil, err, "failed to read all fields") + assert.Equal(t, "TEST_KEY", key, "failed to read key") + assert.Equal(t, "TEST_VER", ver, "failed to read version") + }) + t.Run("With missing data", func(t *testing.T) { + _, _, err := store.getKeyVersion([]interface{}{"version", "TEST_VER"}) + assert.NotNil(t, err, "failed to respond to missing data field") + }) + t.Run("With missing version", func(t *testing.T) { + _, _, err := store.getKeyVersion([]interface{}{"data", "TEST_KEY"}) + assert.NotNil(t, err, "failed to respond to missing version field") + }) + t.Run("With all required fields - out of order", func(t *testing.T) { + key, ver, err := store.getKeyVersion([]interface{}{"version", "TEST_VER", "dragon", "TEST_DRAGON", "data", "TEST_KEY"}) + assert.Equal(t, nil, err, "failed to read all fields") + assert.Equal(t, "TEST_KEY", key, "failed to read key") + assert.Equal(t, "TEST_VER", ver, "failed to read version") + }) + t.Run("With no fields", func(t *testing.T) { + _, _, err := store.getKeyVersion([]interface{}{}) + assert.NotNil(t, err, "failed to respond to missing fields") + }) + t.Run("With wrong fields", func(t *testing.T) { + _, _, err := store.getKeyVersion([]interface{}{"dragon", "TEST_DRAGON"}) + assert.NotNil(t, err, "failed to respond to missing fields") + }) +} + +func TestParseEtag(t *testing.T) { + store := NewRedisStateStore() + t.Run("Empty ETag", func(t *testing.T) { + ver, err := store.parseETag("") + assert.Equal(t, nil, err, "failed to parse ETag") + assert.Equal(t, 0, ver, "default version should be 0") + }) + t.Run("Number ETag", func(t *testing.T) { + ver, err := store.parseETag("354") + assert.Equal(t, nil, err, "failed to parse ETag") + assert.Equal(t, 354, ver, "version should be 254") + }) + t.Run("String ETag", func(t *testing.T) { + _, err := store.parseETag("dragon") + assert.NotNil(t, err, "shouldn't recognize string ETag") + }) +} + +func TestParseConnectedSlavs(t *testing.T) { + store := NewRedisStateStore() + + t.Run("Empty info", func(t *testing.T) { + slaves := store.parseConnectedSlaves("") + assert.Equal(t, 0, slaves, "connected slaves must be 0") + }) + + t.Run("connectedSlaves property is not included", func(t *testing.T) { + slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\n") + assert.Equal(t, 0, slaves, "connected slaves must be 0") + }) + + t.Run("connectedSlaves is 2", func(t *testing.T) { + slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\nconnected_slaves:2\r\n") + assert.Equal(t, 2, slaves, "connected slaves must be 2") + }) + + t.Run("connectedSlaves is 1", func(t *testing.T) { + slaves := store.parseConnectedSlaves("# Replication\r\nrole:master\r\nconnected_slaves:1") + assert.Equal(t, 1, slaves, "connected slaves must be 1") + }) +} diff --git a/state/retry.go b/state/retry.go index 5737ab3b6..07253f61c 100644 --- a/state/retry.go +++ b/state/retry.go @@ -1,98 +1,98 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package state - -import ( - "fmt" - "time" -) - -const ( - FirstWrite = "first-write" - LastWrite = "last-write" - Strong = "strong" - Eventual = "eventual" - Exponential = "exponential" - Linear = "linear" -) - -// CheckSetRequestOptions checks if set request options use supported keywords -func CheckSetRequestOptions(req *SetRequest) error { - if req.Options.Concurrency != "" && req.Options.Concurrency != FirstWrite && req.Options.Concurrency != LastWrite { - return fmt.Errorf("unrecognized concurrency model '%s'", req.Options.Concurrency) - } - if req.Options.Consistency != "" && req.Options.Consistency != Strong && req.Options.Consistency != Eventual { - return fmt.Errorf("unrecognized consistency model '%s'", req.Options.Consistency) - } - return nil -} - -// CheckDeleteRequestOptions checks if delete request options use supported keywords -func CheckDeleteRequestOptions(req *DeleteRequest) error { - if req.Options.Concurrency != "" && req.Options.Concurrency != FirstWrite && req.Options.Concurrency != LastWrite { - return fmt.Errorf("unrecognized concurrency model '%s'", req.Options.Concurrency) - } - if req.Options.Consistency != "" && req.Options.Consistency != Strong && req.Options.Consistency != Eventual { - return fmt.Errorf("unrecognized consistency model '%s'", req.Options.Consistency) - } - return nil -} - -// SetWithRetries handles SetRequest with retries -func SetWithRetries(method func(req *SetRequest) error, req *SetRequest) error { - switch req.Options.RetryPolicy.Pattern { - case "": - fallthrough - case Linear: - fallthrough - case Exponential: - if req.Options.RetryPolicy.Threshold > 0 { - duration := req.Options.RetryPolicy.Interval - for i := 0; i < req.Options.RetryPolicy.Threshold; i++ { - err := method(req) - if err == nil { - return nil - } - time.Sleep(duration) - if req.Options.RetryPolicy.Pattern == Exponential { - duration *= 2 - } - } - return fmt.Errorf("failed to set value after %d retries", req.Options.RetryPolicy.Threshold) - } - return method(req) - default: - return fmt.Errorf("unrecognized retry patter '%s'", req.Options.RetryPolicy.Pattern) - } -} - -// DeleteWithRetries handles SetRequest with retries -func DeleteWithRetries(method func(req *DeleteRequest) error, req *DeleteRequest) error { - switch req.Options.RetryPolicy.Pattern { - case "": - fallthrough - case Linear: - fallthrough - case Exponential: - if req.Options.RetryPolicy.Threshold > 0 { - duration := req.Options.RetryPolicy.Interval - for i := 0; i < req.Options.RetryPolicy.Threshold; i++ { - err := method(req) - if err == nil { - return nil - } - time.Sleep(duration) - if req.Options.RetryPolicy.Pattern == Exponential { - duration *= 2 - } - } - return fmt.Errorf("failed to set value after %d retries", req.Options.RetryPolicy.Threshold) - } - return method(req) - default: - return fmt.Errorf("unrecognized retry patter '%s'", req.Options.RetryPolicy.Pattern) - } -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package state + +import ( + "fmt" + "time" +) + +const ( + FirstWrite = "first-write" + LastWrite = "last-write" + Strong = "strong" + Eventual = "eventual" + Exponential = "exponential" + Linear = "linear" +) + +// CheckSetRequestOptions checks if set request options use supported keywords +func CheckSetRequestOptions(req *SetRequest) error { + if req.Options.Concurrency != "" && req.Options.Concurrency != FirstWrite && req.Options.Concurrency != LastWrite { + return fmt.Errorf("unrecognized concurrency model '%s'", req.Options.Concurrency) + } + if req.Options.Consistency != "" && req.Options.Consistency != Strong && req.Options.Consistency != Eventual { + return fmt.Errorf("unrecognized consistency model '%s'", req.Options.Consistency) + } + return nil +} + +// CheckDeleteRequestOptions checks if delete request options use supported keywords +func CheckDeleteRequestOptions(req *DeleteRequest) error { + if req.Options.Concurrency != "" && req.Options.Concurrency != FirstWrite && req.Options.Concurrency != LastWrite { + return fmt.Errorf("unrecognized concurrency model '%s'", req.Options.Concurrency) + } + if req.Options.Consistency != "" && req.Options.Consistency != Strong && req.Options.Consistency != Eventual { + return fmt.Errorf("unrecognized consistency model '%s'", req.Options.Consistency) + } + return nil +} + +// SetWithRetries handles SetRequest with retries +func SetWithRetries(method func(req *SetRequest) error, req *SetRequest) error { + switch req.Options.RetryPolicy.Pattern { + case "": + fallthrough + case Linear: + fallthrough + case Exponential: + if req.Options.RetryPolicy.Threshold > 0 { + duration := req.Options.RetryPolicy.Interval + for i := 0; i < req.Options.RetryPolicy.Threshold; i++ { + err := method(req) + if err == nil { + return nil + } + time.Sleep(duration) + if req.Options.RetryPolicy.Pattern == Exponential { + duration *= 2 + } + } + return fmt.Errorf("failed to set value after %d retries", req.Options.RetryPolicy.Threshold) + } + return method(req) + default: + return fmt.Errorf("unrecognized retry patter '%s'", req.Options.RetryPolicy.Pattern) + } +} + +// DeleteWithRetries handles SetRequest with retries +func DeleteWithRetries(method func(req *DeleteRequest) error, req *DeleteRequest) error { + switch req.Options.RetryPolicy.Pattern { + case "": + fallthrough + case Linear: + fallthrough + case Exponential: + if req.Options.RetryPolicy.Threshold > 0 { + duration := req.Options.RetryPolicy.Interval + for i := 0; i < req.Options.RetryPolicy.Threshold; i++ { + err := method(req) + if err == nil { + return nil + } + time.Sleep(duration) + if req.Options.RetryPolicy.Pattern == Exponential { + duration *= 2 + } + } + return fmt.Errorf("failed to set value after %d retries", req.Options.RetryPolicy.Threshold) + } + return method(req) + default: + return fmt.Errorf("unrecognized retry patter '%s'", req.Options.RetryPolicy.Pattern) + } +} diff --git a/state/retry_test.go b/state/retry_test.go index 731df3f89..6e5962c50 100644 --- a/state/retry_test.go +++ b/state/retry_test.go @@ -1,89 +1,88 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// ------------------------------------------------------------ - -package state - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -// TestRetryPolicies is used to test retry policies -func TestRetryPolicies(t *testing.T) { - t.Run("set with no options", func(t *testing.T) { - counter := 0 - SetWithRetries(func(req *SetRequest) error { - counter++ - return nil - }, &SetRequest{}) - assert.Equal(t, 1, counter, "should execute only once") - }) - - t.Run("set with no retry policies", func(t *testing.T) { - counter := 0 - SetWithRetries(func(req *SetRequest) error { - counter++ - return nil - }, &SetRequest{ - Options: SetStateOption{}, - }) - assert.Equal(t, 1, counter, "should execute only once") - }) - - t.Run("set with empty retry policies", func(t *testing.T) { - counter := 0 - SetWithRetries(func(req *SetRequest) error { - counter++ - return nil - }, &SetRequest{ - Options: SetStateOption{ - RetryPolicy: RetryPolicy{ - Interval: 0, - Threshold: 0, - Pattern: "", - }, - }, - }) - assert.Equal(t, 1, counter, "should execute only once") - }) - - t.Run("bad policy", func(t *testing.T) { - ret := SetWithRetries(func(req *SetRequest) error { - return nil - }, &SetRequest{ - Options: SetStateOption{ - RetryPolicy: RetryPolicy{ - Interval: 100, - Threshold: 3, - Pattern: "dummy", - }, - }, - }) - assert.NotNil(t, ret, "should reject policy") - }) - - t.Run("liner retry 3 times", func(t *testing.T) { - counter := 0 - SetWithRetries(func(req *SetRequest) error { - counter++ - if counter < 3 { - return fmt.Errorf("BAD") - } - return nil - }, &SetRequest{ - Options: SetStateOption{ - RetryPolicy: RetryPolicy{ - Interval: 100, - Threshold: 3, - Pattern: "linear", - }, - }, - }) - assert.Equal(t, 3, counter, "should execute 3 times") - }) - -} +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package state + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestRetryPolicies is used to test retry policies +func TestRetryPolicies(t *testing.T) { + t.Run("set with no options", func(t *testing.T) { + counter := 0 + SetWithRetries(func(req *SetRequest) error { + counter++ + return nil + }, &SetRequest{}) + assert.Equal(t, 1, counter, "should execute only once") + }) + + t.Run("set with no retry policies", func(t *testing.T) { + counter := 0 + SetWithRetries(func(req *SetRequest) error { + counter++ + return nil + }, &SetRequest{ + Options: SetStateOption{}, + }) + assert.Equal(t, 1, counter, "should execute only once") + }) + + t.Run("set with empty retry policies", func(t *testing.T) { + counter := 0 + SetWithRetries(func(req *SetRequest) error { + counter++ + return nil + }, &SetRequest{ + Options: SetStateOption{ + RetryPolicy: RetryPolicy{ + Interval: 0, + Threshold: 0, + Pattern: "", + }, + }, + }) + assert.Equal(t, 1, counter, "should execute only once") + }) + + t.Run("bad policy", func(t *testing.T) { + ret := SetWithRetries(func(req *SetRequest) error { + return nil + }, &SetRequest{ + Options: SetStateOption{ + RetryPolicy: RetryPolicy{ + Interval: 100, + Threshold: 3, + Pattern: "dummy", + }, + }, + }) + assert.NotNil(t, ret, "should reject policy") + }) + + t.Run("liner retry 3 times", func(t *testing.T) { + counter := 0 + SetWithRetries(func(req *SetRequest) error { + counter++ + if counter < 3 { + return fmt.Errorf("BAD") + } + return nil + }, &SetRequest{ + Options: SetStateOption{ + RetryPolicy: RetryPolicy{ + Interval: 100, + Threshold: 3, + Pattern: "linear", + }, + }, + }) + assert.Equal(t, 3, counter, "should execute 3 times") + }) +} diff --git a/state/state_store.go b/state/state_store.go index 043c3254d..2ddc6a854 100644 --- a/state/state_store.go +++ b/state/state_store.go @@ -6,6 +6,7 @@ package state // StateStore is an interface to perform operations on store +// nolint:golint type StateStore interface { Init(metadata Metadata) error Delete(req *DeleteRequest) error From b0c67018bf5ebe6d04ac3264177ed57614a814a7 Mon Sep 17 00:00:00 2001 From: sayboras Date: Tue, 29 Oct 2019 16:02:24 +1100 Subject: [PATCH 3/3] To add the build badge for github action (#69) --- Readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Readme.md b/Readme.md index 7ecd03fe1..054e2aed5 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,11 @@ # Components Contrib +[![Go Report Card](https://goreportcard.com/badge/github.com/dapr/components-contrib)](https://goreportcard.com/report/github.com/dapr/components-contrib) +[![Build Status](https://github.com/dapr/components-contrib/workflows/components-contrib/badge.svg?event=push&branch=master)](https://github.com/dapr/components-contrib/actions?workflow=components-contrib) +[![Gitter](https://badges.gitter.im/Dapr/community.svg)](https://gitter.im/Dapr/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + + The purpose of Components Contrib is to provide open, community driven reusable components for building distributed applications. These components are being used by the [Dapr](https://github.com/dapr/dapr) project, but are separate and decoupled from it.