ci: standard linter config (#199)

Signed-off-by: Long <long0dai@foxmail.com>
This commit is contained in:
Long Dai 2021-09-23 02:02:52 +08:00 committed by GitHub
parent 994f9b69f2
commit de5cf935fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 387 additions and 116 deletions

View File

@ -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 }}

255
.golangci.yml Normal file
View File

@ -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

View File

@ -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

View File

@ -42,5 +42,4 @@ func TestInvokeBinding(t *testing.T) {
assert.NotNil(t, out)
assert.Equal(t, "test", string(out.Data))
})
}

View File

@ -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.

View File

@ -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
}
}

View File

@ -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")
}

View File

@ -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 {

View File

@ -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")
}

View File

@ -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.

View File

@ -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")
}

View File

@ -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
service/common/service.go Executable file → Normal file
View File

@ -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

18
service/common/type.go Executable file → Normal file
View File

@ -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"`
}

View File

@ -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")

View File

@ -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) {

View File

@ -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")

View File

@ -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) {

View File

@ -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.

View File

@ -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")

View File

@ -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)

2
service/http/binding.go Executable file → Normal file
View File

@ -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")

3
service/http/binding_test.go Executable file → Normal file
View File

@ -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) {

4
service/http/invoke.go Executable file → Normal file
View File

@ -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
}

3
service/http/invoke_test.go Executable file → Normal file
View File

@ -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) {

10
service/http/service.go Executable file → Normal file
View File

@ -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

View File

@ -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)
}

8
service/http/topic.go Executable file → Normal file
View File

@ -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")

3
service/http/topic_test.go Executable file → Normal file
View File

@ -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) {