diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..e43646e --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,60 @@ +run: + tests: false + skip-dirs: + - "mocks" +issues: + exclude-rules: + - path: internal/events/test_helper.go + text: "unused" +linters-settings: + golint: {} + gocritic: + enabled-checks: [] + disabled-checks: + - regexpMust + goheader: + values: + regexp: + COMPANY: .* + template: |- + Copyright © {{ YEAR }} {{ COMPANY }} + + SPDX-License-Identifier: Apache-2.0 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +linters: + disable-all: false + disable: + - structcheck + enable: + - dogsled + - errcheck + - goconst + - gocritic + - gocyclo + - gofmt + - goheader + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - revive + - staticcheck + - stylecheck + - typecheck + - unconvert + - unused \ No newline at end of file diff --git a/Makefile b/Makefile index 0e961ee..7d119b3 100644 --- a/Makefile +++ b/Makefile @@ -45,11 +45,11 @@ mocks: mockery ${GOFILES} ${MOCKERY} --case underscore --dir internal/fabric/dep --name CAClient --output mocks/fabric/dep --outpkg mockfabricdep ${MOCKERY} --case underscore --dir internal/kvstore --name KVStore --output mocks/kvstore --outpkg mockkvstore ${MOCKERY} --case underscore --dir internal/kvstore --name KVIterator --output mocks/kvstore --outpkg mockkvstore - ${MOCKERY} --case underscore --dir internal/rest/async --name AsyncDispatcher --output mocks/rest/async --outpkg mockasync - ${MOCKERY} --case underscore --dir internal/rest/identity --name IdentityClient --output mocks/rest/identity --outpkg mockidentity - ${MOCKERY} --case underscore --dir internal/rest/receipt --name ReceiptStore --output mocks/rest/receipt --outpkg mockreceipt + ${MOCKERY} --case underscore --dir internal/rest/async --name Dispatcher --output mocks/rest/async --outpkg mockasync + ${MOCKERY} --case underscore --dir internal/rest/identity --name Client --output mocks/rest/identity --outpkg mockidentity + ${MOCKERY} --case underscore --dir internal/rest/receipt --name Store --output mocks/rest/receipt --outpkg mockreceipt ${MOCKERY} --case underscore --dir internal/rest/receipt/api --name ReceiptStorePersistence --output mocks/rest/receipt/api --outpkg mockreceiptapi - ${MOCKERY} --case underscore --dir internal/rest/sync --name SyncDispatcher --output mocks/rest/sync --outpkg mocksync - ${MOCKERY} --case underscore --dir internal/tx --name TxProcessor --output mocks/tx --outpkg mocktx + ${MOCKERY} --case underscore --dir internal/rest/sync --name Dispatcher --output mocks/rest/sync --outpkg mocksync + ${MOCKERY} --case underscore --dir internal/tx --name Processor --output mocks/tx --outpkg mocktx ${MOCKERY} --case underscore --dir internal/ws --name WebSocketServer --output mocks/ws --outpkg mockws ${MOCKERY} --case underscore --dir internal/ws --name WebSocketChannels --output mocks/ws --outpkg mockws diff --git a/cmd/debugrouter.go b/cmd/debugrouter.go index 65d1d14..473f97b 100644 --- a/cmd/debugrouter.go +++ b/cmd/debugrouter.go @@ -1,3 +1,19 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package cmd import ( @@ -10,19 +26,19 @@ import ( log "github.com/sirupsen/logrus" ) -type debugRouter struct { +type DebugRouter struct { router *httprouter.Router } -func NewDebugRouter() *debugRouter { +func NewDebugRouter() *DebugRouter { r := httprouter.New() cors.Default().Handler(r) - return &debugRouter{ + return &DebugRouter{ router: r, } } -func (d *debugRouter) addRoutes() { +func (d *DebugRouter) addRoutes() { d.router.GET("/debug/pprof/cmdline", d.cmdline) d.router.GET("/debug/pprof/profile", d.profile) d.router.GET("/debug/pprof/symbol", d.symbol) @@ -31,35 +47,35 @@ func (d *debugRouter) addRoutes() { d.router.GET("/debug/pprof/", d.index) } -func (d *debugRouter) cmdline(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) cmdline(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) pprof.Cmdline(res, req) } -func (d *debugRouter) profile(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) profile(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) pprof.Profile(res, req) } -func (d *debugRouter) symbol(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) symbol(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) pprof.Symbol(res, req) } -func (d *debugRouter) trace(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) trace(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) pprof.Trace(res, req) } -func (d *debugRouter) index(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) index(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) pprof.Index(res, req) } -func (d *debugRouter) goroutines(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *DebugRouter) goroutines(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) _ = runtimepprof.Lookup("goroutine").WriteTo(res, 1) diff --git a/cmd/fabconnect.go b/cmd/fabconnect.go index 1983a28..0e3c328 100644 --- a/cmd/fabconnect.go +++ b/cmd/fabconnect.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -23,7 +23,7 @@ import ( "strings" "time" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" "github.com/hyperledger/firefly-fabconnect/internal/conf" "github.com/hyperledger/firefly-fabconnect/internal/rest" @@ -31,8 +31,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" prefixed "github.com/x-cray/logrus-prefixed-formatter" - - _ "net/http/pprof" ) func initLogging(debugLevel int) { @@ -68,7 +66,7 @@ var rootConfig = &cmdConfig{} func newRootCmd() (*cobra.Command, *conf.RESTGatewayConf) { restGatewayConf := &conf.RESTGatewayConf{} - var restGateway *rest.RESTGateway + var restGateway *rest.Gateway rootCmd := &cobra.Command{ Use: "fabconnect", @@ -151,7 +149,7 @@ func initConfig() { } } -func startServer(restGatewayConf *conf.RESTGatewayConf, restGateway *rest.RESTGateway) error { +func startServer(restGatewayConf *conf.RESTGatewayConf, restGateway *rest.Gateway) error { if rootConfig.PrintYAML { a, err := marshalToYAML(rootConfig) diff --git a/internal/auth/auth.go b/internal/auth/auth.go index ae6bfc4..f556946 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ package auth import ( "context" - "github.com/hyperledger/firefly-fabconnect/internal/errors" + internalErrors "github.com/hyperledger/firefly-fabconnect/internal/errors" "github.com/hyperledger/firefly-fabconnect/pkg/plugins" ) @@ -77,60 +77,60 @@ func GetAccessToken(ctx context.Context) string { return "" } -// AuthRPC authorize an RPC call -func AuthRPC(ctx context.Context, method string, args ...interface{}) error { +// RPC authorize an RPC call +func RPC(ctx context.Context, method string, args ...interface{}) error { if securityModule != nil && !IsSystemContext(ctx) { authCtx := GetAuthContext(ctx) if authCtx == nil { - return errors.Errorf(errors.SecurityModuleNoAuthContext) + return internalErrors.Errorf(internalErrors.SecurityModuleNoAuthContext) } return securityModule.AuthRPC(authCtx, method, args...) } return nil } -// AuthRPCSubscribe authorize a subscribe RPC call -func AuthRPCSubscribe(ctx context.Context, namespace string, channel interface{}, args ...interface{}) error { +// RPCSubscribe authorize a subscribe RPC call +func RPCSubscribe(ctx context.Context, namespace string, channel interface{}, args ...interface{}) error { if securityModule != nil && !IsSystemContext(ctx) { authCtx := GetAuthContext(ctx) if authCtx == nil { - return errors.Errorf(errors.SecurityModuleNoAuthContext) + return internalErrors.Errorf(internalErrors.SecurityModuleNoAuthContext) } return securityModule.AuthRPCSubscribe(authCtx, namespace, channel, args...) } return nil } -// AuthEventStreams authorize the whole of event streams -func AuthEventStreams(ctx context.Context) error { +// EventStreams authorize the whole of event streams +func EventStreams(ctx context.Context) error { if securityModule != nil && !IsSystemContext(ctx) { authCtx := GetAuthContext(ctx) if authCtx == nil { - return errors.Errorf(errors.SecurityModuleNoAuthContext) + return internalErrors.Errorf(internalErrors.SecurityModuleNoAuthContext) } return securityModule.AuthEventStreams(authCtx) } return nil } -// AuthListAsyncReplies authorize the listing or searching of all replies -func AuthListAsyncReplies(ctx context.Context) error { +// ListAsyncReplies authorize the listing or searching of all replies +func ListAsyncReplies(ctx context.Context) error { if securityModule != nil && !IsSystemContext(ctx) { authCtx := GetAuthContext(ctx) if authCtx == nil { - return errors.Errorf(errors.SecurityModuleNoAuthContext) + return internalErrors.Errorf(internalErrors.SecurityModuleNoAuthContext) } return securityModule.AuthListAsyncReplies(authCtx) } return nil } -// AuthReadAsyncReplyByUUID authorize the query of an invidual reply by UUID -func AuthReadAsyncReplyByUUID(ctx context.Context) error { +// ReadAsyncReplyByUUID authorize the query of an invidual reply by UUID +func ReadAsyncReplyByUUID(ctx context.Context) error { if securityModule != nil && !IsSystemContext(ctx) { authCtx := GetAuthContext(ctx) if authCtx == nil { - return errors.Errorf(errors.SecurityModuleNoAuthContext) + return internalErrors.Errorf(internalErrors.SecurityModuleNoAuthContext) } return securityModule.AuthReadAsyncReplyByUUID(authCtx) } diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 039468a..eeece40 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -61,17 +61,17 @@ func TestAccessToken(t *testing.T) { func TestAuthRPC(t *testing.T) { assert := assert.New(t) - assert.NoError(AuthRPC(context.Background(), "anything")) + assert.NoError(RPC(context.Background(), "anything")) RegisterSecurityModule(&authtest.TestSecurityModule{}) - assert.EqualError(AuthRPC(context.Background(), "anything"), "No auth context") + assert.EqualError(RPC(context.Background(), "anything"), "No auth context") - assert.NoError(AuthRPC(NewSystemAuthContext(), "anything")) + assert.NoError(RPC(NewSystemAuthContext(), "anything")) ctx, _ := WithAuthContext(context.Background(), "testat") - assert.NoError(AuthRPC(ctx, "testrpc")) - assert.EqualError(AuthRPC(ctx, "anything"), "badness") + assert.NoError(RPC(ctx, "testrpc")) + assert.EqualError(RPC(ctx, "anything"), "badness") RegisterSecurityModule(nil) @@ -80,17 +80,17 @@ func TestAuthRPC(t *testing.T) { func TestAuthRPCSubscribe(t *testing.T) { assert := assert.New(t) - assert.NoError(AuthRPCSubscribe(context.Background(), "anything", nil)) + assert.NoError(RPCSubscribe(context.Background(), "anything", nil)) RegisterSecurityModule(&authtest.TestSecurityModule{}) - assert.EqualError(AuthRPCSubscribe(context.Background(), "anything", nil), "No auth context") + assert.EqualError(RPCSubscribe(context.Background(), "anything", nil), "No auth context") - assert.NoError(AuthRPCSubscribe(NewSystemAuthContext(), "anything", nil)) + assert.NoError(RPCSubscribe(NewSystemAuthContext(), "anything", nil)) ctx, _ := WithAuthContext(context.Background(), "testat") - assert.NoError(AuthRPCSubscribe(ctx, "testns", nil)) - assert.EqualError(AuthRPCSubscribe(ctx, "anything", nil), "badness") + assert.NoError(RPCSubscribe(ctx, "testns", nil)) + assert.EqualError(RPCSubscribe(ctx, "anything", nil), "badness") RegisterSecurityModule(nil) @@ -99,16 +99,16 @@ func TestAuthRPCSubscribe(t *testing.T) { func TestAuthEventStreams(t *testing.T) { assert := assert.New(t) - assert.NoError(AuthEventStreams(context.Background())) + assert.NoError(EventStreams(context.Background())) RegisterSecurityModule(&authtest.TestSecurityModule{}) - assert.EqualError(AuthEventStreams(context.Background()), "No auth context") + assert.EqualError(EventStreams(context.Background()), "No auth context") - assert.NoError(AuthEventStreams(NewSystemAuthContext())) + assert.NoError(EventStreams(NewSystemAuthContext())) ctx, _ := WithAuthContext(context.Background(), "testat") - assert.NoError(AuthEventStreams(ctx)) + assert.NoError(EventStreams(ctx)) RegisterSecurityModule(nil) @@ -117,16 +117,16 @@ func TestAuthEventStreams(t *testing.T) { func TestAuthListAsyncReplies(t *testing.T) { assert := assert.New(t) - assert.NoError(AuthListAsyncReplies(context.Background())) + assert.NoError(ListAsyncReplies(context.Background())) RegisterSecurityModule(&authtest.TestSecurityModule{}) - assert.EqualError(AuthListAsyncReplies(context.Background()), "No auth context") + assert.EqualError(ListAsyncReplies(context.Background()), "No auth context") - assert.NoError(AuthListAsyncReplies(NewSystemAuthContext())) + assert.NoError(ListAsyncReplies(NewSystemAuthContext())) ctx, _ := WithAuthContext(context.Background(), "testat") - assert.NoError(AuthListAsyncReplies(ctx)) + assert.NoError(ListAsyncReplies(ctx)) RegisterSecurityModule(nil) @@ -135,16 +135,16 @@ func TestAuthListAsyncReplies(t *testing.T) { func TestAuthReadAsyncReplyByUUID(t *testing.T) { assert := assert.New(t) - assert.NoError(AuthReadAsyncReplyByUUID(context.Background())) + assert.NoError(ReadAsyncReplyByUUID(context.Background())) RegisterSecurityModule(&authtest.TestSecurityModule{}) - assert.EqualError(AuthReadAsyncReplyByUUID(context.Background()), "No auth context") + assert.EqualError(ReadAsyncReplyByUUID(context.Background()), "No auth context") - assert.NoError(AuthReadAsyncReplyByUUID(NewSystemAuthContext())) + assert.NoError(ReadAsyncReplyByUUID(NewSystemAuthContext())) ctx, _ := WithAuthContext(context.Background(), "testat") - assert.NoError(AuthReadAsyncReplyByUUID(ctx)) + assert.NoError(ReadAsyncReplyByUUID(ctx)) RegisterSecurityModule(nil) diff --git a/internal/auth/authtest/testsm.go b/internal/auth/authtest/testsm.go index 1781b8e..054217f 100644 --- a/internal/auth/authtest/testsm.go +++ b/internal/auth/authtest/testsm.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -32,23 +32,25 @@ func (sm *TestSecurityModule) VerifyToken(tok string) (interface{}, error) { } // AuthRPC of TEST MODULE checks if a token matches a fixed string -func (sm *TestSecurityModule) AuthRPC(authCtx interface{}, method string, args ...interface{}) error { +func (sm *TestSecurityModule) AuthRPC(authCtx interface{}, method string, _ ...interface{}) error { switch authCtx.(type) { case string: if method == "testrpc" { return nil } + default: } return fmt.Errorf("badness") } // AuthRPCSubscribe of TEST MODULE checks if a namespace matches a fixed string -func (sm *TestSecurityModule) AuthRPCSubscribe(authCtx interface{}, namespace string, channel interface{}, args ...interface{}) error { +func (sm *TestSecurityModule) AuthRPCSubscribe(authCtx interface{}, namespace string, _ interface{}, _ ...interface{}) error { switch authCtx.(type) { case string: if namespace == "testns" { return nil } + default: } return fmt.Errorf("badness") } @@ -58,6 +60,7 @@ func (sm *TestSecurityModule) AuthEventStreams(authCtx interface{}) error { switch authCtx.(type) { case string: return nil + default: } return fmt.Errorf("badness") } @@ -67,6 +70,7 @@ func (sm *TestSecurityModule) AuthListAsyncReplies(authCtx interface{}) error { switch authCtx.(type) { case string: return nil + default: } return fmt.Errorf("badness") } @@ -76,6 +80,7 @@ func (sm *TestSecurityModule) AuthReadAsyncReplyByUUID(authCtx interface{}) erro switch authCtx.(type) { case string: return nil + default: } return fmt.Errorf("badness") } diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 9a33656..22f452d 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -158,7 +158,7 @@ const ( // LevelDBFailedRetriveOriginalKey problem retrieving entry - original key LevelDBFailedRetriveOriginalKey = "Failed to retrieve the entry for the original key: %s. %s" // LevelDBFailedRetriveGeneratedID problem retrieving entry - generated ID - LevelDBFailedRetriveGeneratedID = "Failed to retrieve the entry for the generated ID: %s. %s" + LevelDBFailedRetriveGeneratedID = "failed to retrieve the entry for the generated ID: %s. %s" // KVStoreDBLoad failed to init DB KVStoreDBLoad = "Failed to open DB at %s: %s" diff --git a/internal/events/api/event.go b/internal/events/api/event.go index 00442aa..e6115cf 100644 --- a/internal/events/api/event.go +++ b/internal/events/api/event.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,25 +19,27 @@ package api import "fmt" const ( - BlockType_TX = "tx" // corresponds to blocks containing regular transactions - BlockType_Config = "config" // corresponds to blocks containing channel configurations and updates - EventPayloadType_Bytes = "bytes" // default data type of the event payload, no special processing is done before returning to the subscribing client - EventPayloadType_String = "string" // event payload will be an UTF-8 encoded string - EventPayloadType_JSON = "json" // event payload will be a structured map with UTF-8 encoded string values - EventPayloadType_StringifiedJSON = "stringifiedJSON" // equivalent to "json" (deprecated) + BlockTypeTX = "tx" // corresponds to blocks containing regular transactions + BlockTypeConfig = "config" // corresponds to blocks containing channel configurations and updates + EventPayloadTypeBytes = "bytes" // default data type of the event payload, no special processing is done before returning to the subscribing client + EventPayloadTypeString = "string" // event payload will be an UTF-8 encoded string + EventPayloadTypeJSON = "json" // event payload will be a structured map with UTF-8 encoded string values + EventPayloadTypeStringifiedJSON = "stringifiedJSON" // equivalent to "json" (deprecated) ) // persistedFilter is the part of the filter we record to storage // BlockType: optional. only notify on blocks of a specific type -// types are defined in github.com/hyperledger/fabric-protos-go/common: -// "config": for HeaderType_CONFIG, HeaderType_CONFIG_UPDATE -// "tx": for HeaderType_ENDORSER_TRANSACTION -// ChaincodeId: optional, only notify on blocks containing events for chaincode Id +// +// types are defined in github.com/hyperledger/fabric-protos-go/common: +// "config": for HeaderType_CONFIG, HeaderType_CONFIG_UPDATE +// "tx": for HeaderType_ENDORSER_TRANSACTION +// +// ChaincodeID: optional, only notify on blocks containing events for chaincode Id // Filter: optional. regexp applied to the event name. can be used independent of Chaincode ID // FromBlock: optional. "newest", "oldest", a number. default is "newest" type persistedFilter struct { BlockType string `json:"blockType,omitempty"` - ChaincodeId string `json:"chaincodeId,omitempty"` + ChaincodeID string `json:"chaincodeId,omitempty"` EventFilter string `json:"eventFilter,omitempty"` } @@ -45,7 +47,7 @@ type persistedFilter struct { type SubscriptionInfo struct { TimeSorted ID string `json:"id,omitempty"` - ChannelId string `json:"channel,omitempty"` + ChannelID string `json:"channel,omitempty"` Path string `json:"path"` Summary string `json:"-"` // System generated name for the subscription Name string `json:"name"` // User provided name for the subscription, set to Summary if missing @@ -62,9 +64,9 @@ func (info *SubscriptionInfo) GetID() string { } type EventEntry struct { - ChaincodeId string `json:"chaincodeId"` + ChaincodeID string `json:"chaincodeId"` BlockNumber uint64 `json:"blockNumber"` - TransactionId string `json:"transactionId"` + TransactionID string `json:"transactionId"` TransactionIndex int `json:"transactionIndex"` EventIndex int `json:"eventIndex"` EventName string `json:"eventName"` @@ -73,10 +75,10 @@ type EventEntry struct { SubID string `json:"subId"` } -func GetKeyForEventClient(channelId string, chaincodeId string) string { - // key for a unique event client is - +func GetKeyForEventClient(channelID string, chaincodeID string) string { + // key for a unique event client is - // note that we don't allow "fromBlock" to be a key segment, because on restart // the "fromBlock" will be set to the checkpoint which will be the same, thus failing // to differentiate unique event clients - return fmt.Sprintf("%s-%s", channelId, chaincodeId) + return fmt.Sprintf("%s-%s", channelID, chaincodeID) } diff --git a/internal/events/eventstream.go b/internal/events/eventstream.go index 8dfff63..36061db 100644 --- a/internal/events/eventstream.go +++ b/internal/events/eventstream.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -310,7 +310,7 @@ func (a *eventStream) handleEvent(event *eventData) { // Does nothing more than add it to the batch, to be picked up // by the batchDispatcher if a.stopped { - log.Infof("Event stream stopped, skipping event %s for transaction %s", event.event.EventName, event.event.TransactionId) + log.Infof("Event stream stopped, skipping event %s for transaction %s", event.event.EventName, event.event.TransactionID) } else { a.eventStream <- event } @@ -364,7 +364,7 @@ func (a *eventStream) isBlocked() bool { return v } -func (a *eventStream) markAllSubscriptionsStale(ctx context.Context) { +func (a *eventStream) markAllSubscriptionsStale(_ context.Context) { // Mark all subscriptions stale, so they will re-start from the checkpoint if/when we re-run the poller subs := a.sm.subscriptionsForStream(a.spec.ID) for _, sub := range subs { @@ -442,7 +442,7 @@ func (a *eventStream) eventPoller() { log.Infof("%s: Notified of an ongoing stream update, exiting event poller", a.spec.ID) a.markAllSubscriptionsStale(ctx) return - case <-time.After(a.pollingInterval): //fall through and continue to the next iteration + case <-time.After(a.pollingInterval): // fall through and continue to the next iteration } } @@ -540,12 +540,11 @@ func (a *eventStream) batchProcessor() { <-a.updateInterrupt // we were notified by the caller about an ongoing update, return log.Infof("%s: Notified of an ongoing stream update, exiting batch processor", a.spec.ID) - a.updateWG.Done() //Not moving this to a 'defer' since we need to unlock after calling Done() + a.updateWG.Done() // Not moving this to a 'defer' since we need to unlock after calling Done() a.batchCond.L.Unlock() return - } else { - a.batchCond.Wait() } + a.batchCond.Wait() } if a.suspendOrStop() { log.Infof("%s: Suspended, returning exiting batch processor", a.spec.ID) @@ -582,7 +581,7 @@ func (a *eventStream) processBatch(batchNumber uint64, events []*eventData) { // we were notified by the caller about an ongoing update, no need to continue log.Infof("%s: Notified of an ongoing stream update, terminating process batch", a.spec.ID) return - case <-time.After(time.Duration(a.spec.BlockedRetryDelaySec) * time.Second): //fall through and continue + case <-time.After(time.Duration(a.spec.BlockedRetryDelaySec) * time.Second): // fall through and continue } } attempt++ @@ -645,7 +644,7 @@ func (a *eventStream) performActionWithRetry(batchNumber uint64, events []*event // we were notified by the caller about an ongoing update, no need to continue log.Infof("%s: Notified of an ongoing stream update, terminating perform action for batch number: %d", a.spec.ID, batchNumber) return - case <-time.After(delay): //fall through and continue + case <-time.After(delay): // fall through and continue } delay = time.Duration(float64(delay) * a.backoffFactor) } diff --git a/internal/events/evtprocessor.go b/internal/events/evtprocessor.go index f1fc531..1f14668 100644 --- a/internal/events/evtprocessor.go +++ b/internal/events/evtprocessor.go @@ -1,11 +1,13 @@ -// Copyright 2021 Kaleido - +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -68,15 +70,15 @@ func (ep *evtProcessor) processEventEntry(subInfo *api.SubscriptionInfo, entry * entry.SubID = subInfo.ID payloadType := subInfo.PayloadType if payloadType == "" { - payloadType = api.EventPayloadType_Bytes + payloadType = api.EventPayloadTypeBytes } payloadBytes, ok := entry.Payload.([]byte) if ok { switch payloadType { - case api.EventPayloadType_String: + case api.EventPayloadTypeString: entry.Payload = string(payloadBytes) - case api.EventPayloadType_StringifiedJSON, api.EventPayloadType_JSON: + case api.EventPayloadTypeStringifiedJSON, api.EventPayloadTypeJSON: structuredMap := make(map[string]interface{}) err := json.Unmarshal(payloadBytes, &structuredMap) if err != nil { @@ -93,7 +95,7 @@ func (ep *evtProcessor) processEventEntry(subInfo *api.SubscriptionInfo, entry * } // Ok, now we have the full event in a friendly map output. Pass it down to the stream - log.Infof("%s: Dispatching event. BlockNumber=%d TxId=%s", subInfo.ID, result.event.BlockNumber, result.event.TransactionId) + log.Infof("%s: Dispatching event. BlockNumber=%d TxId=%s", subInfo.ID, result.event.BlockNumber, result.event.TransactionID) ep.stream.eventHandler(&result) return nil } diff --git a/internal/events/evtprocessor_test.go b/internal/events/evtprocessor_test.go index bcc937c..993d78a 100644 --- a/internal/events/evtprocessor_test.go +++ b/internal/events/evtprocessor_test.go @@ -39,7 +39,7 @@ func TestEventPayloadUnmarshaling(t *testing.T) { p := newEvtProcessor("abc", stream) subInfo := &api.SubscriptionInfo{ ID: "abc", - PayloadType: api.EventPayloadType_StringifiedJSON, + PayloadType: api.EventPayloadTypeStringifiedJSON, } jsonstring := "{\"ID\":\"asset1072\",\"color\":\"yellow\",\"size\":10,\"owner\":\"Tom\",\"appraisedValue\":1300}" entry := &api.EventEntry{ @@ -50,7 +50,7 @@ func TestEventPayloadUnmarshaling(t *testing.T) { decoded := entry.Payload.(map[string]interface{}) assert.Equal("asset1072", decoded["ID"]) - subInfo.PayloadType = api.EventPayloadType_String + subInfo.PayloadType = api.EventPayloadTypeString entry.Payload = []byte(jsonstring) err = p.processEventEntry(subInfo, entry) assert.NoError(err) diff --git a/internal/events/submanager.go b/internal/events/submanager.go index cd2a183..adb6ed0 100644 --- a/internal/events/submanager.go +++ b/internal/events/submanager.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -122,7 +122,7 @@ func (s *subscriptionMGR) Init(mocked ...kvstore.KVStore) error { } // StreamByID used externally to get serializable details -func (s *subscriptionMGR) StreamByID(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*StreamInfo, *restutil.RestError) { +func (s *subscriptionMGR) StreamByID(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*StreamInfo, *restutil.RestError) { streamID := params.ByName("streamId") stream, err := s.streamByID(streamID) if err != nil { @@ -132,12 +132,12 @@ func (s *subscriptionMGR) StreamByID(res http.ResponseWriter, req *http.Request, } // Streams used externally to get list streams -func (s *subscriptionMGR) Streams(res http.ResponseWriter, req *http.Request, params httprouter.Params) []*StreamInfo { +func (s *subscriptionMGR) Streams(_ http.ResponseWriter, _ *http.Request, _ httprouter.Params) []*StreamInfo { return s.getStreams() } // AddStream adds a new stream -func (s *subscriptionMGR) AddStream(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*StreamInfo, *restutil.RestError) { +func (s *subscriptionMGR) AddStream(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*StreamInfo, *restutil.RestError) { var spec StreamInfo if err := json.NewDecoder(req.Body).Decode(&spec); err != nil { return nil, restutil.NewRestError(fmt.Sprintf(errors.RESTGatewayEventStreamInvalid, err), 400) @@ -161,9 +161,8 @@ func (s *subscriptionMGR) AddStream(res http.ResponseWriter, req *http.Request, eh := strings.ToLower(spec.ErrorHandling) if eh != ErrorHandlingBlock && eh != ErrorHandlingSkip { return nil, restutil.NewRestError("Unknown errorHandling type. Must be an empty string, 'skip' or 'block'") - } else { - spec.ErrorHandling = eh } + spec.ErrorHandling = eh } if spec.Suspended != nil { return nil, restutil.NewRestError("Can not set 'suspended'") @@ -176,7 +175,7 @@ func (s *subscriptionMGR) AddStream(res http.ResponseWriter, req *http.Request, } // UpdateStream updates an existing stream -func (s *subscriptionMGR) UpdateStream(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*StreamInfo, *restutil.RestError) { +func (s *subscriptionMGR) UpdateStream(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*StreamInfo, *restutil.RestError) { streamID := params.ByName("streamId") stream, err := s.streamByID(streamID) if err != nil { @@ -199,9 +198,8 @@ func (s *subscriptionMGR) UpdateStream(res http.ResponseWriter, req *http.Reques eh := strings.ToLower(spec.ErrorHandling) if eh != ErrorHandlingBlock && eh != ErrorHandlingSkip { return nil, restutil.NewRestError("Unknown errorHandling type. Must be an empty string, 'skip' or 'block'", 400) - } else { - spec.ErrorHandling = eh } + spec.ErrorHandling = eh } if spec.Suspended != nil { return nil, restutil.NewRestError("Can not set 'suspended'") @@ -214,7 +212,7 @@ func (s *subscriptionMGR) UpdateStream(res http.ResponseWriter, req *http.Reques } // DeleteStream deletes a streamm -func (s *subscriptionMGR) DeleteStream(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { +func (s *subscriptionMGR) DeleteStream(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { streamID := params.ByName("streamId") stream, err := s.streamByID(streamID) if err != nil { @@ -226,12 +224,12 @@ func (s *subscriptionMGR) DeleteStream(res http.ResponseWriter, req *http.Reques result := map[string]string{} result["id"] = streamID - result["deleted"] = "true" + result["deleted"] = strconv.FormatBool(true) return &result, nil } // SuspendStream suspends a stream from firing -func (s *subscriptionMGR) SuspendStream(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { +func (s *subscriptionMGR) SuspendStream(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { streamID := params.ByName("streamId") stream, err := s.streamByID(streamID) if err != nil { @@ -243,12 +241,12 @@ func (s *subscriptionMGR) SuspendStream(res http.ResponseWriter, req *http.Reque result := map[string]string{} result["id"] = streamID - result["suspended"] = "true" + result["suspended"] = strconv.FormatBool(true) return &result, nil } // ResumeStream restarts a suspended stream -func (s *subscriptionMGR) ResumeStream(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { +func (s *subscriptionMGR) ResumeStream(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { streamID := params.ByName("streamId") stream, err := s.streamByID(streamID) if err != nil { @@ -260,12 +258,12 @@ func (s *subscriptionMGR) ResumeStream(res http.ResponseWriter, req *http.Reques result := map[string]string{} result["id"] = streamID - result["resumed"] = "true" + result["resumed"] = strconv.FormatBool(true) return &result, nil } // SubscriptionByID used externally to get serializable details -func (s *subscriptionMGR) SubscriptionByID(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*eventsapi.SubscriptionInfo, *restutil.RestError) { +func (s *subscriptionMGR) SubscriptionByID(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*eventsapi.SubscriptionInfo, *restutil.RestError) { id := params.ByName("subscriptionId") sub, err := s.subscriptionByID(id) if err != nil { @@ -275,17 +273,17 @@ func (s *subscriptionMGR) SubscriptionByID(res http.ResponseWriter, req *http.Re } // Subscriptions used externally to get list subscriptions -func (s *subscriptionMGR) Subscriptions(res http.ResponseWriter, req *http.Request, params httprouter.Params) []*eventsapi.SubscriptionInfo { +func (s *subscriptionMGR) Subscriptions(_ http.ResponseWriter, _ *http.Request, _ httprouter.Params) []*eventsapi.SubscriptionInfo { return s.getSubscriptions() } // AddSubscription adds a new subscription -func (s *subscriptionMGR) AddSubscription(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*eventsapi.SubscriptionInfo, *restutil.RestError) { +func (s *subscriptionMGR) AddSubscription(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*eventsapi.SubscriptionInfo, *restutil.RestError) { var spec eventsapi.SubscriptionInfo if err := json.NewDecoder(req.Body).Decode(&spec); err != nil { return nil, restutil.NewRestError(fmt.Sprintf(errors.RESTGatewaySubscriptionInvalid, err), 400) } - if spec.ChannelId == "" { + if spec.ChannelID == "" { return nil, restutil.NewRestError(`Missing required parameter "channel"`, 400) } if spec.Stream == "" { @@ -295,25 +293,25 @@ func (s *subscriptionMGR) AddSubscription(res http.ResponseWriter, req *http.Req return nil, restutil.NewRestError(`Missing required parameter "signer"`, 400) } pt := spec.PayloadType - if pt != "" && pt != eventsapi.EventPayloadType_String && pt != eventsapi.EventPayloadType_JSON { + if pt != "" && pt != eventsapi.EventPayloadTypeString && pt != eventsapi.EventPayloadTypeJSON { return nil, restutil.NewRestError(`Parameter "payloadType" must be an empty string, "string" or "json"`, 400) } bt := spec.Filter.BlockType - if bt != "" && bt != eventsapi.BlockType_TX && bt != eventsapi.BlockType_Config { + if bt != "" && bt != eventsapi.BlockTypeTX && bt != eventsapi.BlockTypeConfig { return nil, restutil.NewRestError(`Parameter "filter.blockType" must be an empty string, "tx" or "config"`, 400) } if err := validateFromBlock(spec.FromBlock); err != nil { return nil, restutil.NewRestError(err.Error(), 400) } - if err, statusCode := s.addSubscription(&spec); err != nil { + if statusCode, err := s.addSubscription(&spec); err != nil { return nil, restutil.NewRestError(err.Error(), statusCode) } return &spec, nil } // ResetSubscription restarts the steam from the specified block -func (s *subscriptionMGR) ResetSubscription(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { +func (s *subscriptionMGR) ResetSubscription(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { id := params.ByName("subscriptionId") sub, err := s.subscriptionByID(id) if err != nil { @@ -332,12 +330,12 @@ func (s *subscriptionMGR) ResetSubscription(res http.ResponseWriter, req *http.R } result := map[string]string{} result["id"] = sub.info.ID - result["reset"] = "true" + result["reset"] = strconv.FormatBool(true) return &result, nil } // DeleteSubscription deletes a subscription -func (s *subscriptionMGR) DeleteSubscription(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { +func (s *subscriptionMGR) DeleteSubscription(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*map[string]string, *restutil.RestError) { id := params.ByName("subscriptionId") sub, err := s.subscriptionByID(id) if err != nil { @@ -349,7 +347,7 @@ func (s *subscriptionMGR) DeleteSubscription(res http.ResponseWriter, req *http. } result := map[string]string{} result["id"] = sub.info.ID - result["deleted"] = "true" + result["deleted"] = strconv.FormatBool(true) return &result, nil } @@ -376,7 +374,6 @@ func (s *subscriptionMGR) streamByID(id string) (*eventStream, error) { func (s *subscriptionMGR) addStream(spec *StreamInfo) error { spec.ID = streamIDPrefix + utils.UUIDv4() - spec.CreatedISO8601 = time.Now().UTC().Format(time.RFC3339) spec.Path = StreamPathPrefix + "/" + spec.ID stream, err := newEventStream(s, spec, s.wsChannels) if err != nil { @@ -419,10 +416,7 @@ func (s *subscriptionMGR) deleteStream(stream *eventStream) error { func (s *subscriptionMGR) suspendStream(stream *eventStream) error { stream.suspend() // Persist the state change - if err := s.storeStream(stream.spec); err != nil { - return err - } - return nil + return s.storeStream(stream.spec) } func (s *subscriptionMGR) resumeStream(stream *eventStream) error { @@ -430,10 +424,7 @@ func (s *subscriptionMGR) resumeStream(stream *eventStream) error { return err } // Persist the state change - if err := s.storeStream(stream.spec); err != nil { - return err - } - return nil + return s.storeStream(stream.spec) } func (s *subscriptionMGR) storeStream(spec *StreamInfo) error { @@ -452,7 +443,7 @@ func (s *subscriptionMGR) getSubscriptions() []*eventsapi.SubscriptionInfo { return l } -func (s *subscriptionMGR) addSubscription(spec *eventsapi.SubscriptionInfo) (error, int) { +func (s *subscriptionMGR) addSubscription(spec *eventsapi.SubscriptionInfo) (int, error) { spec.TimeSorted = eventsapi.TimeSorted{ CreatedISO8601: time.Now().UTC().Format(time.RFC3339), } @@ -464,9 +455,9 @@ func (s *subscriptionMGR) addSubscription(spec *eventsapi.SubscriptionInfo) (err spec.FromBlock = FromBlockNewest } if spec.Filter.BlockType == "" { - spec.Filter.BlockType = eventsapi.BlockType_TX + spec.Filter.BlockType = eventsapi.BlockTypeTX } - if spec.Filter.EventFilter == "" && spec.Filter.ChaincodeId != "" { + if spec.Filter.EventFilter == "" && spec.Filter.ChaincodeID != "" { spec.Filter.EventFilter = ".*" } @@ -491,24 +482,24 @@ func (s *subscriptionMGR) addSubscription(spec *eventsapi.SubscriptionInfo) (err _, err := s.db.Get(subscriptionKey) if err == nil { // a conflicting subscription already exists, return 400 - return errors.Error("A subscription with the same channel ID, chaincode ID, block type and event filter already exists"), 400 + return 400, errors.Error("A subscription with the same channel ID, chaincode ID, block type and event filter already exists") } // Create it stream, err := s.streamByID(spec.Stream) if err != nil { - return err, 500 + return 500, err } sub, err := newSubscription(stream, s.rpc, spec) if err != nil { - return err, 500 + return 500, err } s.subscriptions[sub.info.ID] = sub - return s.storeSubscription(spec, subscriptionKey), 200 + return 200, s.storeSubscription(spec, subscriptionKey) } func (s *subscriptionMGR) resetSubscription(sub *subscription, initialBlock string) error { - // Re-set the inital block on the subscription and save it + // Re-set the initial block on the subscription and save it if initialBlock == "" || initialBlock == FromBlockNewest { sub.info.FromBlock = FromBlockNewest } else { @@ -535,11 +526,7 @@ func (s *subscriptionMGR) deleteSubscription(sub *subscription) error { } // also delete the lookup key entry subscriptionKey := calculateLookupKey(sub.info) - if err := s.db.Delete(subscriptionKey); err != nil { - return err - } - - return nil + return s.db.Delete(subscriptionKey) } func (s *subscriptionMGR) storeSubscription(info *eventsapi.SubscriptionInfo, lookupKey string) error { @@ -683,14 +670,14 @@ func validateFromBlock(fromBlock string) error { // - "" if fromBlock != "" && fromBlock != FromBlockNewest { if _, err := strconv.Atoi(fromBlock); err != nil { - return fmt.Errorf("Invalid initial block: must be an integer, an empty string or 'newest'") + return fmt.Errorf("invalid initial block: must be an integer, an empty string or 'newest'") } } return nil } func calculateLookupKey(spec *eventsapi.SubscriptionInfo) string { - compositeKey := fmt.Sprintf("%s-%s-%s-%s", spec.ChannelId, spec.Filter.ChaincodeId, spec.Filter.BlockType, spec.Filter.EventFilter) + compositeKey := fmt.Sprintf("%s-%s-%s-%s", spec.ChannelID, spec.Filter.ChaincodeID, spec.Filter.BlockType, spec.Filter.EventFilter) hashKey := sha256.Sum256([]byte(compositeKey)) subscriptionKey := fmt.Sprintf("sub-idx-%x", hashKey) return subscriptionKey diff --git a/internal/events/submanager_test.go b/internal/events/submanager_test.go index 9f39931..2004668 100644 --- a/internal/events/submanager_test.go +++ b/internal/events/submanager_test.go @@ -82,10 +82,10 @@ func TestActionAndSubscriptionLifecyle(t *testing.T) { sub := &api.SubscriptionInfo{ Name: subscriptionName, Stream: stream.ID, - ChannelId: "testChannel", + ChannelID: "testChannel", } - sub.Filter.ChaincodeId = "testChaincode" - err, _ = sm.addSubscription(sub) + sub.Filter.ChaincodeID = "testChaincode" + _, err = sm.addSubscription(sub) assert.NoError(err) // confirm that the lookup key entry has also been persisted alongside the main entry @@ -174,7 +174,7 @@ func TestActionChildCleanup(t *testing.T) { Name: "testSub", Stream: stream.ID, } - err, _ = sm.addSubscription(sub) + _, err = sm.addSubscription(sub) assert.NoError(err) err = sm.deleteStream(sm.streams[stream.ID]) assert.NoError(err) @@ -208,9 +208,9 @@ func TestStreamAndSubscriptionErrors(t *testing.T) { sub := &api.SubscriptionInfo{ Name: "testSub", Stream: stream.ID, - ChannelId: "testChannel", + ChannelID: "testChannel", } - err, _ = sm.addSubscription(sub) + _, err = sm.addSubscription(sub) assert.NoError(err) err = sm.resetSubscription(sm.subscriptions[sub.ID], "badness") @@ -243,14 +243,14 @@ func TestStreamAndSubscriptionDuplicateErrors(t *testing.T) { sub := &api.SubscriptionInfo{ Name: "testSub", Stream: stream.ID, - ChannelId: "testChannel", + ChannelID: "testChannel", } - sub.Filter.BlockType = eventsapi.BlockType_TX - sub.Filter.ChaincodeId = "testChaincode" - err, _ = sm.addSubscription(sub) + sub.Filter.BlockType = eventsapi.BlockTypeTX + sub.Filter.ChaincodeID = "testChaincode" + _, err = sm.addSubscription(sub) assert.NoError(err) - err, _ = sm.addSubscription(sub) + _, err = sm.addSubscription(sub) assert.EqualError(err, "A subscription with the same channel ID, chaincode ID, block type and event filter already exists") sm.db.Close() diff --git a/internal/events/subscription.go b/internal/events/subscription.go index f1c2cc3..b3f6ca9 100644 --- a/internal/events/subscription.go +++ b/internal/events/subscription.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -49,13 +49,13 @@ func newSubscription(stream *eventStream, rpc client.RPCClient, i *eventsapi.Sub ep: newEvtProcessor(i.ID, stream), filterStale: true, } - i.Summary = fmt.Sprintf(`FromBlock=%s,Chaincode=%s,Filter=%s`, i.FromBlock, i.Filter.ChaincodeId, i.Filter.EventFilter) + i.Summary = fmt.Sprintf(`FromBlock=%s,Chaincode=%s,Filter=%s`, i.FromBlock, i.Filter.ChaincodeID, i.Filter.EventFilter) // If a name was not provided by the end user, set it to the system generated summary if i.Name == "" { log.Debugf("No name provided for subscription, using auto-generated ID:%s", i.ID) i.Name = i.ID } - log.Infof("Created subscription ID:%s Chaincode: %s name:%s", i.ID, i.Filter.ChaincodeId, i.Name) + log.Infof("Created subscription ID:%s Chaincode: %s name:%s", i.ID, i.Filter.ChaincodeID, i.Name) return s, nil } @@ -69,7 +69,7 @@ func restoreSubscription(stream *eventStream, rpc client.RPCClient, i *eventsapi return s, nil } -func (s *subscription) setInitialBlockHeight(ctx context.Context) (uint64, error) { +func (s *subscription) setInitialBlockHeight(_ context.Context) (uint64, error) { log.Debugf(`%s: Setting initial block height. "fromBlock" value in the subscription is %s`, s.info.ID, s.info.FromBlock) if s.info.FromBlock != "" && s.info.FromBlock != FromBlockNewest { fromBlock, err := strconv.ParseUint(s.info.FromBlock, 10, 64) @@ -79,7 +79,7 @@ func (s *subscription) setInitialBlockHeight(ctx context.Context) (uint64, error log.Infof("%s: initial block height for subscription: %d", s.info.ID, fromBlock) return fromBlock, nil } - result, err := s.client.QueryChainInfo(s.info.ChannelId, s.info.Signer) + result, err := s.client.QueryChainInfo(s.info.ChannelID, s.info.Signer) if err != nil { return 0, errors.Errorf(errors.RPCCallReturnedError, "QSCC GetChainInfo()", err) } @@ -94,7 +94,7 @@ func (s *subscription) setCheckpointBlockHeight(i uint64) { log.Infof("%s: checkpoint restored block height for subscription: %d", s.info.ID, i) } -func (s *subscription) restartFilter(ctx context.Context, since uint64) error { +func (s *subscription) restartFilter(_ context.Context, since uint64) error { reg, blockEventNotifier, ccEventNotifier, err := s.client.SubscribeEvent(s.info, since) if err != nil { return errors.Errorf(errors.RPCCallReturnedError, "SubscribeEvent", err) @@ -131,9 +131,9 @@ func (s *subscription) processNewEvents() { return } event := &eventsapi.EventEntry{ - ChaincodeId: ccEvent.ChaincodeID, + ChaincodeID: ccEvent.ChaincodeID, BlockNumber: ccEvent.BlockNumber, - TransactionId: ccEvent.TxID, + TransactionID: ccEvent.TxID, EventName: ccEvent.EventName, Payload: ccEvent.Payload, } @@ -157,7 +157,7 @@ func (s *subscription) getEventTimestamp(evt *eventsapi.EventEntry) { return } // we didn't find the timestamp in our cache, query the node for the block header where we can find the timestamp - _, block, err := s.client.QueryBlock(s.info.ChannelId, s.info.Signer, evt.BlockNumber, nil) + _, block, err := s.client.QueryBlock(s.info.ChannelID, s.info.Signer, evt.BlockNumber, nil) if err != nil { log.Errorf("Unable to retrieve block[%s] timestamp: %s", blockNumber, err) evt.Timestamp = 0 // set to 0, we were not able to retrieve the timestamp. diff --git a/internal/events/test_helper.go b/internal/events/test_helper.go index a9d4b3a..34559fb 100644 --- a/internal/events/test_helper.go +++ b/internal/events/test_helper.go @@ -1,11 +1,13 @@ -// Copyright 2022 Kaleido - +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/internal/events/webhooks.go b/internal/events/webhooks.go index b175ad3..f6d2429 100644 --- a/internal/events/webhooks.go +++ b/internal/events/webhooks.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -61,7 +61,7 @@ func newWebhookAction(es *eventStream, spec *webhookActionInfo) (*webhookAction, } // attemptWebhookAction performs a single attempt of a webhook action -func (w *webhookAction) attemptBatch(batchNumber, attempt uint64, events []*api.EventEntry) error { +func (w *webhookAction) attemptBatch(_, attempt uint64, events []*api.EventEntry) error { // We perform DNS resolution before each attempt, to exclude private IP address ranges from the target esID := w.es.spec.ID u, _ := url.Parse(w.spec.URL) @@ -87,6 +87,7 @@ func (w *webhookAction) attemptBatch(batchNumber, attempt uint64, events []*api. TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } + // #nosec G402 transport.TLSClientConfig = &tls.Config{ InsecureSkipVerify: *w.spec.TLSkipHostVerify, } diff --git a/internal/events/websockets.go b/internal/events/websockets.go index a0e0c3e..5c0010f 100644 --- a/internal/events/websockets.go +++ b/internal/events/websockets.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -46,7 +46,7 @@ func newWebSocketAction(es *eventStream, spec *webSocketActionInfo) (*webSocketA func validateWebsocketConfig(spec *webSocketActionInfo) error { if spec.Topic == "" { - return fmt.Errorf("Missing required parameter 'websocket.topic'") + return fmt.Errorf("missing required parameter 'websocket.topic'") } sd := spec.DistributionMode if sd != "" && sd != DistributionModeBroadcast && sd != DistributionModeWLD { @@ -56,7 +56,7 @@ func validateWebsocketConfig(spec *webSocketActionInfo) error { } // attemptBatch attempts to deliver a batch over socket IO -func (w *webSocketAction) attemptBatch(batchNumber, attempt uint64, events []*api.EventEntry) error { +func (w *webSocketAction) attemptBatch(batchNumber, _ uint64, events []*api.EventEntry) error { var err error // Get a blocking channel to send and receive on our chosen namespace diff --git a/internal/fabric/client/api.go b/internal/fabric/client/api.go index 5f07a71..cbf68e1 100644 --- a/internal/fabric/client/api.go +++ b/internal/fabric/client/api.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -52,12 +52,12 @@ type RegistrationWrapper struct { } type RPCClient interface { - Invoke(channelId, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) - Query(channelId, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) - QueryChainInfo(channelId, signer string) (*fab.BlockchainInfoResponse, error) - QueryBlock(channelId string, signer string, blocknumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) - QueryBlockByTxId(channelId string, signer string, txId string) (*utils.RawBlock, *utils.Block, error) - QueryTransaction(channelId, signer, txId string) (map[string]interface{}, error) + Invoke(channelID, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) + Query(channelID, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) + QueryChainInfo(channelID, signer string) (*fab.BlockchainInfoResponse, error) + QueryBlock(channelID string, signer string, blocknumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) + QueryBlockByTxID(channelID string, signer string, txID string) (*utils.RawBlock, *utils.Block, error) + QueryTransaction(channelID, signer, txID string) (map[string]interface{}, error) SubscribeEvent(subInfo *eventsapi.SubscriptionInfo, since uint64) (*RegistrationWrapper, <-chan *fab.BlockEvent, <-chan *fab.CCEvent, error) Unregister(*RegistrationWrapper) Close() error diff --git a/internal/fabric/client/client_ccp.go b/internal/fabric/client/client_ccp.go index c9e936c..33fb9b6 100644 --- a/internal/fabric/client/client_ccp.go +++ b/internal/fabric/client/client_ccp.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -82,23 +82,23 @@ func newRPCClientFromCCP(configProvider core.ConfigProvider, txTimeout int, user return w, nil } -func (w *ccpRPCWrapper) Invoke(channelId, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) { - log.Tracef("RPC [%s:%s:%s:isInit=%t] --> %+v", channelId, chaincodeName, method, isInit, args) +func (w *ccpRPCWrapper) Invoke(channelID, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) { + log.Tracef("RPC [%s:%s:%s:isInit=%t] --> %+v", channelID, chaincodeName, method, isInit, args) - signerID, result, txStatus, err := w.sendTransaction(channelId, signer, chaincodeName, method, args, transientMap, isInit) + signerID, result, txStatus, err := w.sendTransaction(channelID, signer, chaincodeName, method, args, transientMap, isInit) if err != nil { - log.Errorf("Failed to send transaction [%s:%s:%s:isInit=%t]. %s", channelId, chaincodeName, method, isInit, err) + log.Errorf("Failed to send transaction [%s:%s:%s:isInit=%t]. %s", channelID, chaincodeName, method, isInit, err) return nil, err } - log.Tracef("RPC [%s:%s:%s:isInit=%t] <-- %+v", channelId, chaincodeName, method, isInit, result) + log.Tracef("RPC [%s:%s:%s:isInit=%t] <-- %+v", channelID, chaincodeName, method, isInit, result) return newReceipt(result, txStatus, signerID), err } -func (w *ccpRPCWrapper) Query(channelId, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) { - log.Tracef("RPC [%s:%s:%s] --> %+v", channelId, chaincodeName, method, args) +func (w *ccpRPCWrapper) Query(channelID, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) { + log.Tracef("RPC [%s:%s:%s] --> %+v", channelID, chaincodeName, method, args) - client, err := w.getChannelClient(channelId, signer) + client, err := w.getChannelClient(channelID, signer) if err != nil { log.Errorf("Failed to get channel client. %s", err) return nil, errors.Errorf("Failed to get channel client. %s", err) @@ -124,11 +124,11 @@ func (w *ccpRPCWrapper) Query(channelId, signer, chaincodeName, method string, a result, err1 = client.channelClient.Query(req, channel.WithRetry(retry.DefaultChannelOpts), channel.WithTargetEndpoints(peerEndpoint)) } if err1 != nil { - log.Errorf("Failed to send query [%s:%s:%s]. %s", channelId, chaincodeName, method, err) + log.Errorf("Failed to send query [%s:%s:%s]. %s", channelID, chaincodeName, method, err) return nil, err1 } - log.Tracef("RPC [%s:%s:%s] <-- %+v", channelId, chaincodeName, method, result) + log.Tracef("RPC [%s:%s:%s] <-- %+v", channelID, chaincodeName, method, result) return result.Payload, nil } @@ -140,7 +140,7 @@ func (w *ccpRPCWrapper) SignerUpdated(signer string) { w.mu.Unlock() } -func (w *ccpRPCWrapper) getChannelClient(channelId string, signer string) (*ccpClientWrapper, error) { +func (w *ccpRPCWrapper) getChannelClient(channelID string, signer string) (*ccpClientWrapper, error) { w.mu.Lock() defer w.mu.Unlock() id, err := w.idClient.GetSigningIdentity(signer) @@ -151,13 +151,13 @@ func (w *ccpRPCWrapper) getChannelClient(channelId string, signer string) (*ccpC return nil, errors.Errorf("Failed to retrieve signing identity: %s", err) } - allClientsOfChannel := w.channelClients[channelId] + allClientsOfChannel := w.channelClients[channelID] if allClientsOfChannel == nil { - w.channelClients[channelId] = make(map[string]*ccpClientWrapper) + w.channelClients[channelID] = make(map[string]*ccpClientWrapper) } - clientOfUser := w.channelClients[channelId][id.Identifier().ID] + clientOfUser := w.channelClients[channelID][id.Identifier().ID] if clientOfUser == nil { - channelProvider := w.sdk.ChannelContext(channelId, fabsdk.WithOrg(w.idClient.GetClientOrg()), fabsdk.WithUser(id.Identifier().ID)) + channelProvider := w.sdk.ChannelContext(channelID, fabsdk.WithOrg(w.idClient.GetClientOrg()), fabsdk.WithUser(id.Identifier().ID)) cClient, err := w.channelCreator(channelProvider) if err != nil { return nil, err @@ -167,7 +167,7 @@ func (w *ccpRPCWrapper) getChannelClient(channelId string, signer string) (*ccpC channelProvider: channelProvider, signer: id.Identifier(), } - w.channelClients[channelId][id.Identifier().ID] = newWrapper + w.channelClients[channelID][id.Identifier().ID] = newWrapper clientOfUser = newWrapper } return clientOfUser, nil @@ -178,8 +178,8 @@ func (w *ccpRPCWrapper) Close() error { return nil } -func (w *ccpRPCWrapper) sendTransaction(channelId, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*msp.IdentityIdentifier, []byte, *fab.TxStatusEvent, error) { - client, err := w.getChannelClient(channelId, signer) +func (w *ccpRPCWrapper) sendTransaction(channelID, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*msp.IdentityIdentifier, []byte, *fab.TxStatusEvent, error) { + client, err := w.getChannelClient(channelID, signer) if err != nil { return nil, nil, nil, errors.Errorf("Failed to get channel client. %s", err) } diff --git a/internal/fabric/client/client_common.go b/internal/fabric/client/client_common.go index aa8a5ef..70f6c5e 100644 --- a/internal/fabric/client/client_common.go +++ b/internal/fabric/client/client_common.go @@ -1,3 +1,19 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( @@ -68,7 +84,7 @@ func createChannelClient(channelProvider context.ChannelProvider) (*channel.Clie return channel.New(channelProvider) } -func newReceipt(responsePayload []byte, status *fab.TxStatusEvent, signerID *msp.IdentityIdentifier) *TxReceipt { +func newReceipt(_ []byte, status *fab.TxStatusEvent, signerID *msp.IdentityIdentifier) *TxReceipt { return &TxReceipt{ SignerMSP: signerID.MSPID, Signer: signerID.ID, @@ -95,55 +111,55 @@ func convertStringMap(_map map[string]string) map[string][]byte { return result } -func (w *commonRPCWrapper) QueryChainInfo(channelId, signer string) (*fab.BlockchainInfoResponse, error) { - log.Tracef("RPC [%s] --> QueryChainInfo", channelId) +func (w *commonRPCWrapper) QueryChainInfo(channelID, signer string) (*fab.BlockchainInfoResponse, error) { + log.Tracef("RPC [%s] --> QueryChainInfo", channelID) - result, err := w.ledgerClientWrapper.queryChainInfo(channelId, signer) + result, err := w.ledgerClientWrapper.queryChainInfo(channelID, signer) if err != nil { - log.Errorf("Failed to query chain info on channel %s. %s", channelId, err) + log.Errorf("Failed to query chain info on channel %s. %s", channelID, err) return nil, err } - log.Tracef("RPC [%s] <-- %+v", channelId, result) + log.Tracef("RPC [%s] <-- %+v", channelID, result) return result, nil } -func (w *commonRPCWrapper) QueryBlock(channelId string, signer string, blockNumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { - log.Tracef("RPC [%s] --> QueryBlock %v", channelId, blockNumber) +func (w *commonRPCWrapper) QueryBlock(channelID string, signer string, blockNumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { + log.Tracef("RPC [%s] --> QueryBlock %v", channelID, blockNumber) - rawblock, block, err := w.ledgerClientWrapper.queryBlock(channelId, signer, blockNumber, blockhash) + rawblock, block, err := w.ledgerClientWrapper.queryBlock(channelID, signer, blockNumber, blockhash) if err != nil { - log.Errorf("Failed to query block %v on channel %s. %s", blockNumber, channelId, err) + log.Errorf("Failed to query block %v on channel %s. %s", blockNumber, channelID, err) return nil, nil, err } - log.Tracef("RPC [%s] <-- success", channelId) + log.Tracef("RPC [%s] <-- success", channelID) return rawblock, block, nil } -func (w *commonRPCWrapper) QueryBlockByTxId(channelId string, signer string, txId string) (*utils.RawBlock, *utils.Block, error) { - log.Tracef("RPC [%s] --> QueryBlockByTxId %s", channelId, txId) +func (w *commonRPCWrapper) QueryBlockByTxID(channelID string, signer string, txID string) (*utils.RawBlock, *utils.Block, error) { + log.Tracef("RPC [%s] --> QueryBlockByTxID %s", channelID, txID) - rawblock, block, err := w.ledgerClientWrapper.queryBlockByTxId(channelId, signer, txId) + rawblock, block, err := w.ledgerClientWrapper.queryBlockByTxID(channelID, signer, txID) if err != nil { - log.Errorf("Failed to query block by transaction Id %s on channel %s. %s", txId, channelId, err) + log.Errorf("Failed to query block by transaction Id %s on channel %s. %s", txID, channelID, err) return nil, nil, err } - log.Tracef("RPC [%s] <-- success", channelId) + log.Tracef("RPC [%s] <-- success", channelID) return rawblock, block, nil } -func (w *commonRPCWrapper) QueryTransaction(channelId, signer, txId string) (map[string]interface{}, error) { - log.Tracef("RPC [%s] --> QueryTransaction %s", channelId, txId) +func (w *commonRPCWrapper) QueryTransaction(channelID, signer, txID string) (map[string]interface{}, error) { + log.Tracef("RPC [%s] --> QueryTransaction %s", channelID, txID) - result, err := w.ledgerClientWrapper.queryTransaction(channelId, signer, txId) + result, err := w.ledgerClientWrapper.queryTransaction(channelID, signer, txID) if err != nil { - log.Errorf("Failed to query transaction on channel %s. %s", channelId, err) + log.Errorf("Failed to query transaction on channel %s. %s", channelID, err) return nil, err } - log.Tracef("RPC [%s] <-- %+v", channelId, result) + log.Tracef("RPC [%s] <-- %+v", channelID, result) return result, nil } @@ -151,7 +167,7 @@ func (w *commonRPCWrapper) QueryTransaction(channelId, signer, txId string) (map func (w *commonRPCWrapper) SubscribeEvent(subInfo *eventsapi.SubscriptionInfo, since uint64) (*RegistrationWrapper, <-chan *fab.BlockEvent, <-chan *fab.CCEvent, error) { reg, blockEventCh, ccEventCh, err := w.eventClientWrapper.subscribeEvent(subInfo, since) if err != nil { - log.Errorf("Failed to subscribe to event [%s:%s:%s]. %s", subInfo.Stream, subInfo.ChannelId, subInfo.Filter.ChaincodeId, err) + log.Errorf("Failed to subscribe to event [%s:%s:%s]. %s", subInfo.Stream, subInfo.ChannelID, subInfo.Filter.ChaincodeID, err) return nil, nil, nil, err } return reg, blockEventCh, ccEventCh, nil diff --git a/internal/fabric/client/client_gateway_clientside.go b/internal/fabric/client/client_gateway_clientside.go index cebf86f..f99b98f 100644 --- a/internal/fabric/client/client_gateway_clientside.go +++ b/internal/fabric/client/client_gateway_clientside.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -76,66 +76,65 @@ func newRPCClientWithClientSideGateway(configProvider core.ConfigProvider, txTim return w, nil } -func (w *gwRPCWrapper) Invoke(channelId, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) { - log.Tracef("RPC [%s:%s:%s:isInit=%t] --> %+v", channelId, chaincodeName, method, isInit, args) +func (w *gwRPCWrapper) Invoke(channelID, signer, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) (*TxReceipt, error) { + log.Tracef("RPC [%s:%s:%s:isInit=%t] --> %+v", channelID, chaincodeName, method, isInit, args) - result, txStatus, err := w.sendTransaction(channelId, signer, chaincodeName, method, args, transientMap, isInit) + result, txStatus, err := w.sendTransaction(channelID, signer, chaincodeName, method, args, transientMap, isInit) if err != nil { - log.Errorf("Failed to send transaction [%s:%s:%s:isInit=%t]. %s", channelId, chaincodeName, method, isInit, err) + log.Errorf("Failed to send transaction [%s:%s:%s:isInit=%t]. %s", channelID, chaincodeName, method, isInit, err) return nil, err } - signingId, err := w.idClient.GetSigningIdentity(signer) + signingID, err := w.idClient.GetSigningIdentity(signer) if err != nil { return nil, err } - log.Tracef("RPC [%s:%s:%s:isInit=%t] <-- %+v", channelId, chaincodeName, method, isInit, result) - return newReceipt(result, txStatus, signingId.Identifier()), err + log.Tracef("RPC [%s:%s:%s:isInit=%t] <-- %+v", channelID, chaincodeName, method, isInit, result) + return newReceipt(result, txStatus, signingID.Identifier()), err } -func (w *gwRPCWrapper) Query(channelId, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) { - log.Tracef("RPC [%s:%s:%s] --> %+v", channelId, chaincodeName, method, args) +func (w *gwRPCWrapper) Query(channelID, signer, chaincodeName, method string, args []string, strongread bool) ([]byte, error) { + log.Tracef("RPC [%s:%s:%s] --> %+v", channelID, chaincodeName, method, args) - client, err := w.getChannelClient(channelId, signer) + client, err := w.getChannelClient(channelID, signer) if err != nil { return nil, errors.Errorf("Failed to get channel client. %s", err) } if strongread { - client, err := w.getGatewayClient(channelId, signer) + client, err := w.getGatewayClient(channelID, signer) if err != nil { return nil, errors.Errorf("Failed to get gateway client. %s", err) } contractClient := client.GetContract(chaincodeName) result, err := contractClient.EvaluateTransaction(method, args...) if err != nil { - log.Errorf("Failed to send query [%s:%s:%s]. %s", channelId, chaincodeName, method, err) + log.Errorf("Failed to send query [%s:%s:%s]. %s", channelID, chaincodeName, method, err) return nil, err } - log.Tracef("RPC [%s:%s:%s] <-- %+v", channelId, chaincodeName, method, result) + log.Tracef("RPC [%s:%s:%s] <-- %+v", channelID, chaincodeName, method, result) return result, nil - } else { - peerEndpoint, err := getFirstPeerEndpointFromConfig(w.configProvider) - if err != nil { - return nil, err - } - - bytes := convertStringArray(args) - req := channel.Request{ - ChaincodeID: chaincodeName, - Fcn: method, - Args: bytes, - } - result, err := client.Query(req, channel.WithRetry(retry.DefaultChannelOpts), channel.WithTargetEndpoints(peerEndpoint)) - if err != nil { - log.Errorf("Failed to send query [%s:%s:%s]. %s", channelId, chaincodeName, method, err) - return nil, err - } + } + peerEndpoint, err := getFirstPeerEndpointFromConfig(w.configProvider) + if err != nil { + return nil, err + } - log.Tracef("RPC [%s:%s:%s] <-- %+v", channelId, chaincodeName, method, result) - return result.Payload, nil + bytes := convertStringArray(args) + req := channel.Request{ + ChaincodeID: chaincodeName, + Fcn: method, + Args: bytes, } + result, err := client.Query(req, channel.WithRetry(retry.DefaultChannelOpts), channel.WithTargetEndpoints(peerEndpoint)) + if err != nil { + log.Errorf("Failed to send query [%s:%s:%s]. %s", channelID, chaincodeName, method, err) + return nil, err + } + + log.Tracef("RPC [%s:%s:%s] <-- %+v", channelID, chaincodeName, method, result) + return result.Payload, nil } func (w *gwRPCWrapper) SignerUpdated(signer string) { @@ -153,9 +152,9 @@ func (w *gwRPCWrapper) Close() error { return nil } -func (w *gwRPCWrapper) sendTransaction(signer, channelId, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) ([]byte, *fab.TxStatusEvent, error) { +func (w *gwRPCWrapper) sendTransaction(signer, channelID, chaincodeName, method string, args []string, transientMap map[string]string, isInit bool) ([]byte, *fab.TxStatusEvent, error) { convertedMap := convertStringMap(transientMap) - tx, notifier, err := w.txPreparer(w, signer, channelId, chaincodeName, method, isInit, convertedMap) + tx, notifier, err := w.txPreparer(w, signer, channelID, chaincodeName, method, isInit, convertedMap) if err != nil { return nil, nil, err } @@ -172,13 +171,13 @@ func (w *gwRPCWrapper) sendTransaction(signer, channelId, chaincodeName, method return result, txStatus, nil case <-ctx.Done(): cancel() - return nil, nil, errors.Errorf("Failed to get status event for transaction (channel=%s, chaincode=%s, func=%s)", channelId, chaincodeName, method) + return nil, nil, errors.Errorf("Failed to get status event for transaction (channel=%s, chaincode=%s, func=%s)", channelID, chaincodeName, method) } } // channel clients for transactions are created with the gateway API, so that the internal handling of using // the discovery service and selecting the right set of endorsers are automated -func (w *gwRPCWrapper) getGatewayClient(channelId, signer string) (gatewayClient *gateway.Network, err error) { +func (w *gwRPCWrapper) getGatewayClient(channelID, signer string) (gatewayClient *gateway.Network, err error) { w.mu.Lock() defer w.mu.Unlock() gatewayClientsForSigner := w.gwGatewayClients[signer] @@ -194,14 +193,14 @@ func (w *gwRPCWrapper) getGatewayClient(channelId, signer string) (gatewayClient w.gwGatewayClients[signer] = gatewayClientsForSigner } - gatewayClient = gatewayClientsForSigner[channelId] + gatewayClient = gatewayClientsForSigner[channelID] if gatewayClient == nil { client := w.gwClients[signer] - gatewayClient, err = w.networkCreator(client, channelId) + gatewayClient, err = w.networkCreator(client, channelID) if err != nil { return nil, err } - gatewayClientsForSigner[channelId] = gatewayClient + gatewayClientsForSigner[channelID] = gatewayClient } return gatewayClient, nil } @@ -209,7 +208,7 @@ func (w *gwRPCWrapper) getGatewayClient(channelId, signer string) (gatewayClient // channel clients for queries are created with the channel client API, so that we can dictate the target // peer to be the single peer that this fabconnect instance is attached to. This is more useful than trying to // do a "strong read" across multiple peers -func (w *gwRPCWrapper) getChannelClient(channelId, signer string) (channelClient *channel.Client, err error) { +func (w *gwRPCWrapper) getChannelClient(channelID, signer string) (channelClient *channel.Client, err error) { w.mu.Lock() defer w.mu.Unlock() channelClientsForSigner := w.gwChannelClients[signer] @@ -218,20 +217,20 @@ func (w *gwRPCWrapper) getChannelClient(channelId, signer string) (channelClient w.gwChannelClients[signer] = channelClientsForSigner } - channelClient = channelClientsForSigner[channelId] + channelClient = channelClientsForSigner[channelID] if channelClient == nil { sdk := w.ledgerClientWrapper.sdk org, err := getOrgFromConfig(w.configProvider) if err != nil { return nil, err } - clientChannelContext := sdk.ChannelContext(channelId, fabsdk.WithUser(signer), fabsdk.WithOrg(org)) + clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser(signer), fabsdk.WithOrg(org)) // Channel client is used to query and execute transactions (Org1 is default org) channelClient, err = w.channelCreator(clientChannelContext) if err != nil { return nil, errors.Errorf("Failed to create new channel client: %s", err) } - channelClientsForSigner[channelId] = channelClient + channelClientsForSigner[channelID] = channelClient } return channelClient, nil } @@ -240,12 +239,12 @@ func createGateway(configProvider core.ConfigProvider, signer string, txTimeout return gateway.Connect(gateway.WithConfig(configProvider), gateway.WithUser(signer), gateway.WithTimeout(time.Duration(txTimeout)*time.Second)) } -func getNetwork(gateway *gateway.Gateway, channelId string) (*gateway.Network, error) { - return gateway.GetNetwork(channelId) +func getNetwork(gateway *gateway.Gateway, channelID string) (*gateway.Network, error) { + return gateway.GetNetwork(channelID) } -func prepareTx(w *gwRPCWrapper, signer, channelId, chaincodeName, method string, isInit bool, transientMap map[string][]byte) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) { - channelClient, err := w.getGatewayClient(signer, channelId) +func prepareTx(w *gwRPCWrapper, signer, channelID, chaincodeName, method string, isInit bool, transientMap map[string][]byte) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) { + channelClient, err := w.getGatewayClient(signer, channelID) if err != nil { return nil, nil, err } diff --git a/internal/fabric/client/eventsubscriber.go b/internal/fabric/client/eventsubscriber.go index ff87b27..f542ca1 100644 --- a/internal/fabric/client/eventsubscriber.go +++ b/internal/fabric/client/eventsubscriber.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -44,7 +44,7 @@ type eventClientWrapper struct { mu sync.Mutex } -func newEventClient(configProvider core.ConfigProvider, sdk *fabsdk.FabricSDK, idClient IdentityClient) *eventClientWrapper { +func newEventClient(_ core.ConfigProvider, sdk *fabsdk.FabricSDK, idClient IdentityClient) *eventClientWrapper { w := &eventClientWrapper{ sdk: sdk, idClient: idClient, @@ -57,45 +57,44 @@ func newEventClient(configProvider core.ConfigProvider, sdk *fabsdk.FabricSDK, i } func (e *eventClientWrapper) subscribeEvent(subInfo *eventsapi.SubscriptionInfo, since uint64) (*RegistrationWrapper, <-chan *fab.BlockEvent, <-chan *fab.CCEvent, error) { - eventClient, err := e.getEventClient(subInfo.ChannelId, subInfo.Signer, since, subInfo.Filter.ChaincodeId) + eventClient, err := e.getEventClient(subInfo.ChannelID, subInfo.Signer, since, subInfo.Filter.ChaincodeID) if err != nil { log.Errorf("Failed to get event client. %s", err) return nil, nil, nil, errors.Errorf("Failed to get event client. %s", err) } - if subInfo.Filter.ChaincodeId != "" { - reg, notifier, err := eventClient.RegisterChaincodeEvent(subInfo.Filter.ChaincodeId, subInfo.Filter.EventFilter) + if subInfo.Filter.ChaincodeID != "" { + reg, notifier, err := eventClient.RegisterChaincodeEvent(subInfo.Filter.ChaincodeID, subInfo.Filter.EventFilter) if err != nil { - return nil, nil, nil, errors.Errorf("Failed to subscribe to chaincode %s events. %s", subInfo.Filter.ChaincodeId, err) + return nil, nil, nil, errors.Errorf("Failed to subscribe to chaincode %s events. %s", subInfo.Filter.ChaincodeID, err) } - log.Infof("Subscribed to events in channel %s chaincode %s from block %d", subInfo.ChannelId, subInfo.Filter.ChaincodeId, since) + log.Infof("Subscribed to events in channel %s chaincode %s from block %d", subInfo.ChannelID, subInfo.Filter.ChaincodeID, since) regWrapper := &RegistrationWrapper{ registration: reg, eventClient: eventClient, } return regWrapper, nil, notifier, nil - } else { - blockType := subInfo.Filter.BlockType - var blockfilter fab.BlockFilter - if blockType == eventsapi.BlockType_TX { - blockfilter = headertypefilter.New(common.HeaderType_ENDORSER_TRANSACTION) - } else if blockType == eventsapi.BlockType_Config { - blockfilter = headertypefilter.New(common.HeaderType_CONFIG, common.HeaderType_CONFIG_UPDATE) - } + } + blockType := subInfo.Filter.BlockType + var blockfilter fab.BlockFilter + if blockType == eventsapi.BlockTypeTX { + blockfilter = headertypefilter.New(common.HeaderType_ENDORSER_TRANSACTION) + } else if blockType == eventsapi.BlockTypeConfig { + blockfilter = headertypefilter.New(common.HeaderType_CONFIG, common.HeaderType_CONFIG_UPDATE) + } - reg, notifier, err := eventClient.RegisterBlockEvent(blockfilter) - if err != nil { - return nil, nil, nil, errors.Errorf("Failed to subscribe to block events. %s", err) - } - log.Infof("Subscribed to events in channel %s from block %d", subInfo.ChannelId, since) - regWrapper := &RegistrationWrapper{ - registration: reg, - eventClient: eventClient, - } - return regWrapper, notifier, nil, nil + reg, notifier, err := eventClient.RegisterBlockEvent(blockfilter) + if err != nil { + return nil, nil, nil, errors.Errorf("Failed to subscribe to block events. %s", err) + } + log.Infof("Subscribed to events in channel %s from block %d", subInfo.ChannelID, since) + regWrapper := &RegistrationWrapper{ + registration: reg, + eventClient: eventClient, } + return regWrapper, notifier, nil, nil } -func (e *eventClientWrapper) getEventClient(channelId, signer string, since uint64, chaincodeId string) (eventClient *event.Client, err error) { +func (e *eventClientWrapper) getEventClient(channelID, signer string, since uint64, chaincodeID string) (eventClient *event.Client, err error) { e.mu.Lock() defer e.mu.Unlock() eventClientsForSigner := e.eventClients[signer] @@ -103,7 +102,7 @@ func (e *eventClientWrapper) getEventClient(channelId, signer string, since uint eventClientsForSigner = make(map[string]*event.Client) e.eventClients[signer] = eventClientsForSigner } - key := eventsapi.GetKeyForEventClient(channelId, chaincodeId) + key := eventsapi.GetKeyForEventClient(channelID, chaincodeID) eventClient = eventClientsForSigner[key] if eventClient == nil { eventOpts := []event.ClientOption{ @@ -111,10 +110,10 @@ func (e *eventClientWrapper) getEventClient(channelId, signer string, since uint event.WithSeekType(seek.FromBlock), event.WithBlockNum(since), } - if chaincodeId != "" { - eventOpts = append(eventOpts, event.WithChaincodeID(chaincodeId)) + if chaincodeID != "" { + eventOpts = append(eventOpts, event.WithChaincodeID(chaincodeID)) } - channelProvider := e.sdk.ChannelContext(channelId, fabsdk.WithOrg(e.idClient.GetClientOrg()), fabsdk.WithUser(signer)) + channelProvider := e.sdk.ChannelContext(channelID, fabsdk.WithOrg(e.idClient.GetClientOrg()), fabsdk.WithUser(signer)) eventClient, err = e.eventClientCreator(channelProvider, eventOpts...) if err != nil { return nil, err diff --git a/internal/fabric/client/identity.go b/internal/fabric/client/identity.go index bcb6467..fc61554 100644 --- a/internal/fabric/client/identity.go +++ b/internal/fabric/client/identity.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -43,7 +43,7 @@ type identityManagerProvider struct { } // IdentityManager returns the organization's identity manager -func (p *identityManagerProvider) IdentityManager(orgName string) (msp.IdentityManager, bool) { +func (p *identityManagerProvider) IdentityManager(_ string) (msp.IdentityManager, bool) { return p.identityManager, true } @@ -130,7 +130,7 @@ func (w *idClientWrapper) GetClientOrg() string { } // the rpcWrapper is also an implementation of the interface internal/rest/idenity/IdentityClient -func (w *idClientWrapper) Register(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RegisterResponse, *restutil.RestError) { +func (w *idClientWrapper) Register(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*identity.RegisterResponse, *restutil.RestError) { regreq := identity.Identity{} decoder := json.NewDecoder(req.Body) decoder.DisallowUnknownFields() @@ -173,7 +173,7 @@ func (w *idClientWrapper) Register(res http.ResponseWriter, req *http.Request, p return &result, nil } -func (w *idClientWrapper) Modify(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RegisterResponse, *restutil.RestError) { +func (w *idClientWrapper) Modify(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RegisterResponse, *restutil.RestError) { username := params.ByName("username") regreq := identity.Identity{} decoder := json.NewDecoder(req.Body) @@ -210,7 +210,7 @@ func (w *idClientWrapper) Modify(res http.ResponseWriter, req *http.Request, par return &result, nil } -func (w *idClientWrapper) Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.IdentityResponse, *restutil.RestError) { +func (w *idClientWrapper) Enroll(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *restutil.RestError) { username := params.ByName("username") enreq := identity.EnrollRequest{} decoder := json.NewDecoder(req.Body) @@ -242,7 +242,7 @@ func (w *idClientWrapper) Enroll(res http.ResponseWriter, req *http.Request, par return nil, restutil.NewRestError(err.Error()) } - result := identity.IdentityResponse{ + result := identity.Response{ Name: enreq.Name, Success: true, } @@ -251,7 +251,7 @@ func (w *idClientWrapper) Enroll(res http.ResponseWriter, req *http.Request, par return &result, nil } -func (w *idClientWrapper) Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.IdentityResponse, *restutil.RestError) { +func (w *idClientWrapper) Reenroll(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *restutil.RestError) { username := params.ByName("username") enreq := identity.EnrollRequest{} decoder := json.NewDecoder(req.Body) @@ -279,7 +279,7 @@ func (w *idClientWrapper) Reenroll(res http.ResponseWriter, req *http.Request, p return nil, restutil.NewRestError(err.Error()) } - result := identity.IdentityResponse{ + result := identity.Response{ Name: username, Success: true, } @@ -288,7 +288,7 @@ func (w *idClientWrapper) Reenroll(res http.ResponseWriter, req *http.Request, p return &result, nil } -func (w *idClientWrapper) Revoke(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RevokeResponse, *restutil.RestError) { +func (w *idClientWrapper) Revoke(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RevokeResponse, *restutil.RestError) { username := params.ByName("username") enreq := identity.RevokeRequest{} decoder := json.NewDecoder(req.Body) @@ -326,46 +326,46 @@ func (w *idClientWrapper) Revoke(res http.ResponseWriter, req *http.Request, par return &result, nil } -func (w *idClientWrapper) List(res http.ResponseWriter, req *http.Request, params httprouter.Params) ([]*identity.Identity, *restutil.RestError) { +func (w *idClientWrapper) List(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) ([]*identity.Identity, *restutil.RestError) { result, err := w.caClient.GetAllIdentities(params.ByName("caname")) if err != nil { return nil, restutil.NewRestError(err.Error(), 500) } ret := make([]*identity.Identity, len(result)) for i, v := range result { - newId := identity.Identity{} - newId.Name = v.ID - newId.MaxEnrollments = v.MaxEnrollments - newId.CAName = v.CAName - newId.Type = v.Type - newId.Affiliation = v.Affiliation + newID := identity.Identity{} + newID.Name = v.ID + newID.MaxEnrollments = v.MaxEnrollments + newID.CAName = v.CAName + newID.Type = v.Type + newID.Affiliation = v.Affiliation if len(v.Attributes) > 0 { - newId.Attributes = make(map[string]string, len(v.Attributes)) + newID.Attributes = make(map[string]string, len(v.Attributes)) for _, attr := range v.Attributes { - newId.Attributes[attr.Name] = attr.Value + newID.Attributes[attr.Name] = attr.Value } } - ret[i] = &newId + ret[i] = &newID } return ret, nil } -func (w *idClientWrapper) Get(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Identity, *restutil.RestError) { +func (w *idClientWrapper) Get(_ http.ResponseWriter, _ *http.Request, params httprouter.Params) (*identity.Identity, *restutil.RestError) { username := params.ByName("username") result, err := w.caClient.GetIdentity(username, params.ByName("caname")) if err != nil { return nil, restutil.NewRestError(err.Error(), 500) } - newId := identity.Identity{} - newId.Name = result.ID - newId.MaxEnrollments = result.MaxEnrollments - newId.CAName = result.CAName - newId.Type = result.Type - newId.Affiliation = result.Affiliation + newID := identity.Identity{} + newID.Name = result.ID + newID.MaxEnrollments = result.MaxEnrollments + newID.CAName = result.CAName + newID.Type = result.Type + newID.Affiliation = result.Affiliation if len(result.Attributes) > 0 { - newId.Attributes = make(map[string]string, len(result.Attributes)) + newID.Attributes = make(map[string]string, len(result.Attributes)) for _, attr := range result.Attributes { - newId.Attributes[attr.Name] = attr.Value + newID.Attributes[attr.Name] = attr.Value } } @@ -378,11 +378,11 @@ func (w *idClientWrapper) Get(res http.ResponseWriter, req *http.Request, params if err == nil { // the user may have been enrolled by a different client instance ecert := si.EnrollmentCertificate() - mspId := si.Identifier().MSPID - newId.MSPID = mspId - newId.EnrollmentCert = ecert + mspID := si.Identifier().MSPID + newID.MSPID = mspID + newID.EnrollmentCert = ecert } - newId.Organization = w.identityConfig.Client().Organization + newID.Organization = w.identityConfig.Client().Organization // the SDK doesn't save the CACert locally, we have to retrieve it from the Fabric CA server cacert, err := w.getCACert() @@ -390,8 +390,8 @@ func (w *idClientWrapper) Get(res http.ResponseWriter, req *http.Request, params return nil, restutil.NewRestError(err.Error(), 500) } - newId.CACert = cacert - return &newId, nil + newID.CACert = cacert + return &newID, nil } func (w *idClientWrapper) getCACert() ([]byte, error) { diff --git a/internal/fabric/client/invokehandler.go b/internal/fabric/client/invokehandler.go index 5f3a758..70eef2a 100644 --- a/internal/fabric/client/invokehandler.go +++ b/internal/fabric/client/invokehandler.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,20 +26,20 @@ import ( // adapted from the CommitHandler in https://github.com/hyperledger/fabric-sdk-go // in order to custom process the transaction status event -type txSubmitAndListenHandler struct { +type TxSubmitAndListenHandler struct { txStatusEvent *fab.TxStatusEvent } -func NewTxSubmitAndListenHandler(txStatus *fab.TxStatusEvent) *txSubmitAndListenHandler { - return &txSubmitAndListenHandler{ +func NewTxSubmitAndListenHandler(txStatus *fab.TxStatusEvent) *TxSubmitAndListenHandler { + return &TxSubmitAndListenHandler{ txStatusEvent: txStatus, } } -func (h *txSubmitAndListenHandler) Handle(requestContext *invoke.RequestContext, clientContext *invoke.ClientContext) { +func (h *TxSubmitAndListenHandler) Handle(requestContext *invoke.RequestContext, clientContext *invoke.ClientContext) { txnID := requestContext.Response.TransactionID - //Register Tx event + // Register Tx event reg, statusNotifier, err := clientContext.EventService.RegisterTxStatusEvent(string(txnID)) if err != nil { requestContext.Error = errors.Errorf("Error registering for TxStatus event for transaction %s. %s", txnID, err) diff --git a/internal/fabric/client/ledger.go b/internal/fabric/client/ledger.go index 03c4d6d..dd3a92e 100644 --- a/internal/fabric/client/ledger.go +++ b/internal/fabric/client/ledger.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -41,7 +41,7 @@ type ledgerClientWrapper struct { mu sync.Mutex } -func newLedgerClient(configProvider core.ConfigProvider, sdk *fabsdk.FabricSDK, idClient IdentityClient) *ledgerClientWrapper { +func newLedgerClient(_ core.ConfigProvider, sdk *fabsdk.FabricSDK, idClient IdentityClient) *ledgerClientWrapper { w := &ledgerClientWrapper{ sdk: sdk, idClient: idClient, @@ -52,8 +52,8 @@ func newLedgerClient(configProvider core.ConfigProvider, sdk *fabsdk.FabricSDK, return w } -func (l *ledgerClientWrapper) queryChainInfo(channelId, signer string) (*fab.BlockchainInfoResponse, error) { - client, err := l.getLedgerClient(channelId, signer) +func (l *ledgerClientWrapper) queryChainInfo(channelID, signer string) (*fab.BlockchainInfoResponse, error) { + client, err := l.getLedgerClient(channelID, signer) if err != nil { return nil, errors.Errorf("Failed to get channel client. %s", err) } @@ -64,8 +64,8 @@ func (l *ledgerClientWrapper) queryChainInfo(channelId, signer string) (*fab.Blo return result, nil } -func (l *ledgerClientWrapper) queryBlock(channelId string, signer string, blockNumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { - client, err := l.getLedgerClient(channelId, signer) +func (l *ledgerClientWrapper) queryBlock(channelID string, signer string, blockNumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { + client, err := l.getLedgerClient(channelID, signer) if err != nil { return nil, nil, errors.Errorf("Failed to get channel client. %s", err) } @@ -83,12 +83,12 @@ func (l *ledgerClientWrapper) queryBlock(channelId string, signer string, blockN return rawblock, block, err } -func (l *ledgerClientWrapper) queryBlockByTxId(channelId string, signer string, txId string) (*utils.RawBlock, *utils.Block, error) { - client, err := l.getLedgerClient(channelId, signer) +func (l *ledgerClientWrapper) queryBlockByTxID(channelID string, signer string, txID string) (*utils.RawBlock, *utils.Block, error) { + client, err := l.getLedgerClient(channelID, signer) if err != nil { return nil, nil, errors.Errorf("Failed to get channel client. %s", err) } - result, err := client.QueryBlockByTxID(fab.TransactionID(txId)) + result, err := client.QueryBlockByTxID(fab.TransactionID(txID)) if err != nil { return nil, nil, err } @@ -96,13 +96,13 @@ func (l *ledgerClientWrapper) queryBlockByTxId(channelId string, signer string, return rawblock, block, err } -func (l *ledgerClientWrapper) queryTransaction(channelId, signer, txId string) (map[string]interface{}, error) { - client, err := l.getLedgerClient(channelId, signer) +func (l *ledgerClientWrapper) queryTransaction(channelID, signer, txID string) (map[string]interface{}, error) { + client, err := l.getLedgerClient(channelID, signer) if err != nil { return nil, errors.Errorf("Failed to get channel client. %s", err) } - txID := fab.TransactionID(txId) - result, err := client.QueryTransaction(txID) + fabTxID := fab.TransactionID(txID) + result, err := client.QueryTransaction(fabTxID) if err != nil { return nil, err } @@ -118,7 +118,7 @@ func (l *ledgerClientWrapper) queryTransaction(channelId, signer, txId string) ( return ret, nil } -func (l *ledgerClientWrapper) getLedgerClient(channelId, signer string) (ledgerClient *ledger.Client, err error) { +func (l *ledgerClientWrapper) getLedgerClient(channelID, signer string) (ledgerClient *ledger.Client, err error) { l.mu.Lock() defer l.mu.Unlock() ledgerClientsForSigner := l.ledgerClients[signer] @@ -126,14 +126,14 @@ func (l *ledgerClientWrapper) getLedgerClient(channelId, signer string) (ledgerC ledgerClientsForSigner = make(map[string]*ledger.Client) l.ledgerClients[signer] = ledgerClientsForSigner } - ledgerClient = ledgerClientsForSigner[channelId] + ledgerClient = ledgerClientsForSigner[channelID] if ledgerClient == nil { - channelProvider := l.sdk.ChannelContext(channelId, fabsdk.WithOrg(l.idClient.GetClientOrg()), fabsdk.WithUser(signer)) + channelProvider := l.sdk.ChannelContext(channelID, fabsdk.WithOrg(l.idClient.GetClientOrg()), fabsdk.WithUser(signer)) ledgerClient, err = l.ledgerClientCreator(channelProvider) if err != nil { return nil, err } - ledgerClientsForSigner[channelId] = ledgerClient + ledgerClientsForSigner[channelID] = ledgerClient } return ledgerClient, nil } diff --git a/internal/fabric/client/rpc.go b/internal/fabric/client/rpc.go index 388105a..ad2e0a6 100644 --- a/internal/fabric/client/rpc.go +++ b/internal/fabric/client/rpc.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,14 +25,12 @@ import ( log "github.com/sirupsen/logrus" ) -// // Instantiate an RPC client to interact with a Fabric network. based on the client configuration // on gateway usage, it creates different types of client under the cover: // - "useGatewayClient: true": returned RPCClient uses the client-side Gateway // - "useGatewayClient: false": returned RPCClient uses a static network map described by the Connection Profile // - "useGatewayServer: true": for Fabric 2.4 node only, the returned RPCClient utilizes the server-side gateway service -// -func RPCConnect(c conf.RPCConf, txTimeout int) (RPCClient, identity.IdentityClient, error) { +func RPCConnect(c conf.RPCConf, txTimeout int) (RPCClient, identity.Client, error) { configProvider := config.FromFile(c.ConfigPath) userStore, err := newUserstore(configProvider) if err != nil { diff --git a/internal/fabric/test/helper.go b/internal/fabric/test/helper.go index 4d2338c..d6e1dfd 100644 --- a/internal/fabric/test/helper.go +++ b/internal/fabric/test/helper.go @@ -1,11 +1,13 @@ -// Copyright 2019 Kaleido - +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -42,7 +44,7 @@ func MockRPCClient(fromBlock string, withReset ...bool) *mockfabric.RPCClient { } tx1 := &utils.Transaction{ Timestamp: 1000000, - TxId: "3144a3ad43dcc11374832bbb71561320de81fd80d69cc8e26a9ea7d3240a5e84", + TxID: "3144a3ad43dcc11374832bbb71561320de81fd80d69cc8e26a9ea7d3240a5e84", } block := &utils.Block{ Number: uint64(20), @@ -55,7 +57,7 @@ func MockRPCClient(fromBlock string, withReset ...bool) *mockfabric.RPCClient { rpc.On("Query", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(chaincodeResult, nil) rpc.On("QueryChainInfo", mock.Anything, mock.Anything).Return(res, nil) rpc.On("QueryBlock", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(rawBlock, block, nil) - rpc.On("QueryBlockByTxId", mock.Anything, mock.Anything, mock.Anything).Return(rawBlock, block, nil) + rpc.On("QueryBlockByTxID", mock.Anything, mock.Anything, mock.Anything).Return(rawBlock, block, nil) rpc.On("QueryTransaction", mock.Anything, mock.Anything, mock.Anything).Return(txResult, nil) rpc.On("Unregister", mock.Anything).Return() diff --git a/internal/fabric/tx.go b/internal/fabric/tx.go index 6d2fedf..680392a 100644 --- a/internal/fabric/tx.go +++ b/internal/fabric/tx.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,10 +21,10 @@ import ( "sync" "time" - "github.com/hyperledger/firefly-fabconnect/internal/fabric/client" - "github.com/hyperledger/firefly-fabconnect/internal/messages" + fabricClient "github.com/hyperledger/firefly-fabconnect/internal/fabric/client" + messaging "github.com/hyperledger/firefly-fabconnect/internal/messages" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" ) // Txn wraps a Fabric transaction, along with the logic to send it over @@ -38,11 +38,11 @@ type Tx struct { Args []string TransientMap map[string]string Hash string - Receipt *client.TxReceipt + Receipt *fabricClient.TxReceipt Signer string } -func NewSendTx(msg *messages.SendTransaction, signer string) *Tx { +func NewSendTx(msg *messaging.SendTransaction, _ string) *Tx { return &Tx{ ChannelID: msg.Headers.ChannelID, ChaincodeName: msg.Headers.ChaincodeName, @@ -55,7 +55,7 @@ func NewSendTx(msg *messages.SendTransaction, signer string) *Tx { } // GetTXReceipt gets the receipt for the transaction -func (tx *Tx) GetTXReceipt(ctx context.Context, rpc client.RPCClient) (bool, error) { +func (tx *Tx) GetTXReceipt(_ context.Context, _ fabricClient.RPCClient) (bool, error) { tx.lock.Lock() isMined := tx.Receipt.BlockNumber > 0 tx.lock.Unlock() @@ -63,10 +63,10 @@ func (tx *Tx) GetTXReceipt(ctx context.Context, rpc client.RPCClient) (bool, err } // Send sends an individual transaction -func (tx *Tx) Send(ctx context.Context, rpc client.RPCClient) error { +func (tx *Tx) Send(_ context.Context, rpc fabricClient.RPCClient) error { start := time.Now().UTC() - var receipt *client.TxReceipt + var receipt *fabricClient.TxReceipt var err error receipt, err = rpc.Invoke(tx.ChannelID, tx.Signer, tx.ChaincodeName, tx.Function, tx.Args, tx.TransientMap, tx.IsInit) tx.lock.Lock() @@ -75,9 +75,9 @@ func (tx *Tx) Send(ctx context.Context, rpc client.RPCClient) error { callTime := time.Now().UTC().Sub(start) if err != nil { - log.Warnf("TX:%s Failed to send: %s [%.2fs]", tx.Hash, err, callTime.Seconds()) + logrus.Warnf("TX:%s Failed to send: %s [%.2fs]", tx.Hash, err, callTime.Seconds()) } else { - log.Infof("TX:%s Sent OK [%.2fs]", tx.Hash, callTime.Seconds()) + logrus.Infof("TX:%s Sent OK [%.2fs]", tx.Hash, callTime.Seconds()) } return err } diff --git a/internal/fabric/utils/block.go b/internal/fabric/utils/block.go index 391b854..6bf1461 100644 --- a/internal/fabric/utils/block.go +++ b/internal/fabric/utils/block.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -39,7 +39,7 @@ type Creator struct { type Transaction struct { Type string `json:"type"` - TxId string `json:"tx_id"` + TxID string `json:"tx_id"` Nonce string `json:"nonce"` // hex string Creator *Creator `json:"creator"` Status string `json:"status"` @@ -52,7 +52,7 @@ type TransactionAction struct { Nonce string `json:"nonce"` // hex string Creator *Creator `json:"creator"` TransientMap *map[string][]byte `json:"transient_map"` - ChaincodeId *peer.ChaincodeID `json:"chaincode_id"` + ChaincodeID *peer.ChaincodeID `json:"chaincode_id"` Input *ChaincodeSpecInput `json:"input"` ProposalHash string `json:"proposal_hash"` // hex string Event *ChaincodeEvent `json:"event"` diff --git a/internal/fabric/utils/blockdecoder.go b/internal/fabric/utils/blockdecoder.go index a37d887..1fb5467 100644 --- a/internal/fabric/utils/blockdecoder.go +++ b/internal/fabric/utils/blockdecoder.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -39,7 +39,7 @@ func GetEvents(block *common.Block) []*api.EventEntry { } for idx, entry := range rawBlock.Data.Data { timestamp := entry.Payload.Header.ChannelHeader.Timestamp - txId := entry.Payload.Header.ChannelHeader.TxId + txID := entry.Payload.Header.ChannelHeader.TxID actions := entry.Payload.Data.Actions for actionIdx, action := range actions { event := action.Payload.Action.ProposalResponsePayload.Extension.Events @@ -48,11 +48,11 @@ func GetEvents(block *common.Block) []*api.EventEntry { } // if the transaction did not publish any events, we need to get most of the // information below from other parts of the transaction - chaincodeId := action.Payload.Action.ProposalResponsePayload.Extension.ChaincodeId.Name + chaincodeID := action.Payload.Action.ProposalResponsePayload.Extension.ChaincodeID.Name eventEntry := api.EventEntry{ - ChaincodeId: chaincodeId, + ChaincodeID: chaincodeID, BlockNumber: rawBlock.Header.Number, - TransactionId: txId, + TransactionID: txID, TransactionIndex: idx, EventIndex: actionIdx, // each action only allowed one event, so event index is the action index EventName: event.EventName, @@ -77,7 +77,7 @@ func DecodeBlock(block *common.Block) (*RawBlock, *Block, error) { bloc := &Block{} // this array in the block header's metadata contains each transaction's status code - txFilter := []byte(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) + txFilter := block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] var transactions []*Transaction for i, data := range block.Data.Data { env, err := getEnvelopeFromBlock(data) @@ -136,11 +136,10 @@ func (block *RawBlock) DecodeBlockDataEnvelope(env *common.Envelope) (*BlockData if ok { tx.Signature = dataEnv.Signature return dataEnv, tx, nil - } else { - config := result.(*ConfigRecord) - config.Signature = dataEnv.Signature - return dataEnv, config, nil } + config := result.(*ConfigRecord) + config.Signature = dataEnv.Signature + return dataEnv, config, nil } // based on the channel header type, returns a *Transaction (type=1) or a *ConfigRecord (type=3) @@ -168,7 +167,7 @@ func (block *RawBlock) decodePayload(payload *common.Payload, _payload *Payload) _transaction.Timestamp = timestamp _transaction.Creator = _creator _transaction.Nonce = hex.EncodeToString([]byte(_payloadHeader.SignatureHeader.Nonce)) - _transaction.TxId = _payloadHeader.ChannelHeader.TxId + _transaction.TxID = _payloadHeader.ChannelHeader.TxID if err := block.decodeTxPayloadData(payload.Data, _payloadData, _transaction); err != nil { return nil, err @@ -203,10 +202,10 @@ func (block *RawBlock) decodePayloadHeader(header *common.Header, _header *Paylo if err := proto.Unmarshal(header.ChannelHeader, channelHeader); err != nil { return errors.Wrap(err, "error decoding ChannelHeader from payload") } - _channelHeader.ChannelId = channelHeader.ChannelId + _channelHeader.ChannelID = channelHeader.ChannelId _channelHeader.Epoch = strconv.FormatUint(channelHeader.Epoch, 10) _channelHeader.Timestamp = time.Unix(channelHeader.Timestamp.GetSeconds(), int64(channelHeader.Timestamp.GetNanos())).UnixNano() - _channelHeader.TxId = channelHeader.TxId + _channelHeader.TxID = channelHeader.TxId _channelHeader.Type = common.HeaderType_name[channelHeader.Type] _channelHeader.Version = int(channelHeader.Version) @@ -268,7 +267,7 @@ func (block *RawBlock) decodeTxPayloadData(payloadData []byte, _payloadData *Pay } txAction.Nonce = hex.EncodeToString([]byte(_signatureHeader.Nonce)) - txAction.ChaincodeId = _actionPayload.Action.ProposalResponsePayload.Extension.ChaincodeId + txAction.ChaincodeID = _actionPayload.Action.ProposalResponsePayload.Extension.ChaincodeID creator := _signatureHeader.Creator txAction.Creator = &Creator{ MspID: creator.Mspid, @@ -292,20 +291,16 @@ func (block *RawBlock) decodeActionPayload(_actionPayload *ActionPayload, payloa _chaincodeProposalPayload := &ChaincodeProposalPayload{} _actionPayload.ChaincodeProposalPayload = _chaincodeProposalPayload - cap := &peer.ChaincodeActionPayload{} - if err := proto.Unmarshal(payload, cap); err != nil { + capPayload := &peer.ChaincodeActionPayload{} + if err := proto.Unmarshal(payload, capPayload); err != nil { return errors.Wrap(err, "error decoding chaincode action payload") } - if err := block.decodeActionPayloadAction(_actionPayloadAction, cap.Action); err != nil { - return err - } - - if err := block.decodeActionPayloadChaincodeProposalPayload(_chaincodeProposalPayload, cap.ChaincodeProposalPayload); err != nil { + if err := block.decodeActionPayloadAction(_actionPayloadAction, capPayload.Action); err != nil { return err } - return nil + return block.decodeActionPayloadChaincodeProposalPayload(_chaincodeProposalPayload, capPayload.ChaincodeProposalPayload) } func (block *RawBlock) decodeActionPayloadChaincodeProposalPayload(chaincodeProposalPayload *ChaincodeProposalPayload, bytes []byte) error { @@ -329,13 +324,13 @@ func (block *RawBlock) decodeActionPayloadChaincodeProposalPayload(chaincodeProp chaincodeSpec.Type = ccSpec.ChaincodeSpec.Type.String() proposalPayloadInput.ChaincodeSpec = chaincodeSpec - chaincodeSpec.ChaincodeId = ccSpec.ChaincodeSpec.ChaincodeId + chaincodeSpec.ChaincodeID = ccSpec.ChaincodeSpec.ChaincodeId chaincodeInput := &ChaincodeSpecInput{} chaincodeSpec.Input = chaincodeInput chaincodeInputArgs := make([]interface{}, len(ccSpec.ChaincodeSpec.Input.Args)) - if chaincodeSpec.ChaincodeId.Name == "_lifecycle" { + if chaincodeSpec.ChaincodeID.Name == "_lifecycle" { funcName := string(ccSpec.ChaincodeSpec.Input.Args[0]) chaincodeInputArgs[0] = funcName argsBytes := ccSpec.ChaincodeSpec.Input.Args[1] @@ -368,10 +363,7 @@ func (block *RawBlock) decodeActionPayloadChaincodeProposalPayload(chaincodeProp func (block *RawBlock) decodeActionPayloadAction(_actionPayloadAction *ActionPayloadAction, action *peer.ChaincodeEndorsedAction) error { _proposalResponsePayload := &ProposalResponsePayload{} _actionPayloadAction.ProposalResponsePayload = _proposalResponsePayload - if err := block.decodeProposalResponsePayload(_proposalResponsePayload, action.ProposalResponsePayload); err != nil { - return err - } - return nil + return block.decodeProposalResponsePayload(_proposalResponsePayload, action.ProposalResponsePayload) } func (block *RawBlock) decodeProposalResponsePayload(_proposalResponsePayload *ProposalResponsePayload, proposalResponsePayload []byte) error { @@ -384,10 +376,7 @@ func (block *RawBlock) decodeProposalResponsePayload(_proposalResponsePayload *P _extension := &Extension{} _proposalResponsePayload.Extension = _extension - if err := block.decodeProposalResponsePayloadExtension(_extension, prp.Extension); err != nil { - return err - } - return nil + return block.decodeProposalResponsePayloadExtension(_extension, prp.Extension) } func (block *RawBlock) decodeProposalResponsePayloadExtension(_extension *Extension, extension []byte) error { @@ -396,7 +385,7 @@ func (block *RawBlock) decodeProposalResponsePayloadExtension(_extension *Extens return errors.Wrap(err, "error decoding chaincode action") } - _extension.ChaincodeId = cca.ChaincodeId + _extension.ChaincodeID = cca.ChaincodeId // skipping read/write sets in the action // decode events @@ -406,8 +395,8 @@ func (block *RawBlock) decodeProposalResponsePayloadExtension(_extension *Extens } _chaincodeEvent := &ChaincodeEvent{} _extension.Events = _chaincodeEvent - _chaincodeEvent.ChaincodeId = ccevt.ChaincodeId - _chaincodeEvent.TxId = ccevt.TxId + _chaincodeEvent.ChaincodeID = ccevt.ChaincodeId + _chaincodeEvent.TxID = ccevt.TxId _chaincodeEvent.EventName = ccevt.EventName _chaincodeEvent.Payload = ccevt.Payload @@ -452,9 +441,9 @@ func UnmarshalTransaction(txBytes []byte) (*peer.Transaction, error) { // UnmarshalChaincodeActionPayload unmarshals bytes to a ChaincodeActionPayload func UnmarshalChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) { - cap := &peer.ChaincodeActionPayload{} - err := proto.Unmarshal(capBytes, cap) - return cap, errors.Wrap(err, "error unmarshaling ChaincodeActionPayload") + capPayload := &peer.ChaincodeActionPayload{} + err := proto.Unmarshal(capBytes, capPayload) + return capPayload, errors.Wrap(err, "error unmarshaling ChaincodeActionPayload") } // UnmarshalProposalResponsePayload unmarshals bytes to a ProposalResponsePayload diff --git a/internal/fabric/utils/blockdecoder_test.go b/internal/fabric/utils/blockdecoder_test.go index e7eb4c1..4c95ed6 100644 --- a/internal/fabric/utils/blockdecoder_test.go +++ b/internal/fabric/utils/blockdecoder_test.go @@ -43,12 +43,12 @@ func TestDecodeEndorserBlockWithEvents(t *testing.T) { assert.Equal("u0o4mkkzs6", action.Header.Creator.Mspid) apa := action.Payload.Action - assert.Equal("asset_transfer", apa.ProposalResponsePayload.Extension.ChaincodeId.Name) - assert.Equal("1.1.0.u0ypz4p14q", apa.ProposalResponsePayload.Extension.ChaincodeId.Version) + assert.Equal("asset_transfer", apa.ProposalResponsePayload.Extension.ChaincodeID.Name) + assert.Equal("1.1.0.u0ypz4p14q", apa.ProposalResponsePayload.Extension.ChaincodeID.Version) event := apa.ProposalResponsePayload.Extension.Events - assert.Equal("asset_transfer", event.ChaincodeId) - assert.Regexp("[0-9a-f]{64}", event.TxId) + assert.Equal("asset_transfer", event.ChaincodeID) + assert.Regexp("[0-9a-f]{64}", event.TxID) assert.Regexp("[0-9]+", event.Timestamp) assert.Equal("AssetCreated", event.EventName) m, ok := event.Payload.([]byte) @@ -56,7 +56,7 @@ func TestDecodeEndorserBlockWithEvents(t *testing.T) { assert.Equal("{\"ID\":\"asset05\",\"color\":\"red\",\"size\":10,\"owner\":\"Tom\",\"appraisedValue\":123000}", string(m)) cpp := action.Payload.ChaincodeProposalPayload - assert.Equal("asset_transfer", cpp.Input.ChaincodeSpec.ChaincodeId.Name) + assert.Equal("asset_transfer", cpp.Input.ChaincodeSpec.ChaincodeID.Name) assert.Equal("CreateAsset", cpp.Input.ChaincodeSpec.Input.Args[0]) } @@ -77,11 +77,11 @@ func TestDecodeEndorserBlockLifecycleTxs(t *testing.T) { assert.Equal("u0o4mkkzs6", action.Header.Creator.Mspid) apa := action.Payload.Action - assert.Equal("_lifecycle", apa.ProposalResponsePayload.Extension.ChaincodeId.Name) - assert.Equal("syscc", apa.ProposalResponsePayload.Extension.ChaincodeId.Version) + assert.Equal("_lifecycle", apa.ProposalResponsePayload.Extension.ChaincodeID.Name) + assert.Equal("syscc", apa.ProposalResponsePayload.Extension.ChaincodeID.Version) cpp := action.Payload.ChaincodeProposalPayload - assert.Equal("_lifecycle", cpp.Input.ChaincodeSpec.ChaincodeId.Name) + assert.Equal("_lifecycle", cpp.Input.ChaincodeSpec.ChaincodeID.Name) assert.Equal("UNDEFINED", cpp.Input.ChaincodeSpec.Type) assert.Equal("ApproveChaincodeDefinitionForMyOrg", cpp.Input.ChaincodeSpec.Input.Args[0]) assert.Equal(int64(1), cpp.Input.ChaincodeSpec.Input.Args[1].(*lifecycle.ApproveChaincodeDefinitionForMyOrgArgs).Sequence) @@ -115,10 +115,10 @@ func TestGetEvents(t *testing.T) { events := GetEvents(testblock) assert.Equal(1, len(events)) entry := events[0] - assert.Equal("asset_transfer", entry.ChaincodeId) + assert.Equal("asset_transfer", entry.ChaincodeID) assert.Equal(uint64(16), entry.BlockNumber) assert.Equal("AssetCreated", entry.EventName) - assert.Regexp("[0-9a-f]{64}", entry.TransactionId) + assert.Regexp("[0-9a-f]{64}", entry.TransactionID) assert.Equal(0, entry.TransactionIndex) assert.Equal(int64(1641861241312746000), entry.Timestamp) } diff --git a/internal/fabric/utils/rawblock.go b/internal/fabric/utils/rawblock.go index 373141d..3e00522 100644 --- a/internal/fabric/utils/rawblock.go +++ b/internal/fabric/utils/rawblock.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -48,10 +48,10 @@ type PayloadHeader struct { } type ChannelHeader struct { - ChannelId string `json:"channel_id"` + ChannelID string `json:"channel_id"` Epoch string `json:"epoch"` Timestamp int64 `json:"timestamp"` - TxId string `json:"tx_id"` + TxID string `json:"tx_id"` Type string `json:"type"` Version int `json:"version"` } @@ -93,15 +93,15 @@ type ProposalResponsePayload struct { } type Extension struct { - ChaincodeId *peer.ChaincodeID `json:"chaincode_id"` + ChaincodeID *peer.ChaincodeID `json:"chaincode_id"` Events *ChaincodeEvent `json:"events"` // Response // Result } type ChaincodeEvent struct { - ChaincodeId string `json:"chaincodeId"` - TxId string `json:"transactionId"` + ChaincodeID string `json:"chaincodeId"` + TxID string `json:"transactionId"` Timestamp string `json:"timestamp"` EventName string `json:"eventName"` Payload interface{} `json:"payload"` @@ -117,7 +117,7 @@ type ProposalPayloadInput struct { } type ChaincodeSpec struct { - ChaincodeId *peer.ChaincodeID `json:"chaincode_id"` + ChaincodeID *peer.ChaincodeID `json:"chaincode_id"` Input *ChaincodeSpecInput `json:"input"` Type string `json:"type"` } diff --git a/internal/kafka/client.go b/internal/kafka/client.go index 22af004..ef6f3d9 100644 --- a/internal/kafka/client.go +++ b/internal/kafka/client.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,38 +29,38 @@ const ( kafkaConsumerReconnectDelaySecs = 5 ) -// KafkaGoRoutines defines goroutines for processing Kafka messages from KafkaCommon -type KafkaGoRoutines interface { - ConsumerMessagesLoop(consumer KafkaConsumer, producer KafkaProducer, wg *sync.WaitGroup) - ProducerErrorLoop(consumer KafkaConsumer, producer KafkaProducer, wg *sync.WaitGroup) - ProducerSuccessLoop(consumer KafkaConsumer, producer KafkaProducer, wg *sync.WaitGroup) +// GoRoutines defines goroutines for processing Kafka messages from KafkaCommon +type GoRoutines interface { + ConsumerMessagesLoop(consumer Consumer, producer Producer, wg *sync.WaitGroup) + ProducerErrorLoop(consumer Consumer, producer Producer, wg *sync.WaitGroup) + ProducerSuccessLoop(consumer Consumer, producer Producer, wg *sync.WaitGroup) } -// KafkaProducer provides the interface passed from KafkaCommon to produce messages (subset of sarama) -type KafkaProducer interface { +// Producer provides the interface passed from KafkaCommon to produce messages (subset of sarama) +type Producer interface { AsyncClose() Input() chan<- *sarama.ProducerMessage Successes() <-chan *sarama.ProducerMessage Errors() <-chan *sarama.ProducerError } -// KafkaConsumer provides the interface passed from KafkaCommon to consume messages -type KafkaConsumer interface { +// Consumer provides the interface passed from KafkaCommon to consume messages +type Consumer interface { Close() error Messages() <-chan *sarama.ConsumerMessage Errors() <-chan error MarkOffset(*sarama.ConsumerMessage, string) } -// KafkaFactory builds new clients -type KafkaFactory interface { - NewClient(KafkaCommon, *sarama.Config) (KafkaClient, error) +// Factory builds new clients +type Factory interface { + NewClient(Common, *sarama.Config) (Client, error) } -// KafkaClient is the kafka client -type KafkaClient interface { - NewProducer(KafkaCommon) (KafkaProducer, error) - NewConsumer(KafkaCommon) (KafkaConsumer, error) +// Client is the kafka client +type Client interface { + NewProducer(Common) (Producer, error) + NewConsumer(Common) (Consumer, error) Brokers() []*sarama.Broker } @@ -68,7 +68,7 @@ type KafkaClient interface { type SaramaKafkaFactory struct{} // NewClient - returns a new client -func (f *SaramaKafkaFactory) NewClient(k KafkaCommon, clientConf *sarama.Config) (c KafkaClient, err error) { +func (f *SaramaKafkaFactory) NewClient(k Common, clientConf *sarama.Config) (c Client, err error) { var client sarama.Client if client, err = sarama.NewClient(k.Conf().Brokers, clientConf); err == nil { c = &saramaKafkaClient{client: client} @@ -84,11 +84,11 @@ func (c *saramaKafkaClient) Brokers() []*sarama.Broker { return c.client.Brokers() } -func (c *saramaKafkaClient) NewProducer(k KafkaCommon) (KafkaProducer, error) { +func (c *saramaKafkaClient) NewProducer(_ Common) (Producer, error) { return sarama.NewAsyncProducerFromClient(c.client) } -func (c *saramaKafkaClient) NewConsumer(k KafkaCommon) (KafkaConsumer, error) { +func (c *saramaKafkaClient) NewConsumer(k Common) (Consumer, error) { h := newSaramaKafkaConsumerGroupHandler( &saramaConsumerGroupFactory{}, c.client, k.Conf().ConsumerGroup, @@ -186,7 +186,7 @@ func (h *saramaKafkaConsumerGroupHandler) Cleanup(session sarama.ConsumerGroupSe return nil } -func (h *saramaKafkaConsumerGroupHandler) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { +func (h *saramaKafkaConsumerGroupHandler) ConsumeClaim(_ sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { for msg := range claim.Messages() { h.messages <- msg } diff --git a/internal/kafka/common.go b/internal/kafka/common.go index 7c67512..0b3988b 100644 --- a/internal/kafka/common.go +++ b/internal/kafka/common.go @@ -1,13 +1,13 @@ -// Copyright 22021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,16 +31,16 @@ import ( log "github.com/sirupsen/logrus" ) -// KafkaCommon is the base interface for bridges that interact with Kafka -type KafkaCommon interface { +// Common is the base interface for bridges that interact with Kafka +type Common interface { ValidateConf() error Start() error Conf() conf.KafkaConf - Producer() KafkaProducer + Producer() Producer } -// NewKafkaCommon constructs a new KafkaCommon instance -func NewKafkaCommon(kf KafkaFactory, conf conf.KafkaConf, kafkaGoRoutines KafkaGoRoutines) (k KafkaCommon) { +// NewKafkaCommon constructs a new Common instance +func NewKafkaCommon(kf Factory, conf conf.KafkaConf, kafkaGoRoutines GoRoutines) (k Common) { k = &kafkaCommon{ factory: kf, kafkaGoRoutines: kafkaGoRoutines, @@ -53,14 +53,14 @@ func NewKafkaCommon(kf KafkaFactory, conf conf.KafkaConf, kafkaGoRoutines KafkaG // producer and a consumer-group type kafkaCommon struct { conf conf.KafkaConf - factory KafkaFactory - client KafkaClient + factory Factory + client Client signals chan os.Signal - consumer KafkaConsumer + consumer Consumer consumerWG sync.WaitGroup - producer KafkaProducer + producer Producer producerWG sync.WaitGroup - kafkaGoRoutines KafkaGoRoutines + kafkaGoRoutines GoRoutines saramaLogger saramaLogger } @@ -68,17 +68,17 @@ func (k *kafkaCommon) Conf() conf.KafkaConf { return k.conf } -func (k *kafkaCommon) Producer() KafkaProducer { +func (k *kafkaCommon) Producer() Producer { return k.producer } // ValidateConf performs common Cobra PreRunE logic for Kafka related commands func (k *kafkaCommon) ValidateConf() error { - return KafkaValidateConf(k.conf) + return ValidateConf(k.conf) } -// KafkaValidateConf validates supplied configuration -func KafkaValidateConf(kconf conf.KafkaConf) (err error) { +// ValidateConf validates supplied configuration +func ValidateConf(kconf conf.KafkaConf) (err error) { if kconf.TopicOut == "" { return errors.Errorf(errors.ConfigKafkaMissingOutputTopic) } @@ -116,8 +116,7 @@ func (k *kafkaCommon) connect() (err error) { log.Debugf("Kafka Bootstrap brokers: %s", k.conf.Brokers) if len(k.conf.Brokers) == 0 || k.conf.Brokers[0] == "" { - err = errors.Errorf(errors.ConfigKafkaMissingBrokers) - return + return errors.Errorf(errors.ConfigKafkaMissingBrokers) } sarama.Logger = k.saramaLogger @@ -125,7 +124,7 @@ func (k *kafkaCommon) connect() (err error) { var tlsConfig *tls.Config if tlsConfig, err = utils.CreateTLSConfiguration(&k.conf.TLS); err != nil { - return + return nil } if k.conf.SASL.Username != "" && k.conf.SASL.Password != "" { @@ -153,7 +152,7 @@ func (k *kafkaCommon) connect() (err error) { if k.client, err = k.factory.NewClient(k, clientConf); err != nil { log.Errorf("Failed to create Kafka client: %s", err) - return + return nil } var brokers []string for _, broker := range k.client.Brokers() { @@ -161,7 +160,7 @@ func (k *kafkaCommon) connect() (err error) { } log.Infof("Kafka Connected: %s", brokers) - return + return nil } func (k *kafkaCommon) createProducer() (err error) { @@ -170,7 +169,7 @@ func (k *kafkaCommon) createProducer() (err error) { log.Errorf("Failed to create Kafka producer: %s", err) return } - return + return nil } func (k *kafkaCommon) startProducer() (err error) { @@ -213,19 +212,19 @@ func (k *kafkaCommon) startConsumer() (err error) { func (k *kafkaCommon) Start() (err error) { if err = k.connect(); err != nil { - return + return nil } if err = k.createConsumer(); err != nil { - return + return nil } if err = k.createProducer(); err != nil { - return + return nil } if err = k.startConsumer(); err != nil { - return + return nil } if err = k.startProducer(); err != nil { - return + return nil } log.Debugf("Kafka initialization complete") @@ -238,7 +237,7 @@ func (k *kafkaCommon) Start() (err error) { k.consumerWG.Wait() log.Infof("Kafka Bridge complete") - return + return nil } - return + return nil } diff --git a/internal/kvstore/kvstore.go b/internal/kvstore/kvstore.go index 5b5219e..5bc0e0e 100644 --- a/internal/kvstore/kvstore.go +++ b/internal/kvstore/kvstore.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -60,12 +60,12 @@ func (k *levelDBKeyValueStore) warnIfErr(op, key string, err error) { } } -func (kv *levelDBKeyValueStore) Init() error { - db, err := leveldb.OpenFile(kv.path, nil) +func (k *levelDBKeyValueStore) Init() error { + db, err := leveldb.OpenFile(k.path, nil) if err != nil { - return errors.Errorf(errors.KVStoreDBLoad, kv.path, err) + return errors.Errorf(errors.KVStoreDBLoad, k.path, err) } - kv.db = db + k.db = db return nil } diff --git a/internal/messages/messages.go b/internal/messages/messages.go index 4c57b3c..db17a89 100644 --- a/internal/messages/messages.go +++ b/internal/messages/messages.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -99,9 +99,9 @@ type QueryChaincode struct { StrongRead bool `json:"strongread"` } -type GetTxById struct { +type GetTxByID struct { RequestCommon - TxId string `json:"txId"` + TxID string `json:"txId"` } type GetChainInfo struct { @@ -114,9 +114,9 @@ type GetBlock struct { BlockHash []byte } -type GetBlockByTxId struct { +type GetBlockByTxID struct { RequestCommon - TxId string + TxID string } // SendTransaction message instructs the bridge to install a contract diff --git a/internal/rest/async/asyncdispatcher.go b/internal/rest/async/asyncdispatcher.go index dea59cd..60ba6a3 100644 --- a/internal/rest/async/asyncdispatcher.go +++ b/internal/rest/async/asyncdispatcher.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,9 +30,9 @@ import ( log "github.com/sirupsen/logrus" ) -// AsyncDispatcher is passed in to process messages over a streaming system with +// Dispatcher is passed in to process messages over a streaming system with // a receipt store. Only used for POST methods, when fly-sync is not set to true -type AsyncDispatcher interface { +type Dispatcher interface { ValidateConf() error Run() error IsInitialized() bool @@ -51,10 +51,10 @@ type asyncRequestHandler interface { type asyncDispatcher struct { handler asyncRequestHandler - receiptStore receipt.ReceiptStore + receiptStore receipt.Store } -func NewAsyncDispatcher(conf *conf.RESTGatewayConf, processor tx.TxProcessor, receiptstore receipt.ReceiptStore) AsyncDispatcher { +func NewAsyncDispatcher(conf *conf.RESTGatewayConf, processor tx.Processor, receiptstore receipt.Store) Dispatcher { var handler asyncRequestHandler if len(conf.Kafka.Brokers) > 0 { handler = newKafkaHandler(conf.Kafka, receiptstore) @@ -96,7 +96,7 @@ func (d *asyncDispatcher) Close() { d.receiptStore.Close() } -func (w *asyncDispatcher) processMsg(ctx context.Context, msg *messages.SendTransaction, ack bool) (*messages.AsyncSentMsg, int, error) { +func (d *asyncDispatcher) processMsg(ctx context.Context, msg *messages.SendTransaction, ack bool) (*messages.AsyncSentMsg, int, error) { switch msg.Headers.MsgType { case messages.MsgTypeDeployContract, messages.MsgTypeSendTransaction: if msg.Headers.Signer == "" { @@ -114,7 +114,7 @@ func (w *asyncDispatcher) processMsg(ctx context.Context, msg *messages.SendTran // Pass to the handler log.Infof("Request handler accepted message. MsgID: %s Type: %s", msg.Headers.ID, msg.Headers.MsgType) - msgAck, status, err := w.handler.dispatchMsg(ctx, msg.Headers.ChannelID, msg.Headers.ID, msg, ack) + msgAck, status, err := d.handler.dispatchMsg(ctx, msg.Headers.ChannelID, msg.Headers.ID, msg, ack) if err != nil { return nil, status, err } @@ -125,10 +125,10 @@ func (w *asyncDispatcher) processMsg(ctx context.Context, msg *messages.SendTran }, 200, nil } -func (w *asyncDispatcher) Run() error { - return w.handler.run() +func (d *asyncDispatcher) Run() error { + return d.handler.run() } -func (w *asyncDispatcher) IsInitialized() bool { - return w.handler.isInitialized() +func (d *asyncDispatcher) IsInitialized() bool { + return d.handler.isInitialized() } diff --git a/internal/rest/async/directhandler.go b/internal/rest/async/directhandler.go index 98acb24..5cba198 100644 --- a/internal/rest/async/directhandler.go +++ b/internal/rest/async/directhandler.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -35,15 +35,15 @@ import ( type directHandler struct { initialized bool - receipts receipt.ReceiptStore + receipts receipt.Store conf *conf.RESTGatewayConf - processor tx.TxProcessor + processor tx.Processor inFlightMutex sync.Mutex inFlight map[string]*msgContext stopChan chan error } -func newDirectHandler(conf *conf.RESTGatewayConf, processor tx.TxProcessor, receiptstore receipt.ReceiptStore) *directHandler { +func newDirectHandler(conf *conf.RESTGatewayConf, processor tx.Processor, receiptstore receipt.Store) *directHandler { return &directHandler{ processor: processor, receipts: receiptstore, @@ -80,7 +80,7 @@ func (t *msgContext) SendErrorReply(status int, err error) { t.SendErrorReplyWithTX(status, err, "") } -func (t *msgContext) SendErrorReplyWithTX(status int, err error, txHash string) { +func (t *msgContext) SendErrorReplyWithTX(_ int, err error, txHash string) { log.Warnf("Failed to process message %s: %s", t, err) origBytes, _ := json.Marshal(t.msg) errMsg := messages.NewErrorReply(err, origBytes) @@ -108,7 +108,7 @@ func (t *msgContext) String() string { return fmt.Sprintf("MsgContext[%s/%s]", t.headers.MsgType, t.msgID) } -func (w *directHandler) dispatchMsg(ctx context.Context, key, msgID string, msg *messages.SendTransaction, ack bool) (string, int, error) { +func (w *directHandler) dispatchMsg(ctx context.Context, key, msgID string, msg *messages.SendTransaction, _ bool) (string, int, error) { w.inFlightMutex.Lock() numInFlight := len(w.inFlight) diff --git a/internal/rest/async/kafkahandler.go b/internal/rest/async/kafkahandler.go index 240d19a..7c5aefe 100644 --- a/internal/rest/async/kafkahandler.go +++ b/internal/rest/async/kafkahandler.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,8 +34,8 @@ import ( // kafkaHandler provides the HTTP -> Kafka bridge functionality type kafkaHandler struct { - kafka kafka.KafkaCommon - receipts receipt.ReceiptStore + kafka kafka.Common + receipts receipt.Store sendCond *sync.Cond pendingMsgs map[string]bool successMsgs map[string]*sarama.ProducerMessage @@ -44,7 +44,7 @@ type kafkaHandler struct { } // newWebhooksKafka constructor -func newKafkaHandler(kconf conf.KafkaConf, receipts receipt.ReceiptStore) *kafkaHandler { +func newKafkaHandler(kconf conf.KafkaConf, receipts receipt.Store) *kafkaHandler { w := &kafkaHandler{ receipts: receipts, sendCond: sync.NewCond(&sync.Mutex{}), @@ -80,7 +80,7 @@ func (w *kafkaHandler) waitForSend(msgID string) (msg *sarama.ProducerMessage, e } // ConsumerMessagesLoop - consume replies -func (w *kafkaHandler) ConsumerMessagesLoop(consumer kafka.KafkaConsumer, producer kafka.KafkaProducer, wg *sync.WaitGroup) { +func (w *kafkaHandler) ConsumerMessagesLoop(consumer kafka.Consumer, _ kafka.Producer, wg *sync.WaitGroup) { for msg := range consumer.Messages() { w.receipts.ProcessReceipt(msg.Value) @@ -91,7 +91,7 @@ func (w *kafkaHandler) ConsumerMessagesLoop(consumer kafka.KafkaConsumer, produc } // ProducerErrorLoop - consume errors -func (w *kafkaHandler) ProducerErrorLoop(consumer kafka.KafkaConsumer, producer kafka.KafkaProducer, wg *sync.WaitGroup) { +func (w *kafkaHandler) ProducerErrorLoop(_ kafka.Consumer, producer kafka.Producer, wg *sync.WaitGroup) { log.Debugf("Kafka handler listening for errors sending to Kafka") for err := range producer.Errors() { log.Errorf("Error sending message: %s", err) @@ -112,7 +112,7 @@ func (w *kafkaHandler) ProducerErrorLoop(consumer kafka.KafkaConsumer, producer } // ProducerSuccessLoop - consume successes -func (w *kafkaHandler) ProducerSuccessLoop(consumer kafka.KafkaConsumer, producer kafka.KafkaProducer, wg *sync.WaitGroup) { +func (w *kafkaHandler) ProducerSuccessLoop(_ kafka.Consumer, producer kafka.Producer, wg *sync.WaitGroup) { log.Debugf("Kafka handler listening for successful sends to Kafka") for msg := range producer.Successes() { log.Infof("Kafka handler sent message ok: %s", msg.Metadata) diff --git a/internal/rest/identity/identity.go b/internal/rest/identity/identity.go index 1931dfe..5682973 100644 --- a/internal/rest/identity/identity.go +++ b/internal/rest/identity/identity.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -56,7 +56,7 @@ type RevokeRequest struct { GenCRL bool `json:"generateCRL"` } -type IdentityResponse struct { +type Response struct { Name string `json:"name"` Success bool `json:"success"` } @@ -66,11 +66,11 @@ type RevokeResponse struct { CRL []byte `json:"CRL"` } -type IdentityClient interface { +type Client interface { Register(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*RegisterResponse, *restutil.RestError) Modify(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*RegisterResponse, *restutil.RestError) - Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*IdentityResponse, *restutil.RestError) - Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*IdentityResponse, *restutil.RestError) + Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*Response, *restutil.RestError) + Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*Response, *restutil.RestError) Revoke(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*RevokeResponse, *restutil.RestError) List(res http.ResponseWriter, req *http.Request, params httprouter.Params) ([]*Identity, *restutil.RestError) Get(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*Identity, *restutil.RestError) diff --git a/internal/rest/receipt/leveldb.go b/internal/rest/receipt/leveldb.go index 5e81003..b06ed11 100644 --- a/internal/rest/receipt/leveldb.go +++ b/internal/rest/receipt/leveldb.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -44,7 +44,7 @@ type levelDBReceipts struct { func newLevelDBReceipts(conf *conf.ReceiptsDBConf) *levelDBReceipts { store := kvstore.NewLDBKeyValueStore(conf.LevelDB.Path) t := time.Unix(1000000, 0) - entropy := ulid.Monotonic(rand.New(rand.NewSource(t.UnixNano())), 0) + entropy := ulid.Monotonic(rand.New(rand.NewSource(t.UnixNano())), 0) // #nosec return &levelDBReceipts{ conf: conf, @@ -54,7 +54,7 @@ func newLevelDBReceipts(conf *conf.ReceiptsDBConf) *levelDBReceipts { } } -func (m *levelDBReceipts) ValidateConf() error { +func (l *levelDBReceipts) ValidateConf() error { // leveldb creates the target directory on demand, no need to check for existence return nil } @@ -142,11 +142,12 @@ func (l *levelDBReceipts) GetReceipts(skip, limit int, ids []string, sinceEpochM if from != "" || to != "" { lookupKeysByFromAndTo = l.getLookupKeysByFromAndTo(from, to, start, endKey, limit) } - if len(ids) > 0 && from == "" && to == "" { + switch { + case len(ids) > 0 && from == "" && to == "": lookupKeys = lookupKeysByIDs - } else if len(ids) == 0 && (from != "" || to != "") { + case len(ids) == 0 && (from != "" || to != ""): lookupKeys = lookupKeysByFromAndTo - } else if len(ids) > 0 && (from != "" || to != "") { + case len(ids) > 0 && (from != "" || to != ""): lookupKeys = intersect(lookupKeysByIDs, lookupKeysByFromAndTo) } if lookupKeys != nil { @@ -198,10 +199,9 @@ func (l *levelDBReceipts) getReceiptsNoFilter(itr kvstore.KVIterator, skip, limi if err != nil { log.Errorf("Failed to decode stored receipt for request ID %s\n", itr.Key()) continue - } else { - receipt["_sequenceKey"] = key - results = append(results, receipt) } + receipt["_sequenceKey"] = key + results = append(results, receipt) } index++ } @@ -214,10 +214,9 @@ func (l *levelDBReceipts) GetReceipt(requestID string) (*map[string]interface{}, if err != nil { if err == kvstore.ErrorNotFound { return nil, nil - } else { - log.Errorf("Failed to retrieve the entry for the original key: %s. %s\n", requestID, err) - return nil, errors.Errorf(errors.LevelDBFailedRetriveOriginalKey, requestID, err) } + log.Errorf("Failed to retrieve the entry for the original key: %s. %s\n", requestID, err) + return nil, errors.Errorf(errors.LevelDBFailedRetriveOriginalKey, requestID, err) } // returned val represents the composite key, use it to retrieve the actual content lookupKey := string(val) @@ -264,9 +263,8 @@ func (l *levelDBReceipts) getLookupKeysByIDs(ids []string, start, end string) [] if err != nil { log.Warnf("Failed to locate entry for key ID %s", id) continue - } else { - result = append(result, string(val)) } + result = append(result, string(val)) } sort.Strings(result) // since our query searches in descending order, while sort.SearchString requires ascending order @@ -293,11 +291,12 @@ func (l *levelDBReceipts) getLookupKeysByFromAndTo(from, to string, start, end s } var result []string - if from != "" && to == "" { + switch { + case from != "" && to == "": result = fromKeys - } else if from == "" && to != "" { + case from == "" && to != "": result = toKeys - } else { + default: // find the intersection of the 2 slices, note that both slices are sorted result = intersect(fromKeys, toKeys) } diff --git a/internal/rest/receipt/leveldb_test.go b/internal/rest/receipt/leveldb_test.go index eb925c6..a0d25b0 100644 --- a/internal/rest/receipt/leveldb_test.go +++ b/internal/rest/receipt/leveldb_test.go @@ -520,7 +520,7 @@ func TestLevelDBReceiptsGetReceiptErrorGeneratedID(t *testing.T) { } _, err := r.GetReceipt("receipt1") - assert.Regexp("Failed to retrieve the entry for the generated ID: receipt1. pop", err) + assert.Regexp("failed to retrieve the entry for the generated ID: receipt1. pop", err) } func TestLevelDBReceiptsGetReceiptBadDataID(t *testing.T) { diff --git a/internal/rest/receipt/memdb.go b/internal/rest/receipt/memdb.go index e9ac252..2d1ea87 100644 --- a/internal/rest/receipt/memdb.go +++ b/internal/rest/receipt/memdb.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -48,7 +48,7 @@ func (m *memoryReceipts) Init() error { return nil } -func (m *memoryReceipts) GetReceipts(skip, limit int, ids []string, sinceEpochMS int64, from, to, start string) (*[]map[string]interface{}, error) { +func (m *memoryReceipts) GetReceipts(skip, limit int, ids []string, sinceEpochMS int64, from, to, _ string) (*[]map[string]interface{}, error) { m.mux.Lock() defer m.mux.Unlock() @@ -84,7 +84,7 @@ func (m *memoryReceipts) GetReceipt(requestID string) (*map[string]interface{}, return nil, nil } -func (m *memoryReceipts) AddReceipt(requestID string, receipt *map[string]interface{}) error { +func (m *memoryReceipts) AddReceipt(_ string, receipt *map[string]interface{}) error { m.mux.Lock() defer m.mux.Unlock() diff --git a/internal/rest/receipt/mongodb.go b/internal/rest/receipt/mongodb.go index 41b87da..f39ab30 100644 --- a/internal/rest/receipt/mongodb.go +++ b/internal/rest/receipt/mongodb.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -118,7 +118,7 @@ func (m *mongoReceipts) Init() (err error) { err = m.mgo.Connect(m.config.MongoDB.URL, time.Duration(m.config.MongoDB.ConnectTimeoutMS)*time.Millisecond) if err != nil { err = errors.Errorf(errors.ReceiptStoreMongoDBConnect, err) - return + return err } m.collection = m.mgo.GetCollection(m.config.MongoDB.Database, m.config.MongoDB.Collection) if collErr := m.collection.Create(&mgo.CollectionInfo{ @@ -136,22 +136,21 @@ func (m *mongoReceipts) Init() (err error) { Sparse: true, } if err = m.collection.EnsureIndex(index); err != nil { - err = errors.Errorf(errors.ReceiptStoreMongoDBIndex, err) - return + return errors.Errorf(errors.ReceiptStoreMongoDBIndex, err) } log.Infof("Connected to MongoDB on %s DB=%s Collection=%s", m.config.MongoDB.URL, m.config.MongoDB.Database, m.config.MongoDB.Collection) - return + return nil } // AddReceipt processes an individual reply message, and contains all errors // To account for any transitory failures writing to mongoDB, it retries adding receipt with a backoff -func (m *mongoReceipts) AddReceipt(requestID string, receipt *map[string]interface{}) (err error) { +func (m *mongoReceipts) AddReceipt(_ string, receipt *map[string]interface{}) (err error) { return m.collection.Insert(*receipt) } // GetReceipts Returns recent receipts with skip & limit -func (m *mongoReceipts) GetReceipts(skip, limit int, ids []string, sinceEpochMS int64, from, to, start string) (*[]map[string]interface{}, error) { +func (m *mongoReceipts) GetReceipts(skip, limit int, ids []string, sinceEpochMS int64, from, to, _ string) (*[]map[string]interface{}, error) { filter := bson.M{} if len(ids) > 0 { filter["_id"] = bson.M{ diff --git a/internal/rest/receipt/receiptstore.go b/internal/rest/receipt/receiptstore.go index 9a9209d..edaff1f 100644 --- a/internal/rest/receipt/receiptstore.go +++ b/internal/rest/receipt/receiptstore.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -43,7 +43,7 @@ const ( var uuidCharsVerifier, _ = regexp.Compile("^[0-9a-zA-Z-]+$") -type ReceiptStore interface { +type Store interface { Init(ws.WebSocketChannels, ...api.ReceiptStorePersistence) error ValidateConf() error ProcessReceipt(msgBytes []byte) @@ -58,15 +58,16 @@ type receiptStore struct { ws ws.WebSocketChannels } -func NewReceiptStore(config *conf.RESTGatewayConf) ReceiptStore { +func NewReceiptStore(config *conf.RESTGatewayConf) Store { var receiptStorePersistence api.ReceiptStorePersistence - if config.Receipts.LevelDB.Path != "" { + switch { + case config.Receipts.LevelDB.Path != "": leveldbStore := newLevelDBReceipts(&config.Receipts) receiptStorePersistence = leveldbStore - } else if config.Receipts.MongoDB.URL != "" { + case config.Receipts.MongoDB.URL != "": mongoStore := newMongoReceipts(&config.Receipts) receiptStorePersistence = mongoStore - } else { + default: memStore := newMemoryReceipts(&config.Receipts) receiptStorePersistence = memStore } @@ -92,10 +93,9 @@ func (r *receiptStore) Init(ws ws.WebSocketChannels, mocked ...api.ReceiptStoreP // only used in test code to pass in a mocked impl r.persistence = mocked[0] return nil - } else { - // the regular runtime does this - return r.persistence.Init() } + // the regular runtime does this + return r.persistence.Init() } func (r *receiptStore) extractHeaders(parsedMsg map[string]interface{}) map[string]interface{} { @@ -190,10 +190,10 @@ func (r *receiptStore) writeReceipt(requestID string, receipt map[string]interfa } // getReplies handles a HTTP request for recent replies -func (r *receiptStore) GetReceipts(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (r *receiptStore) GetReceipts(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) - err := auth.AuthListAsyncReplies(req.Context()) + err := auth.ListAsyncReplies(req.Context()) if err != nil { log.Errorf("Error querying replies: %s", err) errors.RestErrReply(res, req, errors.Errorf(errors.Unauthorized), 401) @@ -281,7 +281,7 @@ func (r *receiptStore) GetReceipts(res http.ResponseWriter, req *http.Request, p func (r *receiptStore) GetReceipt(res http.ResponseWriter, req *http.Request, params httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) - err := auth.AuthReadAsyncReplyByUUID(req.Context()) + err := auth.ReadAsyncReplyByUUID(req.Context()) if err != nil { log.Errorf("Error querying reply: %s", err) errors.RestErrReply(res, req, errors.Errorf(errors.Unauthorized), 401) diff --git a/internal/rest/restgateway.go b/internal/rest/restgateway.go index d9077f9..8f6c908 100644 --- a/internal/rest/restgateway.go +++ b/internal/rest/restgateway.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,13 +45,13 @@ const ( MaxHeaderSize = 16 * 1024 ) -// RESTGateway as the HTTP gateway interface for fabconnect -type RESTGateway struct { +// Gateway as the HTTP gateway interface for fabconnect +type Gateway struct { config *conf.RESTGatewayConf - processor tx.TxProcessor - receiptStore receipt.ReceiptStore - syncDispatcher restsync.SyncDispatcher - asyncDispatcher restasync.AsyncDispatcher + processor tx.Processor + receiptStore receipt.Store + syncDispatcher restsync.Dispatcher + asyncDispatcher restasync.Dispatcher sm events.SubscriptionManager ws ws.WebSocketServer rpc client.RPCClient @@ -68,8 +68,8 @@ type statusMsg struct { } // NewRESTGateway constructor -func NewRESTGateway(config *conf.RESTGatewayConf) *RESTGateway { - g := &RESTGateway{ +func NewRESTGateway(config *conf.RESTGatewayConf) *Gateway { + g := &Gateway{ config: config, sendCond: sync.NewCond(&sync.Mutex{}), pendingMsgs: make(map[string]bool), @@ -81,8 +81,8 @@ func NewRESTGateway(config *conf.RESTGatewayConf) *RESTGateway { return g } -func (g *RESTGateway) Init() error { - g.syncDispatcher = restsync.NewSyncDispatcher(g.processor) +func (g *Gateway) Init() error { + g.syncDispatcher = restsync.NewDispatcher(g.processor) g.asyncDispatcher = restasync.NewAsyncDispatcher(g.config, g.processor, g.receiptStore) err := g.asyncDispatcher.ValidateConf() if err != nil { @@ -118,7 +118,7 @@ func (g *RESTGateway) Init() error { return nil } -func (g *RESTGateway) ValidateConf() error { +func (g *Gateway) ValidateConf() error { // HTTP and RPC configurations are mandatory if g.config.HTTP.Port == 0 { return errors.Errorf(errors.ConfigRESTGatewayRequiredHTTPPort) @@ -133,12 +133,13 @@ func (g *RESTGateway) ValidateConf() error { } // Start kicks off the HTTP listener and router -func (g *RESTGateway) Start() error { +func (g *Gateway) Start() error { tlsConfig, err := utils.CreateTLSConfiguration(&g.config.HTTP.TLS) if err != nil { return err } - + // TODO: Fix linting: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server + // #nosec g.srv = &http.Server{ Addr: fmt.Sprintf("%s:%d", g.config.HTTP.LocalAddr, g.config.HTTP.Port), TLSConfig: tlsConfig, @@ -194,7 +195,7 @@ func (g *RESTGateway) Start() error { return err } -func (g *RESTGateway) Shutdown() { +func (g *Gateway) Shutdown() { if g.sm != nil { g.sm.Close() } diff --git a/internal/rest/restgateway_test.go b/internal/rest/restgateway_test.go index 42709ff..087becb 100644 --- a/internal/rest/restgateway_test.go +++ b/internal/rest/restgateway_test.go @@ -68,7 +68,7 @@ func teardown() { test.Teardown(tmpdir) } -func newTestGateway(t *testing.T, mockDB ...bool) (*assert.Assertions, *RESTGateway, *sync.WaitGroup, *mockreceipt.ReceiptStorePersistence, *mockfabric.RPCClient, *mockidentity.IdentityClient) { +func newTestGateway(t *testing.T, mockDB ...bool) (*assert.Assertions, *Gateway, *sync.WaitGroup, *mockreceipt.ReceiptStorePersistence, *mockfabric.RPCClient, *mockidentity.IdentityClient) { assert := assert.New(t) auth.RegisterSecurityModule(&authtest.TestSecurityModule{}) testConfig.HTTP.Port = lastPort @@ -307,7 +307,7 @@ func TestIdentitiesEndpoints(t *testing.T) { assert.Equal(2, len(result3)) assert.Equal("user1", result3["name"]) - mockResult2 := &identity.IdentityResponse{ + mockResult2 := &identity.Response{ Name: "user1", Success: true, } @@ -963,7 +963,7 @@ func TestEventsAPI(t *testing.T) { resp, _ = http.DefaultClient.Do(req) _ = json.NewDecoder(resp.Body).Decode(&errorResp) assert.Equal(400, resp.StatusCode) - assert.Equal("Invalid initial block: must be an integer, an empty string or 'newest'", errorResp.Message) + assert.Equal("invalid initial block: must be an integer, an empty string or 'newest'", errorResp.Message) // POST /subscriptions failed calls due to bad "payloadType" value url, _ = url.Parse(fmt.Sprintf("http://localhost:%d/subscriptions", g.config.HTTP.Port)) @@ -1086,7 +1086,7 @@ func TestEventsAPI(t *testing.T) { resp, _ = http.DefaultClient.Do(req) _ = json.NewDecoder(resp.Body).Decode(&errorResp) assert.Equal(400, resp.StatusCode) - assert.Equal("Invalid initial block: must be an integer, an empty string or 'newest'", errorResp.Message) + assert.Equal("invalid initial block: must be an integer, an empty string or 'newest'", errorResp.Message) // DELETE /subscriptions/:subId failed calls due to bad ID url, _ = url.Parse(fmt.Sprintf("http://localhost:%d/subscriptions/badId", g.config.HTTP.Port)) diff --git a/internal/rest/router.go b/internal/rest/router.go index 68a4ff6..26725a8 100644 --- a/internal/rest/router.go +++ b/internal/rest/router.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -44,15 +44,15 @@ const ( ) type router struct { - syncDispatcher restsync.SyncDispatcher - asyncDispatcher restasync.AsyncDispatcher - identityClient identity.IdentityClient + syncDispatcher restsync.Dispatcher + asyncDispatcher restasync.Dispatcher + identityClient identity.Client subManager events.SubscriptionManager ws ws.WebSocketServer httpRouter *httprouter.Router } -func newRouter(syncDispatcher restsync.SyncDispatcher, asyncDispatcher restasync.AsyncDispatcher, idClient identity.IdentityClient, sm events.SubscriptionManager, ws ws.WebSocketServer) *router { +func newRouter(syncDispatcher restsync.Dispatcher, asyncDispatcher restasync.Dispatcher, idClient identity.Client, sm events.SubscriptionManager, ws ws.WebSocketServer) *router { r := httprouter.New() cors.Default().Handler(r) return &router{ @@ -79,7 +79,7 @@ func (r *router) addRoutes() { r.httpRouter.GET("/chaininfo", r.queryChainInfo) r.httpRouter.GET("/blocks/:blockNumber", r.queryBlock) - r.httpRouter.GET("/blockByTxId/:txId", r.queryBlockByTxId) + r.httpRouter.GET("/blockByTxId/:txId", r.queryBlockByTxID) r.httpRouter.POST("/query", r.queryChaincode) r.httpRouter.POST("/transactions", r.sendTransaction) @@ -129,20 +129,20 @@ func (r *router) wsHandler(res http.ResponseWriter, req *http.Request, params ht r.ws.NewConnection(res, req, params) } -func (r *router) statusHandler(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { +func (r *router) statusHandler(res http.ResponseWriter, _ *http.Request, _ httprouter.Params) { reply, _ := json.Marshal(&statusMsg{OK: true}) res.Header().Set("Content-Type", "application/json") res.WriteHeader(200) _, _ = res.Write(reply) } -func (r *router) serveSwagger(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (r *router) serveSwagger(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) fs := http.FileServer(http.Dir("./openapi")) fs.ServeHTTP(res, req) } -func (r *router) serveSwaggerUI(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (r *router) serveSwaggerUI(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) res.Header().Add("Content-Type", "text/html") _, _ = res.Write(utils.SwaggerUIHTML(req.Context())) @@ -160,10 +160,10 @@ func (r *router) queryBlock(res http.ResponseWriter, req *http.Request, params h r.syncDispatcher.GetBlock(res, req, params) } -func (r *router) queryBlockByTxId(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (r *router) queryBlockByTxID(res http.ResponseWriter, req *http.Request, params httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) // query requests are always synchronous - r.syncDispatcher.GetBlockByTxId(res, req, params) + r.syncDispatcher.GetBlockByTxID(res, req, params) } func (r *router) queryChaincode(res http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -175,7 +175,7 @@ func (r *router) queryChaincode(res http.ResponseWriter, req *http.Request, para func (r *router) getTransaction(res http.ResponseWriter, req *http.Request, params httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) // query requests are always synchronous - r.syncDispatcher.GetTxById(res, req, params) + r.syncDispatcher.GetTxByID(res, req, params) } func (r *router) sendTransaction(res http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -448,7 +448,7 @@ func (r *router) resetSubscription(res http.ResponseWriter, req *http.Request, p marshalAndReply(res, req, result) } -func (r *router) dumpGoRoutines(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (r *router) dumpGoRoutines(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { log.Infof("--> %s %s", req.Method, req.URL) _ = pprof.Lookup("goroutine").WriteTo(res, 1) } diff --git a/internal/rest/sync/syncdispatcher.go b/internal/rest/sync/syncdispatcher.go index 40a59bf..c9ca641 100644 --- a/internal/rest/sync/syncdispatcher.go +++ b/internal/rest/sync/syncdispatcher.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,7 +26,7 @@ import ( "sync" "time" - "github.com/hyperledger/firefly-fabconnect/internal/errors" + internalErrors "github.com/hyperledger/firefly-fabconnect/internal/errors" "github.com/hyperledger/firefly-fabconnect/internal/messages" restutil "github.com/hyperledger/firefly-fabconnect/internal/rest/utils" "github.com/hyperledger/firefly-fabconnect/internal/tx" @@ -36,23 +36,23 @@ import ( log "github.com/sirupsen/logrus" ) -// SyncDispatcher abstracts the processing of the transactions and queries +// Dispatcher abstracts the processing of the transactions and queries // synchronously. We perform those within this package. -type SyncDispatcher interface { +type Dispatcher interface { DispatchMsgSync(ctx context.Context, res http.ResponseWriter, req *http.Request, msg interface{}) QueryChaincode(res http.ResponseWriter, req *http.Request, params httprouter.Params) - GetTxById(res http.ResponseWriter, req *http.Request, params httprouter.Params) + GetTxByID(res http.ResponseWriter, req *http.Request, params httprouter.Params) GetChainInfo(res http.ResponseWriter, req *http.Request, params httprouter.Params) GetBlock(res http.ResponseWriter, req *http.Request, params httprouter.Params) - GetBlockByTxId(res http.ResponseWriter, req *http.Request, params httprouter.Params) + GetBlockByTxID(res http.ResponseWriter, req *http.Request, params httprouter.Params) } -type syncDispatcher struct { - processor tx.TxProcessor +type dispatcher struct { + processor tx.Processor } -func NewSyncDispatcher(processor tx.TxProcessor) SyncDispatcher { - return &syncDispatcher{ +func NewDispatcher(processor tx.Processor) Dispatcher { + return &dispatcher{ processor: processor, } } @@ -71,12 +71,11 @@ func (t *syncTxInflight) Context() context.Context { func (t *syncTxInflight) Headers() *messages.CommonHeaders { query, ok := t.msg.(*messages.QueryChaincode) if !ok { - byId, ok := t.msg.(*messages.GetTxById) + byID, ok := t.msg.(*messages.GetTxByID) if !ok { return &t.msg.(*messages.SendTransaction).Headers.CommonHeaders - } else { - return &byId.Headers.CommonHeaders } + return &byID.Headers.CommonHeaders } return &query.Headers.CommonHeaders } @@ -86,12 +85,12 @@ func (t *syncTxInflight) Unmarshal(msg interface{}) error { return nil } -func (t *syncTxInflight) SendErrorReply(status int, err error) { +func (t *syncTxInflight) SendErrorReply(_ int, err error) { t.replyProcessor.ReplyWithError(err) } func (t *syncTxInflight) SendErrorReplyWithTX(status int, err error, txHash string) { - t.SendErrorReply(status, errors.Errorf(errors.RESTGatewaySyncWrapErrorWithTXDetail, txHash, err)) + t.SendErrorReply(status, internalErrors.Errorf(internalErrors.RESTGatewaySyncWrapErrorWithTXDetail, txHash, err)) } func (t *syncTxInflight) Reply(replyMessage messages.ReplyWithHeaders) { @@ -124,7 +123,7 @@ type syncResponder struct { } func (i *syncResponder) ReplyWithError(err error) { - errors.RestErrReply(i.res, i.req, err, 500) + internalErrors.RestErrReply(i.res, i.req, err, 500) i.done = true i.waiter.Broadcast() } @@ -157,7 +156,7 @@ func (i *syncResponder) ReplyWithReceipt(receipt messages.ReplyWithHeaders) { } // handles transactions that require tracking transaction results -func (d *syncDispatcher) DispatchMsgSync(ctx context.Context, res http.ResponseWriter, req *http.Request, msg interface{}) { +func (d *dispatcher) DispatchMsgSync(ctx context.Context, res http.ResponseWriter, req *http.Request, msg interface{}) { responder := &syncResponder{ res: res, req: req, @@ -181,11 +180,11 @@ func (d *syncDispatcher) DispatchMsgSync(ctx context.Context, res http.ResponseW // synchronous request to Fabric API endpoints // -func (d *syncDispatcher) QueryChaincode(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *dispatcher) QueryChaincode(res http.ResponseWriter, req *http.Request, params httprouter.Params) { start := time.Now().UTC() msg, err := restutil.BuildQueryMessage(res, req, params) if err != nil { - errors.RestErrReply(res, req, err.Error, err.StatusCode) + internalErrors.RestErrReply(res, req, err.Error, err.StatusCode) return } @@ -193,7 +192,7 @@ func (d *syncDispatcher) QueryChaincode(res http.ResponseWriter, req *http.Reque callTime := time.Now().UTC().Sub(start) if err1 != nil { log.Warnf("Query [chaincode=%s, func=%s] failed to send: %s [%.2fs]", msg.Headers.ChaincodeName, msg.Function, err1, callTime.Seconds()) - errors.RestErrReply(res, req, err1, 500) + internalErrors.RestErrReply(res, req, err1, 500) return } log.Infof("Query [chaincode=%s, func=%s] [%.2fs]", msg.Headers.ChaincodeName, msg.Function, callTime.Seconds()) @@ -204,38 +203,38 @@ func (d *syncDispatcher) QueryChaincode(res http.ResponseWriter, req *http.Reque sendReply(res, req, reply) } -func (d *syncDispatcher) GetTxById(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *dispatcher) GetTxByID(res http.ResponseWriter, req *http.Request, params httprouter.Params) { start := time.Now().UTC() - msg, err := restutil.BuildTxByIdMessage(res, req, params) + msg, err := restutil.BuildTxByIDMessage(res, req, params) if err != nil { - errors.RestErrReply(res, req, err.Error, err.StatusCode) + internalErrors.RestErrReply(res, req, err.Error, err.StatusCode) return } - result, err1 := d.processor.GetRPCClient().QueryTransaction(msg.Headers.ChannelID, msg.Headers.Signer, msg.TxId) + result, err1 := d.processor.GetRPCClient().QueryTransaction(msg.Headers.ChannelID, msg.Headers.Signer, msg.TxID) callTime := time.Now().UTC().Sub(start) if err1 != nil { - log.Warnf("Query transaction %s failed to send: %s [%.2fs]", msg.TxId, err1, callTime.Seconds()) - errors.RestErrReply(res, req, err1, 500) + log.Warnf("Query transaction %s failed to send: %s [%.2fs]", msg.TxID, err1, callTime.Seconds()) + internalErrors.RestErrReply(res, req, err1, 500) return } - log.Infof("Query transaction %s [%.2fs]", msg.TxId, callTime.Seconds()) + log.Infof("Query transaction %s [%.2fs]", msg.TxID, callTime.Seconds()) var reply messages.LedgerQueryResult reply.Result = result sendReply(res, req, reply) } -func (d *syncDispatcher) GetChainInfo(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *dispatcher) GetChainInfo(res http.ResponseWriter, req *http.Request, params httprouter.Params) { msg, err := restutil.BuildGetChainInfoMessage(res, req, params) if err != nil { - errors.RestErrReply(res, req, err.Error, err.StatusCode) + internalErrors.RestErrReply(res, req, err.Error, err.StatusCode) return } result, err1 := d.processor.GetRPCClient().QueryChainInfo(msg.Headers.ChannelID, msg.Headers.Signer) if err1 != nil { - errors.RestErrReply(res, req, err1, 500) + internalErrors.RestErrReply(res, req, err1, 500) return } var reply messages.LedgerQueryResult @@ -248,16 +247,16 @@ func (d *syncDispatcher) GetChainInfo(res http.ResponseWriter, req *http.Request sendReply(res, req, reply) } -func (d *syncDispatcher) GetBlock(res http.ResponseWriter, req *http.Request, params httprouter.Params) { +func (d *dispatcher) GetBlock(res http.ResponseWriter, req *http.Request, params httprouter.Params) { msg, err := restutil.BuildGetBlockMessage(res, req, params) if err != nil { - errors.RestErrReply(res, req, err.Error, err.StatusCode) + internalErrors.RestErrReply(res, req, err.Error, err.StatusCode) return } rawblock, block, err1 := d.processor.GetRPCClient().QueryBlock(msg.Headers.ChannelID, msg.Headers.Signer, msg.BlockNumber, msg.BlockHash) if err1 != nil { - errors.RestErrReply(res, req, err1, 500) + internalErrors.RestErrReply(res, req, err1, 500) return } var reply messages.LedgerQueryResult @@ -269,16 +268,16 @@ func (d *syncDispatcher) GetBlock(res http.ResponseWriter, req *http.Request, pa sendReply(res, req, reply) } -func (d *syncDispatcher) GetBlockByTxId(res http.ResponseWriter, req *http.Request, params httprouter.Params) { - msg, err := restutil.BuildGetBlockByTxIdMessage(res, req, params) +func (d *dispatcher) GetBlockByTxID(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + msg, err := restutil.BuildGetBlockByTxIDMessage(res, req, params) if err != nil { - errors.RestErrReply(res, req, err.Error, err.StatusCode) + internalErrors.RestErrReply(res, req, err.Error, err.StatusCode) return } - rawblock, block, err1 := d.processor.GetRPCClient().QueryBlockByTxId(msg.Headers.ChannelID, msg.Headers.Signer, msg.TxId) + rawblock, block, err1 := d.processor.GetRPCClient().QueryBlockByTxID(msg.Headers.ChannelID, msg.Headers.Signer, msg.TxID) if err1 != nil { - errors.RestErrReply(res, req, err1, 500) + internalErrors.RestErrReply(res, req, err1, 500) return } var reply messages.LedgerQueryResult diff --git a/internal/rest/test/util.go b/internal/rest/test/util.go index dcd2485..a2c4ff3 100644 --- a/internal/rest/test/util.go +++ b/internal/rest/test/util.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -23,10 +23,10 @@ import ( "path" "strings" - "github.com/hyperledger/firefly-fabconnect/internal/conf" + config "github.com/hyperledger/firefly-fabconnect/internal/conf" ) -func Setup() (string, *conf.RESTGatewayConf) { +func Setup() (string, *config.RESTGatewayConf) { var testConfigJSON = `{ "maxInFlight": 10, "maxTXWaitTime": 60, @@ -148,7 +148,7 @@ J4OVv51lNtDLT9k= // set up CA certs certPath := path.Join(tmpdir, "test.crt") - _ = os.WriteFile(certPath, []byte(testCert), 0644) + _ = os.WriteFile(certPath, []byte(testCert), 0644) // #nosec // modify ca cert path ccp := strings.Replace(testRPCConfig, "/tmp-cert", certPath, 1) // set up crypto path for each org @@ -160,7 +160,7 @@ J4OVv51lNtDLT9k= ccp = strings.Replace(ccp, "/tmp-crypto-path-org2", org2MSPPath, 1) // set up CCP ccpPath := path.Join(tmpdir, "ccp.yml") - _ = os.WriteFile(ccpPath, []byte(ccp), 0644) + _ = os.WriteFile(ccpPath, []byte(ccp), 0644) // #nosec testConfigJSON = strings.Replace(testConfigJSON, "/test-config-path", ccpPath, 1) // setup receipt store receiptStorePath := path.Join(tmpdir, "receipts") @@ -169,11 +169,11 @@ J4OVv51lNtDLT9k= } testConfigJSON = strings.Replace(testConfigJSON, "/test-receipt-path", receiptStorePath, 1) // write the config file - _ = os.WriteFile(path.Join(tmpdir, "config.json"), []byte(testConfigJSON), 0644) - _ = os.WriteFile(path.Join(tmpdir, "config-bad.json"), []byte(testConfigJSONBad), 0644) + _ = os.WriteFile(path.Join(tmpdir, "config.json"), []byte(testConfigJSON), 0644) // #nosec + _ = os.WriteFile(path.Join(tmpdir, "config-bad.json"), []byte(testConfigJSONBad), 0644) // #nosec // init the default config - testConfig := &conf.RESTGatewayConf{} + testConfig := &config.RESTGatewayConf{} err := json.Unmarshal([]byte(testConfigJSON), testConfig) if err != nil { fmt.Printf("Failed to unmarshal config file from JSON: %s. %s", testConfigJSON, err) diff --git a/internal/rest/utils/params.go b/internal/rest/utils/params.go index 820e385..68a1441 100644 --- a/internal/rest/utils/params.go +++ b/internal/rest/utils/params.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -39,8 +39,10 @@ type TxOpts struct { // getFlyParam standardizes how special 'fly' params are specified, in body, query params, or headers // these fly-* parameters are supported: // - signer, channel, chaincode +// // precedence order: // - "headers" in body > query parameters > http headers +// // naming conventions: // - properties in the "headers" section of the body has the original name, eg. "channel" // - query parameter has the short prefix, eg. "fly-channel" @@ -79,7 +81,7 @@ func getQueryParamNoCase(name string, req *http.Request) []string { return nil } -func BuildQueryMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.QueryChaincode, *RestError) { +func BuildQueryMessage(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*messages.QueryChaincode, *RestError) { body, err := utils.ParseJSONPayload(req) if err != nil { return nil, NewRestError(err.Error(), 400) @@ -89,7 +91,7 @@ func BuildQueryMessage(res http.ResponseWriter, req *http.Request, params httpro return nil, NewRestError(err.Error(), 400) } - msgId := getFlyParam("id", body, req) + msgID := getFlyParam("id", body, req) channel := getFlyParam("channel", body, req) if channel == "" { return nil, NewRestError("Must specify the channel", 400) @@ -104,7 +106,7 @@ func BuildQueryMessage(res http.ResponseWriter, req *http.Request, params httpro } msg := messages.QueryChaincode{} - msg.Headers.ID = msgId // this could be empty + msg.Headers.ID = msgID // this could be empty msg.Headers.ChannelID = channel msg.Headers.Signer = signer msg.Headers.ChaincodeName = chaincode @@ -137,13 +139,13 @@ func BuildQueryMessage(res http.ResponseWriter, req *http.Request, params httpro return &msg, nil } -func BuildTxByIdMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetTxById, *RestError) { +func BuildTxByIDMessage(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetTxByID, *RestError) { var body map[string]interface{} err := req.ParseForm() if err != nil { return nil, NewRestError(err.Error(), 400) } - msgId := getFlyParam("id", body, req) + msgID := getFlyParam("id", body, req) channel := getFlyParam("channel", body, req) if channel == "" { return nil, NewRestError("Must specify the channel", 400) @@ -153,22 +155,22 @@ func BuildTxByIdMessage(res http.ResponseWriter, req *http.Request, params httpr return nil, NewRestError("Must specify the signer", 400) } - msg := messages.GetTxById{} - msg.Headers.ID = msgId // this could be empty + msg := messages.GetTxByID{} + msg.Headers.ID = msgID // this could be empty msg.Headers.ChannelID = channel msg.Headers.Signer = signer - msg.TxId = params.ByName("txId") + msg.TxID = params.ByName("txId") return &msg, nil } -func BuildGetChainInfoMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetChainInfo, *RestError) { +func BuildGetChainInfoMessage(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*messages.GetChainInfo, *RestError) { var body map[string]interface{} err := req.ParseForm() if err != nil { return nil, NewRestError(err.Error(), 400) } - msgId := getFlyParam("id", body, req) + msgID := getFlyParam("id", body, req) channel := getFlyParam("channel", body, req) if channel == "" { return nil, NewRestError("Must specify the channel", 400) @@ -179,20 +181,20 @@ func BuildGetChainInfoMessage(res http.ResponseWriter, req *http.Request, params } msg := messages.GetChainInfo{} - msg.Headers.ID = msgId // this could be empty + msg.Headers.ID = msgID // this could be empty msg.Headers.ChannelID = channel msg.Headers.Signer = signer return &msg, nil } -func BuildGetBlockMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetBlock, *RestError) { +func BuildGetBlockMessage(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetBlock, *RestError) { var body map[string]interface{} err := req.ParseForm() if err != nil { return nil, NewRestError(err.Error(), 400) } - msgId := getFlyParam("id", body, req) + msgID := getFlyParam("id", body, req) channel := getFlyParam("channel", body, req) if channel == "" { return nil, NewRestError("Must specify the channel", 400) @@ -203,7 +205,7 @@ func BuildGetBlockMessage(res http.ResponseWriter, req *http.Request, params htt } msg := messages.GetBlock{} - msg.Headers.ID = msgId // this could be empty + msg.Headers.ID = msgID // this could be empty msg.Headers.ChannelID = channel msg.Headers.Signer = signer @@ -226,7 +228,7 @@ func BuildGetBlockMessage(res http.ResponseWriter, req *http.Request, params htt return &msg, nil } -func BuildGetBlockByTxIdMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetBlockByTxId, *RestError) { +func BuildGetBlockByTxIDMessage(_ http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.GetBlockByTxID, *RestError) { var body map[string]interface{} err := req.ParseForm() if err != nil { @@ -241,15 +243,15 @@ func BuildGetBlockByTxIdMessage(res http.ResponseWriter, req *http.Request, para return nil, NewRestError("Must specify the signer", 400) } - msg := messages.GetBlockByTxId{} + msg := messages.GetBlockByTxID{} msg.Headers.ChannelID = channel msg.Headers.Signer = signer - msg.TxId = params.ByName("txId") + msg.TxID = params.ByName("txId") return &msg, nil } -func BuildTxMessage(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*messages.SendTransaction, *TxOpts, *RestError) { +func BuildTxMessage(_ http.ResponseWriter, req *http.Request, _ httprouter.Params) (*messages.SendTransaction, *TxOpts, *RestError) { body, err := utils.ParseJSONPayload(req) if err != nil { return nil, nil, NewRestError(err.Error(), 400) @@ -259,7 +261,7 @@ func BuildTxMessage(res http.ResponseWriter, req *http.Request, params httproute return nil, nil, NewRestError(err.Error(), 400) } - msgId := getFlyParam("id", body, req) + msgID := getFlyParam("id", body, req) channel := getFlyParam("channel", body, req) if channel == "" { return nil, nil, NewRestError("Must specify the channel", 400) @@ -274,7 +276,7 @@ func BuildTxMessage(res http.ResponseWriter, req *http.Request, params httproute } msg := messages.SendTransaction{} - msg.Headers.ID = msgId // this could be empty + msg.Headers.ID = msgID // this could be empty msg.Headers.MsgType = messages.MsgTypeSendTransaction msg.Headers.ChannelID = channel msg.Headers.Signer = signer @@ -403,7 +405,7 @@ func processArgs(body map[string]interface{}) ([]string, error) { entryStringValue, ok = entry.(string) if !ok { - return nil, errors.New("Invalid object passed") + return nil, errors.New("invalid object passed") } err := json.Unmarshal([]byte(entryStringValue), &entry) @@ -419,16 +421,17 @@ func processArgs(body map[string]interface{}) ([]string, error) { return nil, err } - if propType == "object" { + switch propType { + case "object": encoded, _ := json.Marshal(entry) args[i] = string(encoded) - } else if propType == "string" { + case "string": strVal, ok := entry.(string) if !ok { return nil, fmt.Errorf("argument property %q of type %q could not be converted to a string", name, propType) } args[i] = strVal - } else { + default: args[i] = entryStringValue } } diff --git a/internal/tx/txcontext.go b/internal/tx/txcontext.go index 05cd3f7..85e4ae2 100644 --- a/internal/tx/txcontext.go +++ b/internal/tx/txcontext.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,8 +22,8 @@ import ( "github.com/hyperledger/firefly-fabconnect/internal/messages" ) -// TxnContext is passed for each message that arrives at the bridge -type TxContext interface { +// Context is passed for each message that arrives at the bridge +type Context interface { // Return the Go context Context() context.Context // Get the headers of the message diff --git a/internal/tx/txprocessor.go b/internal/tx/txprocessor.go index 3f90217..aa76a16 100644 --- a/internal/tx/txprocessor.go +++ b/internal/tx/txprocessor.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -33,10 +33,10 @@ const ( defaultSendConcurrency = 1 ) -// TxProcessor interface is called for each message, as is responsible +// Processor interface is called for each message, as is responsible // for tracking all in-flight messages -type TxProcessor interface { - OnMessage(TxContext) +type Processor interface { + OnMessage(Context) Init(client.RPCClient) GetRPCClient() client.RPCClient } @@ -46,7 +46,7 @@ var highestID = 1000000 type inflightTx struct { id int signer string - txContext TxContext + txContext Context tx *fabric.Tx rpc client.RPCClient } @@ -69,7 +69,7 @@ type txProcessor struct { } // NewTxnProcessor constructor for message procss -func NewTxProcessor(conf *conf.RESTGatewayConf) TxProcessor { +func NewTxProcessor(conf *conf.RESTGatewayConf) Processor { if conf.SendConcurrency == 0 { conf.SendConcurrency = defaultSendConcurrency } @@ -96,7 +96,7 @@ func (p *txProcessor) GetRPCClient() client.RPCClient { // // on txnContext eventually in all scenarios. // It cannot return an error synchronously from this function ** -func (p *txProcessor) OnMessage(txContext TxContext) { +func (p *txProcessor) OnMessage(txContext Context) { var unmarshalErr error headers := txContext.Headers() @@ -121,7 +121,7 @@ func (p *txProcessor) OnMessage(txContext TxContext) { // newInflightWrapper uses the supplied transaction, the inflight txn list. // Builds a new wrapper containing this information, that can be added to // the inflight list if the transaction is submitted -func (p *txProcessor) addInflightWrapper(txContext TxContext, msg *messages.RequestCommon) (inflight *inflightTx, err error) { +func (p *txProcessor) addInflightWrapper(txContext Context, msg *messages.RequestCommon) (inflight *inflightTx, err error) { inflight = &inflightTx{ txContext: txContext, @@ -167,7 +167,7 @@ func (p *txProcessor) cancelInFlight(inflight *inflightTx, submitted bool) { log.Infof("In-flight %d complete. signer=%s sub=%t before=%d after=%d", inflight.id, inflight.signer, submitted, before, after) } -func (p *txProcessor) processCompletion(inflight *inflightTx, tx *fabric.Tx) { +func (p *txProcessor) processCompletion(inflight *inflightTx, _ *fabric.Tx) { receipt := inflight.tx.Receipt isSuccess := receipt.IsSuccess() @@ -194,7 +194,7 @@ func (p *txProcessor) processCompletion(inflight *inflightTx, tx *fabric.Tx) { } -// func (p *txProcessor) OnDeployContractMessage(txnContext TxContext, msg *messages.DeployContract) { +// func (p *txProcessor) OnDeployContractMessage(txnContext Context, msg *messages.DeployContract) { // inflight, err := p.addInflightWrapper(txnContext, &msg.TransactionCommon) // if err != nil { @@ -214,7 +214,7 @@ func (p *txProcessor) processCompletion(inflight *inflightTx, tx *fabric.Tx) { // p.sendTransactionCommon(txnContext, inflight, tx) // } -func (p *txProcessor) OnSendTransactionMessage(txContext TxContext, msg *messages.SendTransaction) { +func (p *txProcessor) OnSendTransactionMessage(txContext Context, msg *messages.SendTransaction) { inflight, err := p.addInflightWrapper(txContext, &msg.RequestCommon) if err != nil { @@ -227,7 +227,7 @@ func (p *txProcessor) OnSendTransactionMessage(txContext TxContext, msg *message p.sendTransactionCommon(txContext, inflight, tx) } -func (p *txProcessor) sendTransactionCommon(txContext TxContext, inflight *inflightTx, tx *fabric.Tx) { +func (p *txProcessor) sendTransactionCommon(txContext Context, inflight *inflightTx, tx *fabric.Tx) { if p.config.SendConcurrency > 1 { // The above must happen synchronously for each partition in Kafka - as it is where we assign the nonce. // However, the send to the node can happen at high concurrency. @@ -239,7 +239,7 @@ func (p *txProcessor) sendTransactionCommon(txContext TxContext, inflight *infli } } -func (p *txProcessor) sendAndTrackMining(txContext TxContext, inflight *inflightTx, tx *fabric.Tx) { +func (p *txProcessor) sendAndTrackMining(txContext Context, inflight *inflightTx, tx *fabric.Tx) { err := tx.Send(txContext.Context(), inflight.rpc) if p.config.SendConcurrency > 1 { <-p.concurrencySlots // return our slot as soon as send is complete, to let an awaiting send go diff --git a/internal/utils/payload_decoder.go b/internal/utils/payload_decoder.go index a18a973..75945ab 100644 --- a/internal/utils/payload_decoder.go +++ b/internal/utils/payload_decoder.go @@ -1,13 +1,13 @@ -// Copyright 2022 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,7 +24,6 @@ func DecodePayload(payload []byte) interface{} { err := json.Unmarshal(payload, &structured) if err != nil { return string(payload) - } else { - return structured } + return structured } diff --git a/internal/utils/swagger-ui.go b/internal/utils/swagger-ui.go index 1db6a9f..6930247 100644 --- a/internal/utils/swagger-ui.go +++ b/internal/utils/swagger-ui.go @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -61,6 +61,6 @@ var swaggerUIHTML = ` ` -func SwaggerUIHTML(ctx context.Context) []byte { +func SwaggerUIHTML(_ context.Context) []byte { return []byte(swaggerUIHTML) } diff --git a/internal/utils/tlsutils.go b/internal/utils/tlsutils.go index 37cb623..6a0e22c 100644 --- a/internal/utils/tlsutils.go +++ b/internal/utils/tlsutils.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,14 +31,14 @@ func CreateTLSConfiguration(tlsConfig *conf.TLSConfig) (t *tls.Config, err error if !AllOrNoneReqd(tlsConfig.ClientCertsFile, tlsConfig.ClientKeyFile) { err = errors.Errorf(errors.ConfigTLSCertOrKey) - return + return nil, err } mutualAuth := tlsConfig.ClientCertsFile != "" && tlsConfig.ClientKeyFile != "" log.Debugf("Kafka TLS Enabled=%t Insecure=%t MutualAuth=%t ClientCertsFile=%s PrivateKeyFile=%s CACertsFile=%s", tlsConfig.Enabled, tlsConfig.InsecureSkipVerify, mutualAuth, tlsConfig.ClientCertsFile, tlsConfig.ClientKeyFile, tlsConfig.CACertsFile) if !tlsConfig.Enabled { - return + return nil, nil } var clientCerts []tls.Certificate @@ -46,7 +46,7 @@ func CreateTLSConfiguration(tlsConfig *conf.TLSConfig) (t *tls.Config, err error var cert tls.Certificate if cert, err = tls.LoadX509KeyPair(tlsConfig.ClientCertsFile, tlsConfig.ClientKeyFile); err != nil { log.Errorf("Unable to load client key/certificate: %s", err) - return + return nil, nil } clientCerts = append(clientCerts, cert) } @@ -56,16 +56,17 @@ func CreateTLSConfiguration(tlsConfig *conf.TLSConfig) (t *tls.Config, err error var caCert []byte if caCert, err = os.ReadFile(tlsConfig.CACertsFile); err != nil { log.Errorf("Unable to load CA certificates: %s", err) - return + return nil, nil } caCertPool = x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) } - + // TODO: Fix linting: G402: TLS InsecureSkipVerify may be true. + // #nosec G402 t = &tls.Config{ Certificates: clientCerts, RootCAs: caCertPool, InsecureSkipVerify: tlsConfig.InsecureSkipVerify, } - return + return t, nil } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 4c43f49..f528f80 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,7 +25,7 @@ import ( "github.com/hyperledger/firefly-fabconnect/internal/errors" uuid "github.com/nu7hatch/gouuid" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) const ( diff --git a/internal/ws/wsconn.go b/internal/ws/wsconn.go index 896d44e..cdc2cc0 100644 --- a/internal/ws/wsconn.go +++ b/internal/ws/wsconn.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,8 +22,8 @@ import ( "sync" "time" - ws "github.com/gorilla/websocket" - log "github.com/sirupsen/logrus" + "github.com/gorilla/websocket" + "github.com/sirupsen/logrus" "github.com/hyperledger/firefly-fabconnect/internal/errors" "github.com/hyperledger/firefly-fabconnect/internal/utils" @@ -32,7 +32,7 @@ import ( type webSocketConnection struct { id string server *webSocketServer - conn *ws.Conn + conn *websocket.Conn mux sync.Mutex closed bool topics map[string]*webSocketTopic @@ -48,7 +48,7 @@ type webSocketCommandMessage struct { Message string `json:"message,omitempty"` } -func newConnection(server *webSocketServer, conn *ws.Conn) *webSocketConnection { +func newConnection(server *webSocketServer, conn *websocket.Conn) *webSocketConnection { wsc := &webSocketConnection{ id: utils.UUIDv4(), server: server, @@ -77,7 +77,7 @@ func (c *webSocketConnection) close() { c.server.cycleTopic(t) } c.server.connectionClosed(c) - log.Infof("WS/%s: Disconnected", c.id) + logrus.Infof("WS/%s: Disconnected", c.id) } func (c *webSocketConnection) sender() { @@ -102,7 +102,7 @@ func (c *webSocketConnection) sender() { for { chosen, value, ok := reflect.Select(cases) if !ok { - log.Infof("WS/%s: Closing", c.id) + logrus.Infof("WS/%s: Closing", c.id) return } @@ -113,7 +113,7 @@ func (c *webSocketConnection) sender() { // Message from one of the existing topics err := c.conn.WriteJSON(value.Interface()) if err != nil { - log.Errorf("Failed to send JSON message: %s", err) + logrus.Errorf("Failed to send JSON message: %s", err) } } } @@ -136,20 +136,20 @@ func (c *webSocketConnection) listenReplies() { func (c *webSocketConnection) listen() { defer c.close() - log.Infof("WS/%s: Connected", c.id) + logrus.Infof("WS/%s: Connected", c.id) for { var msg webSocketCommandMessage err := c.conn.ReadJSON(&msg) if err != nil { - log.Errorf("WS/%s: Error: %s", c.id, err) + logrus.Errorf("WS/%s: Error: %s", c.id, err) return } - log.Debugf("WS/%s: Received: %+v", c.id, msg) + logrus.Debugf("WS/%s: Received: %+v", c.id, msg) t := c.server.getTopic(msg.Topic) switch strings.ToLower(msg.Type) { case "listen": - log.Debugf("Client requested listening on topic: \"%s\"", t.topic) + logrus.Debugf("Client requested listening on topic: \"%s\"", t.topic) c.listenTopic(t) case "listenreplies": c.listenReplies() @@ -158,7 +158,7 @@ func (c *webSocketConnection) listen() { case "error": c.handleAckOrError(t, errors.Errorf(errors.EventStreamsWebSocketErrorFromClient, msg.Message)) default: - log.Errorf("WS/%s: Unexpected message type: %+v", c.id, msg) + logrus.Errorf("WS/%s: Unexpected message type: %+v", c.id, msg) } } } @@ -167,10 +167,10 @@ func (c *webSocketConnection) handleAckOrError(t *webSocketTopic, err error) { isError := err != nil select { case <-time.After(c.server.processingTimeout): - log.Errorf("WS/%s: response (error='%t') on topic '%s'. We were not available to process it after %.2f seconds. Closing connection", c.id, isError, t.topic, c.server.processingTimeout.Seconds()) + logrus.Errorf("WS/%s: response (error='%t') on topic '%s'. We were not available to process it after %.2f seconds. Closing connection", c.id, isError, t.topic, c.server.processingTimeout.Seconds()) c.close() case t.receiverChannel <- err: - log.Debugf("WS/%s: response (error='%t') on topic '%s' passed on for processing", c.id, isError, t.topic) + logrus.Debugf("WS/%s: response (error='%t') on topic '%s' passed on for processing", c.id, isError, t.topic) break } } diff --git a/internal/ws/wsserver.go b/internal/ws/wsserver.go index 3b5c5ca..37cdc46 100644 --- a/internal/ws/wsserver.go +++ b/internal/ws/wsserver.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -81,7 +81,7 @@ func NewWebSocketServer() WebSocketServer { return s } -func (s *webSocketServer) NewConnection(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func (s *webSocketServer) NewConnection(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { conn, err := s.upgrader.Upgrade(w, r, nil) if err != nil { log.Errorf("WebSocket upgrade failed: %s", err) diff --git a/mocks/fabric/client/rpc_client.go b/mocks/fabric/client/rpc_client.go index dff59ce..88f6fe3 100644 --- a/mocks/fabric/client/rpc_client.go +++ b/mocks/fabric/client/rpc_client.go @@ -32,17 +32,17 @@ func (_m *RPCClient) Close() error { return r0 } -// Invoke provides a mock function with given fields: channelId, signer, chaincodeName, method, args, transientMap, isInit -func (_m *RPCClient) Invoke(channelId string, signer string, chaincodeName string, method string, args []string, transientMap map[string]string, isInit bool) (*client.TxReceipt, error) { - ret := _m.Called(channelId, signer, chaincodeName, method, args, transientMap, isInit) +// Invoke provides a mock function with given fields: channelID, signer, chaincodeName, method, args, transientMap, isInit +func (_m *RPCClient) Invoke(channelID string, signer string, chaincodeName string, method string, args []string, transientMap map[string]string, isInit bool) (*client.TxReceipt, error) { + ret := _m.Called(channelID, signer, chaincodeName, method, args, transientMap, isInit) var r0 *client.TxReceipt var r1 error if rf, ok := ret.Get(0).(func(string, string, string, string, []string, map[string]string, bool) (*client.TxReceipt, error)); ok { - return rf(channelId, signer, chaincodeName, method, args, transientMap, isInit) + return rf(channelID, signer, chaincodeName, method, args, transientMap, isInit) } if rf, ok := ret.Get(0).(func(string, string, string, string, []string, map[string]string, bool) *client.TxReceipt); ok { - r0 = rf(channelId, signer, chaincodeName, method, args, transientMap, isInit) + r0 = rf(channelID, signer, chaincodeName, method, args, transientMap, isInit) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*client.TxReceipt) @@ -50,7 +50,7 @@ func (_m *RPCClient) Invoke(channelId string, signer string, chaincodeName strin } if rf, ok := ret.Get(1).(func(string, string, string, string, []string, map[string]string, bool) error); ok { - r1 = rf(channelId, signer, chaincodeName, method, args, transientMap, isInit) + r1 = rf(channelID, signer, chaincodeName, method, args, transientMap, isInit) } else { r1 = ret.Error(1) } @@ -58,17 +58,17 @@ func (_m *RPCClient) Invoke(channelId string, signer string, chaincodeName strin return r0, r1 } -// Query provides a mock function with given fields: channelId, signer, chaincodeName, method, args, strongread -func (_m *RPCClient) Query(channelId string, signer string, chaincodeName string, method string, args []string, strongread bool) ([]byte, error) { - ret := _m.Called(channelId, signer, chaincodeName, method, args, strongread) +// Query provides a mock function with given fields: channelID, signer, chaincodeName, method, args, strongread +func (_m *RPCClient) Query(channelID string, signer string, chaincodeName string, method string, args []string, strongread bool) ([]byte, error) { + ret := _m.Called(channelID, signer, chaincodeName, method, args, strongread) var r0 []byte var r1 error if rf, ok := ret.Get(0).(func(string, string, string, string, []string, bool) ([]byte, error)); ok { - return rf(channelId, signer, chaincodeName, method, args, strongread) + return rf(channelID, signer, chaincodeName, method, args, strongread) } if rf, ok := ret.Get(0).(func(string, string, string, string, []string, bool) []byte); ok { - r0 = rf(channelId, signer, chaincodeName, method, args, strongread) + r0 = rf(channelID, signer, chaincodeName, method, args, strongread) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]byte) @@ -76,7 +76,7 @@ func (_m *RPCClient) Query(channelId string, signer string, chaincodeName string } if rf, ok := ret.Get(1).(func(string, string, string, string, []string, bool) error); ok { - r1 = rf(channelId, signer, chaincodeName, method, args, strongread) + r1 = rf(channelID, signer, chaincodeName, method, args, strongread) } else { r1 = ret.Error(1) } @@ -84,18 +84,18 @@ func (_m *RPCClient) Query(channelId string, signer string, chaincodeName string return r0, r1 } -// QueryBlock provides a mock function with given fields: channelId, signer, blocknumber, blockhash -func (_m *RPCClient) QueryBlock(channelId string, signer string, blocknumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { - ret := _m.Called(channelId, signer, blocknumber, blockhash) +// QueryBlock provides a mock function with given fields: channelID, signer, blocknumber, blockhash +func (_m *RPCClient) QueryBlock(channelID string, signer string, blocknumber uint64, blockhash []byte) (*utils.RawBlock, *utils.Block, error) { + ret := _m.Called(channelID, signer, blocknumber, blockhash) var r0 *utils.RawBlock var r1 *utils.Block var r2 error if rf, ok := ret.Get(0).(func(string, string, uint64, []byte) (*utils.RawBlock, *utils.Block, error)); ok { - return rf(channelId, signer, blocknumber, blockhash) + return rf(channelID, signer, blocknumber, blockhash) } if rf, ok := ret.Get(0).(func(string, string, uint64, []byte) *utils.RawBlock); ok { - r0 = rf(channelId, signer, blocknumber, blockhash) + r0 = rf(channelID, signer, blocknumber, blockhash) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*utils.RawBlock) @@ -103,7 +103,7 @@ func (_m *RPCClient) QueryBlock(channelId string, signer string, blocknumber uin } if rf, ok := ret.Get(1).(func(string, string, uint64, []byte) *utils.Block); ok { - r1 = rf(channelId, signer, blocknumber, blockhash) + r1 = rf(channelID, signer, blocknumber, blockhash) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*utils.Block) @@ -111,7 +111,7 @@ func (_m *RPCClient) QueryBlock(channelId string, signer string, blocknumber uin } if rf, ok := ret.Get(2).(func(string, string, uint64, []byte) error); ok { - r2 = rf(channelId, signer, blocknumber, blockhash) + r2 = rf(channelID, signer, blocknumber, blockhash) } else { r2 = ret.Error(2) } @@ -119,18 +119,18 @@ func (_m *RPCClient) QueryBlock(channelId string, signer string, blocknumber uin return r0, r1, r2 } -// QueryBlockByTxId provides a mock function with given fields: channelId, signer, txId -func (_m *RPCClient) QueryBlockByTxId(channelId string, signer string, txId string) (*utils.RawBlock, *utils.Block, error) { - ret := _m.Called(channelId, signer, txId) +// QueryBlockByTxID provides a mock function with given fields: channelID, signer, txID +func (_m *RPCClient) QueryBlockByTxID(channelID string, signer string, txID string) (*utils.RawBlock, *utils.Block, error) { + ret := _m.Called(channelID, signer, txID) var r0 *utils.RawBlock var r1 *utils.Block var r2 error if rf, ok := ret.Get(0).(func(string, string, string) (*utils.RawBlock, *utils.Block, error)); ok { - return rf(channelId, signer, txId) + return rf(channelID, signer, txID) } if rf, ok := ret.Get(0).(func(string, string, string) *utils.RawBlock); ok { - r0 = rf(channelId, signer, txId) + r0 = rf(channelID, signer, txID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*utils.RawBlock) @@ -138,7 +138,7 @@ func (_m *RPCClient) QueryBlockByTxId(channelId string, signer string, txId stri } if rf, ok := ret.Get(1).(func(string, string, string) *utils.Block); ok { - r1 = rf(channelId, signer, txId) + r1 = rf(channelID, signer, txID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*utils.Block) @@ -146,7 +146,7 @@ func (_m *RPCClient) QueryBlockByTxId(channelId string, signer string, txId stri } if rf, ok := ret.Get(2).(func(string, string, string) error); ok { - r2 = rf(channelId, signer, txId) + r2 = rf(channelID, signer, txID) } else { r2 = ret.Error(2) } @@ -154,17 +154,17 @@ func (_m *RPCClient) QueryBlockByTxId(channelId string, signer string, txId stri return r0, r1, r2 } -// QueryChainInfo provides a mock function with given fields: channelId, signer -func (_m *RPCClient) QueryChainInfo(channelId string, signer string) (*fab.BlockchainInfoResponse, error) { - ret := _m.Called(channelId, signer) +// QueryChainInfo provides a mock function with given fields: channelID, signer +func (_m *RPCClient) QueryChainInfo(channelID string, signer string) (*fab.BlockchainInfoResponse, error) { + ret := _m.Called(channelID, signer) var r0 *fab.BlockchainInfoResponse var r1 error if rf, ok := ret.Get(0).(func(string, string) (*fab.BlockchainInfoResponse, error)); ok { - return rf(channelId, signer) + return rf(channelID, signer) } if rf, ok := ret.Get(0).(func(string, string) *fab.BlockchainInfoResponse); ok { - r0 = rf(channelId, signer) + r0 = rf(channelID, signer) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*fab.BlockchainInfoResponse) @@ -172,7 +172,7 @@ func (_m *RPCClient) QueryChainInfo(channelId string, signer string) (*fab.Block } if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(channelId, signer) + r1 = rf(channelID, signer) } else { r1 = ret.Error(1) } @@ -180,17 +180,17 @@ func (_m *RPCClient) QueryChainInfo(channelId string, signer string) (*fab.Block return r0, r1 } -// QueryTransaction provides a mock function with given fields: channelId, signer, txId -func (_m *RPCClient) QueryTransaction(channelId string, signer string, txId string) (map[string]interface{}, error) { - ret := _m.Called(channelId, signer, txId) +// QueryTransaction provides a mock function with given fields: channelID, signer, txID +func (_m *RPCClient) QueryTransaction(channelID string, signer string, txID string) (map[string]interface{}, error) { + ret := _m.Called(channelID, signer, txID) var r0 map[string]interface{} var r1 error if rf, ok := ret.Get(0).(func(string, string, string) (map[string]interface{}, error)); ok { - return rf(channelId, signer, txId) + return rf(channelID, signer, txID) } if rf, ok := ret.Get(0).(func(string, string, string) map[string]interface{}); ok { - r0 = rf(channelId, signer, txId) + r0 = rf(channelID, signer, txID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string]interface{}) @@ -198,7 +198,7 @@ func (_m *RPCClient) QueryTransaction(channelId string, signer string, txId stri } if rf, ok := ret.Get(1).(func(string, string, string) error); ok { - r1 = rf(channelId, signer, txId) + r1 = rf(channelID, signer, txID) } else { r1 = ret.Error(1) } diff --git a/mocks/rest/async/dispatcher.go b/mocks/rest/async/dispatcher.go new file mode 100644 index 0000000..ad08074 --- /dev/null +++ b/mocks/rest/async/dispatcher.go @@ -0,0 +1,112 @@ +// Code generated by mockery v2.29.0. DO NOT EDIT. + +package mockasync + +import ( + context "context" + http "net/http" + + httprouter "github.com/julienschmidt/httprouter" + + messages "github.com/hyperledger/firefly-fabconnect/internal/messages" + + mock "github.com/stretchr/testify/mock" +) + +// Dispatcher is an autogenerated mock type for the Dispatcher type +type Dispatcher struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *Dispatcher) Close() { + _m.Called() +} + +// DispatchMsgAsync provides a mock function with given fields: ctx, msg, ack +func (_m *Dispatcher) DispatchMsgAsync(ctx context.Context, msg *messages.SendTransaction, ack bool) (*messages.AsyncSentMsg, error) { + ret := _m.Called(ctx, msg, ack) + + var r0 *messages.AsyncSentMsg + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *messages.SendTransaction, bool) (*messages.AsyncSentMsg, error)); ok { + return rf(ctx, msg, ack) + } + if rf, ok := ret.Get(0).(func(context.Context, *messages.SendTransaction, bool) *messages.AsyncSentMsg); ok { + r0 = rf(ctx, msg, ack) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*messages.AsyncSentMsg) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *messages.SendTransaction, bool) error); ok { + r1 = rf(ctx, msg, ack) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HandleReceipts provides a mock function with given fields: res, req, params +func (_m *Dispatcher) HandleReceipts(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// IsInitialized provides a mock function with given fields: +func (_m *Dispatcher) IsInitialized() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Run provides a mock function with given fields: +func (_m *Dispatcher) Run() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ValidateConf provides a mock function with given fields: +func (_m *Dispatcher) ValidateConf() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type mockConstructorTestingTNewDispatcher interface { + mock.TestingT + Cleanup(func()) +} + +// NewDispatcher creates a new instance of Dispatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewDispatcher(t mockConstructorTestingTNewDispatcher) *Dispatcher { + mock := &Dispatcher{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/rest/identity/client.go b/mocks/rest/identity/client.go new file mode 100644 index 0000000..e3f9898 --- /dev/null +++ b/mocks/rest/identity/client.go @@ -0,0 +1,230 @@ +// Code generated by mockery v2.29.0. DO NOT EDIT. + +package mockidentity + +import ( + http "net/http" + + identity "github.com/hyperledger/firefly-fabconnect/internal/rest/identity" + httprouter "github.com/julienschmidt/httprouter" + + mock "github.com/stretchr/testify/mock" + + util "github.com/hyperledger/firefly-fabconnect/internal/rest/utils" +) + +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// Enroll provides a mock function with given fields: res, req, params +func (_m *Client) Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.Response + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.Response, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.Response); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.Response) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// Get provides a mock function with given fields: res, req, params +func (_m *Client) Get(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Identity, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.Identity + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.Identity, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.Identity); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.Identity) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// List provides a mock function with given fields: res, req, params +func (_m *Client) List(res http.ResponseWriter, req *http.Request, params httprouter.Params) ([]*identity.Identity, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 []*identity.Identity + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) ([]*identity.Identity, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) []*identity.Identity); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*identity.Identity) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// Modify provides a mock function with given fields: res, req, params +func (_m *Client) Modify(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RegisterResponse, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.RegisterResponse + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.RegisterResponse, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.RegisterResponse); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.RegisterResponse) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// Reenroll provides a mock function with given fields: res, req, params +func (_m *Client) Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.Response + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.Response, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.Response); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.Response) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// Register provides a mock function with given fields: res, req, params +func (_m *Client) Register(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RegisterResponse, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.RegisterResponse + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.RegisterResponse, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.RegisterResponse); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.RegisterResponse) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +// Revoke provides a mock function with given fields: res, req, params +func (_m *Client) Revoke(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.RevokeResponse, *util.RestError) { + ret := _m.Called(res, req, params) + + var r0 *identity.RevokeResponse + var r1 *util.RestError + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.RevokeResponse, *util.RestError)); ok { + return rf(res, req, params) + } + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.RevokeResponse); ok { + r0 = rf(res, req, params) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*identity.RevokeResponse) + } + } + + if rf, ok := ret.Get(1).(func(http.ResponseWriter, *http.Request, httprouter.Params) *util.RestError); ok { + r1 = rf(res, req, params) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*util.RestError) + } + } + + return r0, r1 +} + +type mockConstructorTestingTNewClient interface { + mock.TestingT + Cleanup(func()) +} + +// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewClient(t mockConstructorTestingTNewClient) *Client { + mock := &Client{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/rest/identity/identity_client.go b/mocks/rest/identity/identity_client.go index 981acb7..6371baa 100644 --- a/mocks/rest/identity/identity_client.go +++ b/mocks/rest/identity/identity_client.go @@ -19,19 +19,19 @@ type IdentityClient struct { } // Enroll provides a mock function with given fields: res, req, params -func (_m *IdentityClient) Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.IdentityResponse, *util.RestError) { +func (_m *IdentityClient) Enroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *util.RestError) { ret := _m.Called(res, req, params) - var r0 *identity.IdentityResponse + var r0 *identity.Response var r1 *util.RestError - if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.IdentityResponse, *util.RestError)); ok { + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.Response, *util.RestError)); ok { return rf(res, req, params) } - if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.IdentityResponse); ok { + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.Response); ok { r0 = rf(res, req, params) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*identity.IdentityResponse) + r0 = ret.Get(0).(*identity.Response) } } @@ -131,19 +131,19 @@ func (_m *IdentityClient) Modify(res http.ResponseWriter, req *http.Request, par } // Reenroll provides a mock function with given fields: res, req, params -func (_m *IdentityClient) Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.IdentityResponse, *util.RestError) { +func (_m *IdentityClient) Reenroll(res http.ResponseWriter, req *http.Request, params httprouter.Params) (*identity.Response, *util.RestError) { ret := _m.Called(res, req, params) - var r0 *identity.IdentityResponse + var r0 *identity.Response var r1 *util.RestError - if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.IdentityResponse, *util.RestError)); ok { + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) (*identity.Response, *util.RestError)); ok { return rf(res, req, params) } - if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.IdentityResponse); ok { + if rf, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request, httprouter.Params) *identity.Response); ok { r0 = rf(res, req, params) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*identity.IdentityResponse) + r0 = ret.Get(0).(*identity.Response) } } diff --git a/mocks/rest/receipt/store.go b/mocks/rest/receipt/store.go new file mode 100644 index 0000000..d154010 --- /dev/null +++ b/mocks/rest/receipt/store.go @@ -0,0 +1,90 @@ +// Code generated by mockery v2.29.0. DO NOT EDIT. + +package mockreceipt + +import ( + http "net/http" + + api "github.com/hyperledger/firefly-fabconnect/internal/rest/receipt/api" + + httprouter "github.com/julienschmidt/httprouter" + + mock "github.com/stretchr/testify/mock" + + ws "github.com/hyperledger/firefly-fabconnect/internal/ws" +) + +// Store is an autogenerated mock type for the Store type +type Store struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *Store) Close() { + _m.Called() +} + +// GetReceipt provides a mock function with given fields: res, req, params +func (_m *Store) GetReceipt(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// GetReceipts provides a mock function with given fields: res, req, params +func (_m *Store) GetReceipts(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// Init provides a mock function with given fields: _a0, _a1 +func (_m *Store) Init(_a0 ws.WebSocketChannels, _a1 ...api.ReceiptStorePersistence) error { + _va := make([]interface{}, len(_a1)) + for _i := range _a1 { + _va[_i] = _a1[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(ws.WebSocketChannels, ...api.ReceiptStorePersistence) error); ok { + r0 = rf(_a0, _a1...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ProcessReceipt provides a mock function with given fields: msgBytes +func (_m *Store) ProcessReceipt(msgBytes []byte) { + _m.Called(msgBytes) +} + +// ValidateConf provides a mock function with given fields: +func (_m *Store) ValidateConf() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type mockConstructorTestingTNewStore interface { + mock.TestingT + Cleanup(func()) +} + +// NewStore creates a new instance of Store. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewStore(t mockConstructorTestingTNewStore) *Store { + mock := &Store{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/rest/sync/dispatcher.go b/mocks/rest/sync/dispatcher.go new file mode 100644 index 0000000..1bb858d --- /dev/null +++ b/mocks/rest/sync/dispatcher.go @@ -0,0 +1,62 @@ +// Code generated by mockery v2.29.0. DO NOT EDIT. + +package mocksync + +import ( + context "context" + http "net/http" + + httprouter "github.com/julienschmidt/httprouter" + + mock "github.com/stretchr/testify/mock" +) + +// Dispatcher is an autogenerated mock type for the Dispatcher type +type Dispatcher struct { + mock.Mock +} + +// DispatchMsgSync provides a mock function with given fields: ctx, res, req, msg +func (_m *Dispatcher) DispatchMsgSync(ctx context.Context, res http.ResponseWriter, req *http.Request, msg interface{}) { + _m.Called(ctx, res, req, msg) +} + +// GetBlock provides a mock function with given fields: res, req, params +func (_m *Dispatcher) GetBlock(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// GetBlockByTxID provides a mock function with given fields: res, req, params +func (_m *Dispatcher) GetBlockByTxID(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// GetChainInfo provides a mock function with given fields: res, req, params +func (_m *Dispatcher) GetChainInfo(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// GetTxByID provides a mock function with given fields: res, req, params +func (_m *Dispatcher) GetTxByID(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +// QueryChaincode provides a mock function with given fields: res, req, params +func (_m *Dispatcher) QueryChaincode(res http.ResponseWriter, req *http.Request, params httprouter.Params) { + _m.Called(res, req, params) +} + +type mockConstructorTestingTNewDispatcher interface { + mock.TestingT + Cleanup(func()) +} + +// NewDispatcher creates a new instance of Dispatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewDispatcher(t mockConstructorTestingTNewDispatcher) *Dispatcher { + mock := &Dispatcher{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/tx/processor.go b/mocks/tx/processor.go new file mode 100644 index 0000000..85ff6dc --- /dev/null +++ b/mocks/tx/processor.go @@ -0,0 +1,56 @@ +// Code generated by mockery v2.29.0. DO NOT EDIT. + +package mocktx + +import ( + client "github.com/hyperledger/firefly-fabconnect/internal/fabric/client" + mock "github.com/stretchr/testify/mock" + + tx "github.com/hyperledger/firefly-fabconnect/internal/tx" +) + +// Processor is an autogenerated mock type for the Processor type +type Processor struct { + mock.Mock +} + +// GetRPCClient provides a mock function with given fields: +func (_m *Processor) GetRPCClient() client.RPCClient { + ret := _m.Called() + + var r0 client.RPCClient + if rf, ok := ret.Get(0).(func() client.RPCClient); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(client.RPCClient) + } + } + + return r0 +} + +// Init provides a mock function with given fields: _a0 +func (_m *Processor) Init(_a0 client.RPCClient) { + _m.Called(_a0) +} + +// OnMessage provides a mock function with given fields: _a0 +func (_m *Processor) OnMessage(_a0 tx.Context) { + _m.Called(_a0) +} + +type mockConstructorTestingTNewProcessor interface { + mock.TestingT + Cleanup(func()) +} + +// NewProcessor creates a new instance of Processor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewProcessor(t mockConstructorTestingTNewProcessor) *Processor { + mock := &Processor{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/tx/tx_processor.go b/mocks/tx/tx_processor.go index 6140202..a921ea9 100644 --- a/mocks/tx/tx_processor.go +++ b/mocks/tx/tx_processor.go @@ -36,7 +36,7 @@ func (_m *TxProcessor) Init(_a0 client.RPCClient) { } // OnMessage provides a mock function with given fields: _a0 -func (_m *TxProcessor) OnMessage(_a0 tx.TxContext) { +func (_m *TxProcessor) OnMessage(_a0 tx.Context) { _m.Called(_a0) } diff --git a/pkg/plugins/securitymodule.go b/pkg/plugins/securitymodule.go index 561bbbd..2f27fd5 100644 --- a/pkg/plugins/securitymodule.go +++ b/pkg/plugins/securitymodule.go @@ -1,13 +1,13 @@ -// Copyright 2021 Kaleido +// Copyright © 2023 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 - +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,8 +20,9 @@ package plugins type EventOperation int // SecurityModule is a code plug-point that can be implemented using a go plugin module. -// Build your plugin with a "SecurityModule" export that implements this interface, -// and configure the dynamic load path of your module in the configuration. +// +// Build your plugin with a "SecurityModule" export that implements this interface, +// and configure the dynamic load path of your module in the configuration. type SecurityModule interface { // VerifyToken - Authentication plugpoint. Verfies a token and returns a context object to store that will be returned to authorization points