mirror of https://github.com/dapr/go-sdk.git
ci: standard linter config (#199)
Signed-off-by: Long <long0dai@foxmail.com>
This commit is contained in:
parent
994f9b69f2
commit
de5cf935fb
|
|
@ -11,6 +11,10 @@ jobs:
|
|||
build:
|
||||
name: Test and Lint on Push
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOVER: 1.17
|
||||
GOLANGCILINT_VER: v1.31
|
||||
|
||||
steps:
|
||||
|
||||
- name: Setup
|
||||
|
|
@ -41,8 +45,6 @@ jobs:
|
|||
uses: codecov/codecov-action@v1
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
uses: golangci/golangci-lint-action@v2.2.1
|
||||
with:
|
||||
version: v1.33
|
||||
|
||||
|
||||
version: ${{ env.GOLANGCILINT_VER }}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,255 @@
|
|||
# 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: 10m
|
||||
|
||||
# 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:
|
||||
# third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs:
|
||||
- ^pkg.*client.*clientset.*versioned.*
|
||||
- ^pkg.*client.*informers.*externalversions.*
|
||||
- ^pkg.*proto.*
|
||||
|
||||
# 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: github.com/dapr/
|
||||
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: 5
|
||||
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: "must use github.com/dapr/kit/logger"
|
||||
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
|
||||
- exitAfterDefer
|
||||
|
||||
# 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
|
||||
godot:
|
||||
exclude:
|
||||
- 'nosec'
|
||||
capital: false
|
||||
scope: all
|
||||
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
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocyclo
|
||||
- gocognit
|
||||
- godox
|
||||
- interfacer
|
||||
- lll
|
||||
- maligned
|
||||
- scopelint
|
||||
- unparam
|
||||
- wsl
|
||||
- gomnd
|
||||
- testpackage
|
||||
- goerr113
|
||||
- nestif
|
||||
- nlreturn
|
||||
- exhaustive
|
||||
- noctx
|
||||
- gci
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: .*_test.go
|
||||
linters:
|
||||
- godot
|
||||
|
||||
|
|
@ -3,11 +3,12 @@ package client
|
|||
import (
|
||||
"context"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
)
|
||||
|
||||
// InvokeBindingRequest represents binding invocation request
|
||||
// InvokeBindingRequest represents binding invocation request.
|
||||
type InvokeBindingRequest struct {
|
||||
// Name is name of binding to invoke.
|
||||
Name string
|
||||
|
|
@ -19,7 +20,7 @@ type InvokeBindingRequest struct {
|
|||
Metadata map[string]string
|
||||
}
|
||||
|
||||
// BindingEvent represents the binding event handler input
|
||||
// BindingEvent represents the binding event handler input.
|
||||
type BindingEvent struct {
|
||||
// Data is the input bindings sent
|
||||
Data []byte
|
||||
|
|
@ -29,7 +30,7 @@ type BindingEvent struct {
|
|||
|
||||
// InvokeBinding invokes specific operation on the configured Dapr binding.
|
||||
// This method covers input, output, and bi-directional bindings.
|
||||
func (c *GRPCClient) InvokeBinding(ctx context.Context, in *InvokeBindingRequest) (out *BindingEvent, err error) {
|
||||
func (c *GRPCClient) InvokeBinding(ctx context.Context, in *InvokeBindingRequest) (*BindingEvent, error) {
|
||||
if in == nil {
|
||||
return nil, errors.New("binding invocation required")
|
||||
}
|
||||
|
|
@ -52,14 +53,14 @@ func (c *GRPCClient) InvokeBinding(ctx context.Context, in *InvokeBindingRequest
|
|||
return nil, errors.Wrapf(err, "error invoking binding %s/%s", in.Name, in.Operation)
|
||||
}
|
||||
|
||||
out = &BindingEvent{}
|
||||
|
||||
if resp != nil {
|
||||
out.Data = resp.Data
|
||||
out.Metadata = resp.Metadata
|
||||
return &BindingEvent{
|
||||
Data: resp.Data,
|
||||
Metadata: resp.Metadata,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// InvokeOutputBinding invokes configured Dapr binding with data (allows nil).InvokeOutputBinding
|
||||
|
|
|
|||
|
|
@ -42,5 +42,4 @@ func TestInvokeBinding(t *testing.T) {
|
|||
assert.NotNil(t, out)
|
||||
assert.Equal(t, "test", string(out.Data))
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ const (
|
|||
daprPortDefault = "50001"
|
||||
daprPortEnvVarName = "DAPR_GRPC_PORT"
|
||||
traceparentKey = "traceparent"
|
||||
apiTokenKey = "dapr-api-token"
|
||||
apiTokenEnvVarName = "DAPR_API_TOKEN"
|
||||
apiTokenKey = "dapr-api-token" /* #nosec */
|
||||
apiTokenEnvVarName = "DAPR_API_TOKEN" /* #nosec */
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -175,14 +175,14 @@ func (c *GRPCClient) Close() {
|
|||
}
|
||||
|
||||
// WithAuthToken sets Dapr API token on the instantiated client.
|
||||
// Allows empty string to reset token on existing client
|
||||
// Allows empty string to reset token on existing client.
|
||||
func (c *GRPCClient) WithAuthToken(token string) {
|
||||
c.mux.Lock()
|
||||
c.authToken = token
|
||||
c.mux.Unlock()
|
||||
}
|
||||
|
||||
// WithTraceID adds existing trace ID to the outgoing context
|
||||
// WithTraceID adds existing trace ID to the outgoing context.
|
||||
func (c *GRPCClient) WithTraceID(ctx context.Context, id string) context.Context {
|
||||
if id == "" {
|
||||
return ctx
|
||||
|
|
@ -196,7 +196,7 @@ func (c *GRPCClient) withAuthToken(ctx context.Context) context.Context {
|
|||
if c.authToken == "" {
|
||||
return ctx
|
||||
}
|
||||
return metadata.NewOutgoingContext(ctx, metadata.Pairs(apiTokenKey, string(c.authToken)))
|
||||
return metadata.NewOutgoingContext(ctx, metadata.Pairs(apiTokenKey, c.authToken))
|
||||
}
|
||||
|
||||
// Shutdown the sidecar.
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ const (
|
|||
testBufSize = 1024 * 1024
|
||||
)
|
||||
|
||||
var (
|
||||
testClient Client
|
||||
)
|
||||
var testClient Client
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
ctx := context.Background()
|
||||
|
|
@ -72,7 +70,6 @@ func TestShutdown(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
func getTestClient(ctx context.Context) (client Client, closer func()) {
|
||||
s := grpc.NewServer()
|
||||
pb.RegisterDaprServer(s, &testDaprServer{
|
||||
|
|
@ -233,4 +230,4 @@ func (s *testDaprServer) UnregisterActorTimer(context.Context, *pb.UnregisterAct
|
|||
|
||||
func (s *testDaprServer) Shutdown(ctx context.Context, req *empty.Empty) (*empty.Empty, error) {
|
||||
return &empty.Empty{}, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,14 @@ import (
|
|||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
anypb "github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
)
|
||||
|
||||
// DataContent the service invocation content
|
||||
// DataContent the service invocation content.
|
||||
type DataContent struct {
|
||||
// Data is the input data
|
||||
Data []byte
|
||||
|
|
@ -97,7 +98,7 @@ func (c *GRPCClient) InvokeMethodWithContent(ctx context.Context, appID, methodN
|
|||
}
|
||||
|
||||
// InvokeMethodWithCustomContent invokes service with custom content (struct + content type).
|
||||
func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) (out []byte, err error) {
|
||||
func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) ([]byte, error) {
|
||||
if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil {
|
||||
return nil, errors.Wrap(err, "missing required parameter")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
)
|
||||
|
||||
type _testStructwithText struct {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
)
|
||||
|
||||
// PublishEvent publishes data onto specific pubsub topic.
|
||||
|
|
@ -41,7 +42,6 @@ func (c *GRPCClient) PublishEventfromCustomContent(ctx context.Context, pubsubNa
|
|||
}
|
||||
|
||||
bytes, err := json.Marshal(data)
|
||||
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "error serializing input struct")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package client
|
|||
import (
|
||||
"context"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
)
|
||||
|
||||
// GetSecret retrieves preconfigured secret from specified store using key.
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/golang/protobuf/ptypes/duration"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -31,7 +32,7 @@ const (
|
|||
StateOperationTypeUpsert OperationType = 1
|
||||
// StateOperationTypeDelete represents delete operation type value.
|
||||
StateOperationTypeDelete OperationType = 2
|
||||
// UndefinedType represents undefined type value
|
||||
// UndefinedType represents undefined type value.
|
||||
UndefinedType = "undefined"
|
||||
)
|
||||
|
||||
|
|
@ -44,12 +45,12 @@ type (
|
|||
OperationType int
|
||||
)
|
||||
|
||||
// GetPBConsistency get consistency pb value
|
||||
// GetPBConsistency get consistency pb value.
|
||||
func (s StateConsistency) GetPBConsistency() v1.StateOptions_StateConsistency {
|
||||
return v1.StateOptions_StateConsistency(s)
|
||||
}
|
||||
|
||||
// GetPBConcurrency get concurrency pb value
|
||||
// GetPBConcurrency get concurrency pb value.
|
||||
func (s StateConcurrency) GetPBConcurrency() v1.StateOptions_StateConcurrency {
|
||||
return v1.StateOptions_StateConcurrency(s)
|
||||
}
|
||||
|
|
@ -69,39 +70,37 @@ func (o OperationType) String() string {
|
|||
}
|
||||
|
||||
// String returns the string value of the StateConsistency.
|
||||
func (c StateConsistency) String() string {
|
||||
func (s StateConsistency) String() string {
|
||||
names := [...]string{
|
||||
UndefinedType,
|
||||
"strong",
|
||||
"eventual",
|
||||
}
|
||||
if c < StateConsistencyStrong || c > StateConsistencyEventual {
|
||||
if s < StateConsistencyStrong || s > StateConsistencyEventual {
|
||||
return UndefinedType
|
||||
}
|
||||
|
||||
return names[c]
|
||||
return names[s]
|
||||
}
|
||||
|
||||
// String returns the string value of the StateConcurrency.
|
||||
func (c StateConcurrency) String() string {
|
||||
func (s StateConcurrency) String() string {
|
||||
names := [...]string{
|
||||
UndefinedType,
|
||||
"first-write",
|
||||
"last-write",
|
||||
}
|
||||
if c < StateConcurrencyFirstWrite || c > StateConcurrencyLastWrite {
|
||||
if s < StateConcurrencyFirstWrite || s > StateConcurrencyLastWrite {
|
||||
return UndefinedType
|
||||
}
|
||||
|
||||
return names[c]
|
||||
return names[s]
|
||||
}
|
||||
|
||||
var (
|
||||
stateOptionDefault = &v1.StateOptions{
|
||||
Concurrency: v1.StateOptions_CONCURRENCY_LAST_WRITE,
|
||||
Consistency: v1.StateOptions_CONSISTENCY_STRONG,
|
||||
}
|
||||
)
|
||||
var stateOptionDefault = &v1.StateOptions{
|
||||
Concurrency: v1.StateOptions_CONCURRENCY_LAST_WRITE,
|
||||
Consistency: v1.StateOptions_CONSISTENCY_STRONG,
|
||||
}
|
||||
|
||||
// StateOperation is a collection of StateItems with a store name.
|
||||
type StateOperation struct {
|
||||
|
|
@ -138,7 +137,7 @@ type SetStateItem struct {
|
|||
// DeleteStateItem represents a single state to be deleted.
|
||||
type DeleteStateItem SetStateItem
|
||||
|
||||
// ETag represents an versioned record information
|
||||
// ETag represents an versioned record information.
|
||||
type ETag struct {
|
||||
Value string
|
||||
}
|
||||
|
|
@ -149,17 +148,17 @@ type StateOptions struct {
|
|||
Consistency StateConsistency
|
||||
}
|
||||
|
||||
// StateOption StateOptions's function type
|
||||
// StateOption StateOptions's function type.
|
||||
type StateOption func(*StateOptions)
|
||||
|
||||
// WithConcurrency set StateOptions's Concurrency
|
||||
// WithConcurrency set StateOptions's Concurrency.
|
||||
func WithConcurrency(concurrency StateConcurrency) StateOption {
|
||||
return func(so *StateOptions) {
|
||||
so.Concurrency = concurrency
|
||||
}
|
||||
}
|
||||
|
||||
// WithConsistency set StateOptions's consistency
|
||||
// WithConsistency set StateOptions's consistency.
|
||||
func WithConsistency(consistency StateConsistency) StateOption {
|
||||
return func(so *StateOptions) {
|
||||
so.Consistency = consistency
|
||||
|
|
@ -212,7 +211,7 @@ func toProtoDuration(d time.Duration) *duration.Duration {
|
|||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &duration.Duration{
|
||||
Seconds: int64(secs),
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
||||
|
|
@ -247,9 +246,9 @@ func (c *GRPCClient) ExecuteStateTransaction(ctx context.Context, storeName stri
|
|||
return nil
|
||||
}
|
||||
|
||||
// SaveState saves the raw data into store, default options: strong, last-write
|
||||
// SaveState saves the raw data into store, default options: strong, last-write.
|
||||
func (c *GRPCClient) SaveState(ctx context.Context, storeName, key string, data []byte, so ...StateOption) error {
|
||||
var stateOptions = new(StateOptions)
|
||||
stateOptions := new(StateOptions)
|
||||
for _, o := range so {
|
||||
o(stateOptions)
|
||||
}
|
||||
|
|
@ -332,7 +331,7 @@ func (c *GRPCClient) GetState(ctx context.Context, storeName, key string) (item
|
|||
}
|
||||
|
||||
// GetStateWithConsistency retrieves state from specific store using provided state consistency.
|
||||
func (c *GRPCClient) GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (item *StateItem, err error) {
|
||||
func (c *GRPCClient) GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (*StateItem, error) {
|
||||
if err := hasRequiredStateArgs(storeName, key); err != nil {
|
||||
return nil, errors.Wrap(err, "missing required arguments")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,14 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
testData = "test"
|
||||
testStore = "store"
|
||||
)
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
|
|
@ -19,7 +25,7 @@ func TestTypes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDurationConverter(t *testing.T) {
|
||||
d := time.Duration(10 * time.Second)
|
||||
d := 10 * time.Second
|
||||
pd := toProtoDuration(d)
|
||||
assert.NotNil(t, pd)
|
||||
assert.Equal(t, pd.Seconds, int64(10))
|
||||
|
|
@ -39,8 +45,8 @@ func TestStateOptionsConverter(t *testing.T) {
|
|||
// go test -timeout 30s ./client -count 1 -run ^TestSaveState$
|
||||
func TestSaveState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
data := "test"
|
||||
store := "test"
|
||||
data := testData
|
||||
store := testStore
|
||||
key := "key1"
|
||||
|
||||
t.Run("save data", func(t *testing.T) {
|
||||
|
|
@ -87,8 +93,8 @@ func TestSaveState(t *testing.T) {
|
|||
// go test -timeout 30s ./client -count 1 -run ^TestDeleteState$
|
||||
func TestDeleteState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
data := "test"
|
||||
store := "test"
|
||||
data := testData
|
||||
store := testStore
|
||||
key := "key1"
|
||||
|
||||
t.Run("delete not exist data", func(t *testing.T) {
|
||||
|
|
@ -165,8 +171,8 @@ func TestDeleteState(t *testing.T) {
|
|||
|
||||
func TestDeleteBulkState(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
data := "test"
|
||||
store := "test"
|
||||
data := testData
|
||||
store := testStore
|
||||
keys := []string{"key1", "key2", "key3"}
|
||||
|
||||
t.Run("delete not exist data", func(t *testing.T) {
|
||||
|
|
@ -273,7 +279,7 @@ func TestDeleteBulkState(t *testing.T) {
|
|||
func TestStateTransactions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
data := `{ "message": "test" }`
|
||||
store := "test"
|
||||
store := testStore
|
||||
meta := map[string]string{}
|
||||
keys := []string{"k1", "k2", "k3"}
|
||||
adds := make([]*StateOperation, 0)
|
||||
|
|
@ -341,5 +347,4 @@ func TestStateTransactions(t *testing.T) {
|
|||
assert.NotNil(t, items)
|
||||
assert.Len(t, items, 0)
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package common
|
|||
|
||||
import "context"
|
||||
|
||||
// Service represents Dapr callback service
|
||||
// Service represents Dapr callback service.
|
||||
type Service interface {
|
||||
// AddServiceInvocationHandler appends provided service invocation handler with its name to the service.
|
||||
AddServiceInvocationHandler(name string, fn func(ctx context.Context, in *InvocationEvent) (out *Content, err error)) error
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package common
|
||||
|
||||
// TopicEvent is the content of the inbound topic message
|
||||
// TopicEvent is the content of the inbound topic message.
|
||||
type TopicEvent struct {
|
||||
// ID identifies the event.
|
||||
ID string `json:"id"`
|
||||
|
|
@ -23,7 +23,7 @@ type TopicEvent struct {
|
|||
PubsubName string `json:"pubsubname"`
|
||||
}
|
||||
|
||||
// InvocationEvent represents the input and output of binding invocation
|
||||
// InvocationEvent represents the input and output of binding invocation.
|
||||
type InvocationEvent struct {
|
||||
// Data is the payload that the input bindings sent.
|
||||
Data []byte `json:"data"`
|
||||
|
|
@ -37,7 +37,7 @@ type InvocationEvent struct {
|
|||
QueryString string `json:"-"`
|
||||
}
|
||||
|
||||
// Content is a generic data content
|
||||
// Content is a generic data content.
|
||||
type Content struct {
|
||||
// Data is the payload that the input bindings sent.
|
||||
Data []byte `json:"data"`
|
||||
|
|
@ -47,7 +47,7 @@ type Content struct {
|
|||
DataTypeURL string `json:"typeUrl,omitempty"`
|
||||
}
|
||||
|
||||
// BindingEvent represents the binding event handler input
|
||||
// BindingEvent represents the binding event handler input.
|
||||
type BindingEvent struct {
|
||||
// Data is the input bindings sent
|
||||
Data []byte `json:"data"`
|
||||
|
|
@ -55,7 +55,7 @@ type BindingEvent struct {
|
|||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// Subscription represents single topic subscription
|
||||
// Subscription represents single topic subscription.
|
||||
type Subscription struct {
|
||||
// PubsubName is name of the pub/sub this message came from
|
||||
PubsubName string `json:"pubsubname"`
|
||||
|
|
@ -68,15 +68,15 @@ type Subscription struct {
|
|||
}
|
||||
|
||||
const (
|
||||
// SubscriptionResponseStatusSuccess means message is processed successfully
|
||||
// SubscriptionResponseStatusSuccess means message is processed successfully.
|
||||
SubscriptionResponseStatusSuccess = "SUCCESS"
|
||||
// SubscriptionResponseStatusRetry means message to be retried by Dapr
|
||||
// SubscriptionResponseStatusRetry means message to be retried by Dapr.
|
||||
SubscriptionResponseStatusRetry = "RETRY"
|
||||
// SubscriptionResponseStatusDrop means warning is logged and message is dropped
|
||||
// SubscriptionResponseStatusDrop means warning is logged and message is dropped.
|
||||
SubscriptionResponseStatusDrop = "DROP"
|
||||
)
|
||||
|
||||
// SubscriptionResponse represents the response handling hint from subscriber to Dapr
|
||||
// SubscriptionResponse represents the response handling hint from subscriber to Dapr.
|
||||
type SubscriptionResponse struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// AddBindingInvocationHandler appends provided binding invocation handler with its name to the service
|
||||
// AddBindingInvocationHandler appends provided binding invocation handler with its name to the service.
|
||||
func (s *Server) AddBindingInvocationHandler(name string, fn func(ctx context.Context, in *common.BindingEvent) (out []byte, err error)) error {
|
||||
if name == "" {
|
||||
return fmt.Errorf("binding name required")
|
||||
|
|
@ -23,7 +24,7 @@ func (s *Server) AddBindingInvocationHandler(name string, fn func(ctx context.Co
|
|||
}
|
||||
|
||||
// ListInputBindings is called by Dapr to get the list of bindings the app will get invoked by. In this example, we are telling Dapr
|
||||
// To invoke our app with a binding named storage
|
||||
// To invoke our app with a binding named storage.
|
||||
func (s *Server) ListInputBindings(ctx context.Context, in *empty.Empty) (*pb.ListInputBindingsResponse, error) {
|
||||
list := make([]string, 0)
|
||||
for k := range s.bindingHandlers {
|
||||
|
|
@ -35,7 +36,7 @@ func (s *Server) ListInputBindings(ctx context.Context, in *empty.Empty) (*pb.Li
|
|||
}, nil
|
||||
}
|
||||
|
||||
// OnBindingEvent gets invoked every time a new event is fired from a registered binding. The message carries the binding name, a payload and optional metadata
|
||||
// OnBindingEvent gets invoked every time a new event is fired from a registered binding. The message carries the binding name, a payload and optional metadata.
|
||||
func (s *Server) OnBindingEvent(ctx context.Context, in *pb.BindingEventRequest) (*pb.BindingEventResponse, error) {
|
||||
if in == nil {
|
||||
return nil, errors.New("nil binding event request")
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func testBindingHandler(ctx context.Context, in *common.BindingEvent) (out []byte, err error) {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
cpb "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
cc "github.com/dapr/go-sdk/service/common"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
cpb "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
cc "github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// AddServiceInvocationHandler appends provided service invocation handler with its method to the service
|
||||
// AddServiceInvocationHandler appends provided service invocation handler with its method to the service.
|
||||
func (s *Server) AddServiceInvocationHandler(method string, fn func(ctx context.Context, in *cc.InvocationEvent) (our *cc.Content, err error)) error {
|
||||
if method == "" {
|
||||
return fmt.Errorf("servie name required")
|
||||
|
|
@ -22,7 +23,7 @@ func (s *Server) AddServiceInvocationHandler(method string, fn func(ctx context.
|
|||
return nil
|
||||
}
|
||||
|
||||
// OnInvoke gets invoked when a remote service has called the app through Dapr
|
||||
// OnInvoke gets invoked when a remote service has called the app through Dapr.
|
||||
func (s *Server) OnInvoke(ctx context.Context, in *cpb.InvokeRequest) (*cpb.InvokeResponse, error) {
|
||||
if in == nil {
|
||||
return nil, errors.New("nil invoke request")
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
cc "github.com/dapr/go-sdk/service/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
cc "github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func testInvokeHandler(ctx context.Context, in *cc.InvocationEvent) (out *cc.Content, err error) {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// NewService creates new Service.
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// AddTopicEventHandler appends provided event handler with topic name to the service
|
||||
// AddTopicEventHandler appends provided event handler with topic name to the service.
|
||||
func (s *Server) AddTopicEventHandler(sub *common.Subscription, fn func(ctx context.Context, e *common.TopicEvent) (retry bool, err error)) error {
|
||||
if sub == nil {
|
||||
return errors.New("subscription required")
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func TestTopicErrors(t *testing.T) {
|
||||
|
|
@ -65,7 +66,7 @@ func TestTopic(t *testing.T) {
|
|||
|
||||
t.Run("topic event for wrong topic", func(t *testing.T) {
|
||||
in := &runtime.TopicEventRequest{
|
||||
Topic: "invlid",
|
||||
Topic: "invalid",
|
||||
}
|
||||
_, err := server.OnTopicEvent(ctx, in)
|
||||
assert.Error(t, err)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// AddBindingInvocationHandler appends provided binding invocation handler with its route to the service
|
||||
// AddBindingInvocationHandler appends provided binding invocation handler with its route to the service.
|
||||
func (s *Server) AddBindingInvocationHandler(route string, fn func(ctx context.Context, in *common.BindingEvent) (out []byte, err error)) error {
|
||||
if route == "" {
|
||||
return fmt.Errorf("binding route required")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func TestBindingHandlerWithoutHandler(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// AddServiceInvocationHandler appends provided service invocation handler with its route to the service
|
||||
// AddServiceInvocationHandler appends provided service invocation handler with its route to the service.
|
||||
func (s *Server) AddServiceInvocationHandler(route string, fn func(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error)) error {
|
||||
if route == "" {
|
||||
return fmt.Errorf("service route required")
|
||||
|
|
@ -63,5 +63,3 @@ func (s *Server) AddServiceInvocationHandler(route string, fn func(ctx context.C
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func TestInvocationHandlerWithoutHandler(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import (
|
|||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
// NewService creates new Service
|
||||
// NewService creates new Service.
|
||||
func NewService(address string) common.Service {
|
||||
return newServer(address, nil)
|
||||
}
|
||||
|
||||
// NewServiceWithMux creates new Service with existing http mux
|
||||
// NewServiceWithMux creates new Service with existing http mux.
|
||||
func NewServiceWithMux(address string, mux *http.ServeMux) common.Service {
|
||||
return newServer(address, mux)
|
||||
}
|
||||
|
|
@ -27,14 +27,14 @@ func newServer(address string, mux *http.ServeMux) *Server {
|
|||
}
|
||||
}
|
||||
|
||||
// Server is the HTTP server wrapping mux many Dapr helpers
|
||||
// Server is the HTTP server wrapping mux many Dapr helpers.
|
||||
type Server struct {
|
||||
address string
|
||||
mux *http.ServeMux
|
||||
topicSubscriptions []*common.Subscription
|
||||
}
|
||||
|
||||
// Start starts the HTTP handler. Blocks while serving
|
||||
// Start starts the HTTP handler. Blocks while serving.
|
||||
func (s *Server) Start() error {
|
||||
s.registerSubscribeHandler()
|
||||
server := http.Server{
|
||||
|
|
@ -44,7 +44,7 @@ func (s *Server) Start() error {
|
|||
return server.ListenAndServe()
|
||||
}
|
||||
|
||||
// Stop stops previously started HTTP service
|
||||
// Stop stops previously started HTTP service.
|
||||
func (s *Server) Stop() error {
|
||||
// TODO: implement service stop
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ func TestSettingOptions(t *testing.T) {
|
|||
w := httptest.NewRecorder()
|
||||
setOptions(w, req)
|
||||
resp := w.Result()
|
||||
defer resp.Body.Close()
|
||||
assert.NotNil(t, resp)
|
||||
assert.Equal(t, "*", resp.Header.Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Access-Control-Allow-Methods"))
|
||||
|
|
@ -31,7 +32,8 @@ func TestSettingOptions(t *testing.T) {
|
|||
func testRequest(t *testing.T, s *Server, r *http.Request, expectedStatusCode int) {
|
||||
rr := httptest.NewRecorder()
|
||||
s.mux.ServeHTTP(rr, r)
|
||||
rez := rr.Result()
|
||||
assert.NotNil(t, rez)
|
||||
assert.Equal(t, expectedStatusCode, rez.StatusCode)
|
||||
resp := rr.Result()
|
||||
defer resp.Body.Close()
|
||||
assert.NotNil(t, resp)
|
||||
assert.Equal(t, expectedStatusCode, resp.StatusCode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// PubSubHandlerSuccessStatusCode is the successful ack code for pubsub event appcallback response
|
||||
// PubSubHandlerSuccessStatusCode is the successful ack code for pubsub event appcallback response.
|
||||
PubSubHandlerSuccessStatusCode int = http.StatusOK
|
||||
|
||||
// PubSubHandlerRetryStatusCode is the error response code (nack) pubsub event appcallback response
|
||||
// PubSubHandlerRetryStatusCode is the error response code (nack) pubsub event appcallback response.
|
||||
PubSubHandlerRetryStatusCode int = http.StatusInternalServerError
|
||||
|
||||
// PubSubHandlerDropStatusCode is the pubsub event appcallback response code indicating that Dapr should drop that message
|
||||
// PubSubHandlerDropStatusCode is the pubsub event appcallback response code indicating that Dapr should drop that message.
|
||||
PubSubHandlerDropStatusCode int = http.StatusSeeOther
|
||||
)
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ func (s *Server) registerSubscribeHandler() {
|
|||
s.mux.HandleFunc("/dapr/subscribe", f)
|
||||
}
|
||||
|
||||
// AddTopicEventHandler appends provided event handler with it's name to the service
|
||||
// AddTopicEventHandler appends provided event handler with it's name to the service.
|
||||
func (s *Server) AddTopicEventHandler(sub *common.Subscription, fn func(ctx context.Context, e *common.TopicEvent) (retry bool, err error)) error {
|
||||
if sub == nil {
|
||||
return errors.New("subscription required")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
)
|
||||
|
||||
func testTopicFunc(ctx context.Context, e *common.TopicEvent) (retry bool, err error) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue