From 1f871c4fa0a45c74c12f935b7349f17673263cf2 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Thu, 21 Jul 2022 14:47:32 -0700 Subject: [PATCH 1/8] feat: Implement Device System Events Also, refactor to use common Messaging Bootstrap Handler closes #4099 Signed-off-by: Leonard Goodell --- Makefile | 4 +- cmd/core-metadata/res/configuration.toml | 20 +++ go.mod | 5 + go.sum | 29 +--- internal/core/data/config/config.go | 9 +- internal/core/data/main.go | 22 +-- internal/core/data/messaging/messaging.go | 134 ------------------ .../core/data/messaging/messaging_test.go | 110 -------------- internal/core/metadata/application/device.go | 68 ++++++++- .../core/metadata/application/device_test.go | 124 ++++++++++++++++ internal/core/metadata/config/config.go | 10 +- internal/core/metadata/main.go | 7 +- 12 files changed, 246 insertions(+), 296 deletions(-) delete mode 100644 internal/core/data/messaging/messaging.go delete mode 100644 internal/core/data/messaging/messaging_test.go create mode 100644 internal/core/metadata/application/device_test.go diff --git a/Makefile b/Makefile index 403bc2e4e4..44ed31240c 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ ifeq ($(INCLUDE_DELAYED_START_BUILD_SUPPORT),"false") endif NO_MESSAGEBUS_GO_BUILD_TAG:=no_messagebus - +NO_ZMQ_GO_BUILD_TAG:=no_zmq build: $(MICROSERVICES) @@ -86,7 +86,7 @@ tidy: go mod tidy cmd/core-metadata/core-metadata: - $(GO) build -tags "$(NO_MESSAGEBUS_GO_BUILD_TAG) $(NON_DELAYED_START_GO_BUILD_TAG_FOR_CORE)" $(GOFLAGS) -o $@ ./cmd/core-metadata + $(GO) build -tags "$(NO_ZMQ_GO_BUILD_TAG) $(NON_DELAYED_START_GO_BUILD_TAG_FOR_CORE)" $(GOFLAGS) -o $@ ./cmd/core-metadata cmd/core-data/core-data: $(GOCGO) build -tags "$(NON_DELAYED_START_GO_BUILD_TAG_FOR_CORE)" $(CGOFLAGS) -o $@ ./cmd/core-data diff --git a/cmd/core-metadata/res/configuration.toml b/cmd/core-metadata/res/configuration.toml index 3b9afc284e..7bb9f717ae 100644 --- a/cmd/core-metadata/res/configuration.toml +++ b/cmd/core-metadata/res/configuration.toml @@ -56,6 +56,26 @@ Sender = "core-metadata" Description = "Metadata change notice" Label = "metadata" +[MessageQueue] +Protocol = "redis" +Host = "localhost" +Port = 6379 +Type = "redis" +AuthMode = "usernamepassword" # required for redis messagebus (secure or insecure). +SecretName = "redisdb" + [MessageQueue.Optional] + # Default MQTT Specific options that need to be here to enable evnironment variable overrides of them + # Client Identifiers + ClientId ="core-metadata" + # Connection information + Qos = "0" # Quality of Sevice values are 0 (At most once), 1 (At least once) or 2 (Exactly once) + KeepAlive = "10" # Seconds (must be 2 or greater) + Retained = "false" + AutoReconnect = "true" + ConnectTimeout = "5" # Seconds + # TLS configuration - Only used if Cert/Key file or Cert/Key PEMblock are specified + SkipCertVerify = "false" + [SecretStore] Type = "vault" Protocol = "http" diff --git a/go.mod b/go.mod index 65897c23e0..497487db62 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,10 @@ module github.com/edgexfoundry/edgex-go +replace ( + github.com/edgexfoundry/go-mod-bootstrap/v2 => ../MODS/go-mod-bootstrap + github.com/edgexfoundry/go-mod-core-contracts/v2 => ../MODS/go-mod-core-contracts +) + require ( bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690 github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11 diff --git a/go.sum b/go.sum index d320486c67..1f7e84f10f 100644 --- a/go.sum +++ b/go.sum @@ -32,14 +32,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfENpMvdbAXAI= github.com/eclipse/paho.mqtt.golang v1.4.1/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= -github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11 h1:HQpkdjcD6nVimvXYtpVbzJNBOOtcoFOcSLN8uyiBkvs= -github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11/go.mod h1:HTrESzn1iz6C3Sg+3ZDBtklpkCxHX0Cf8sGFAFlwM8s= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0 h1:AZeaAPJM5X93ITFgwbwluYDtYEJ7tkCMSlj35GwfLLU= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0/go.mod h1:YP17JhMnXTitowXE13QJwFaKo0oc03iyoKLjWAYl4FE= -github.com/edgexfoundry/go-mod-core-contracts/v2 v2.3.0-dev.13 h1:lPjtuVk2QXoUxs6sAsb0qflxmREB5kgHIjFrkNNnx6A= -github.com/edgexfoundry/go-mod-core-contracts/v2 v2.3.0-dev.13/go.mod h1:YdJ0iBWad86sgOs6am01mE3IAX6d22H08f/enVho4TU= -github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12 h1:YdO9V8pSFK3L2FSpPru3OulK0kFCt96+tsdxTtkfeqk= -github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12/go.mod h1:yLJ9EK4Feg409FDr0oP87LbaRLyOSGJk/ikaIfEDKcI= +github.com/edgexfoundry/go-mod-messaging/v2 v2.2.1-dev.11 h1:mvVU/eRl5GGIH1r/PDRgK3AR8Zsq81Lsi9qjduPsoFk= +github.com/edgexfoundry/go-mod-messaging/v2 v2.2.1-dev.11/go.mod h1:h7iBbErPlPBEjYoO5UpwdFxR+Tqg/eObEbNGy2INVlo= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0 h1:dk9ul1t7INAiyZXeu/GrpinFE3qOekdy8uZOqEGgIiE= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0/go.mod h1:DUQRnAd5fVzoROc5SI+PTFUD/vCNeZmZHBMrLElbmwI= github.com/edgexfoundry/go-mod-secrets/v2 v2.2.1-dev.5 h1:B6LCod0L4qh/+zZdzoMucL7lArZrT1NIpT5naya+CXU= @@ -146,8 +142,6 @@ github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -174,8 +168,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/consulstructure v0.0.0-20190329231841-56fdc4d2da54 h1:DcITQwl3ymmg7i1XfwpZFs/TPv2PuTwxE8bnuKVtKlk= github.com/mitchellh/consulstructure v0.0.0-20190329231841-56fdc4d2da54/go.mod h1:dIfpPVUR+ZfkzkDcKnn+oPW1jKeXe4WlNWc7rIXOVxM= @@ -190,15 +182,6 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= -github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= -github.com/nats-io/nats-server/v2 v2.7.4 h1:c+BZJ3rGzUKCBIM4IXO8uNT2u1vajGbD1kPA6wqCEaM= -github.com/nats-io/nats.go v1.16.0 h1:zvLE7fGBQYW6MWaFaRdsgm9qT39PJDQoju+DS8KsO1g= -github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= -github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= -github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -251,10 +234,8 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -272,7 +253,6 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -288,7 +268,6 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -320,8 +299,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/internal/core/data/config/config.go b/internal/core/data/config/config.go index 9ccd1e9d89..ece32cffa5 100644 --- a/internal/core/data/config/config.go +++ b/internal/core/data/config/config.go @@ -73,10 +73,11 @@ func (c *ConfigurationStruct) UpdateWritableFromRaw(rawWritable interface{}) boo func (c *ConfigurationStruct) GetBootstrap() bootstrapConfig.BootstrapConfiguration { // temporary until we can make backwards-breaking configuration.toml change return bootstrapConfig.BootstrapConfiguration{ - Clients: c.Clients, - Service: c.Service, - Registry: c.Registry, - SecretStore: c.SecretStore, + Clients: c.Clients, + Service: c.Service, + Registry: c.Registry, + SecretStore: c.SecretStore, + MessageQueue: c.MessageQueue, } } diff --git a/internal/core/data/main.go b/internal/core/data/main.go index fabc7be45c..01dbfb198b 100644 --- a/internal/core/data/main.go +++ b/internal/core/data/main.go @@ -21,14 +21,7 @@ import ( "github.com/gorilla/mux" - "github.com/edgexfoundry/edgex-go" - "github.com/edgexfoundry/edgex-go/internal" - "github.com/edgexfoundry/edgex-go/internal/core/data/application" - "github.com/edgexfoundry/edgex-go/internal/core/data/config" - "github.com/edgexfoundry/edgex-go/internal/core/data/container" - "github.com/edgexfoundry/edgex-go/internal/core/data/messaging" - pkgHandlers "github.com/edgexfoundry/edgex-go/internal/pkg/bootstrap/handlers" - "github.com/edgexfoundry/edgex-go/internal/pkg/telemetry" + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/flags" @@ -36,7 +29,14 @@ import ( "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/interfaces" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/startup" "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - "github.com/edgexfoundry/go-mod-core-contracts/v2/common" + + "github.com/edgexfoundry/edgex-go" + "github.com/edgexfoundry/edgex-go/internal" + "github.com/edgexfoundry/edgex-go/internal/core/data/application" + "github.com/edgexfoundry/edgex-go/internal/core/data/config" + "github.com/edgexfoundry/edgex-go/internal/core/data/container" + pkgHandlers "github.com/edgexfoundry/edgex-go/internal/pkg/bootstrap/handlers" + "github.com/edgexfoundry/edgex-go/internal/pkg/telemetry" ) func Main(ctx context.Context, cancel context.CancelFunc, router *mux.Router) { @@ -73,9 +73,9 @@ func Main(ctx context.Context, cancel context.CancelFunc, router *mux.Router) { true, []interfaces.BootstrapHandler{ pkgHandlers.NewDatabase(httpServer, configuration, container.DBClientInterfaceName).BootstrapHandler, // add v2 db client bootstrap handler - messaging.BootstrapHandler, + handlers.MessagingBootstrapHandler, handlers.NewServiceMetrics(common.CoreDataServiceKey).BootstrapHandler, // Must be after Messaging - application.BootstrapHandler, // Must be after Service Metrics and before next handler + application.BootstrapHandler, // Must be after Service Metrics and before next handler NewBootstrap(router, common.CoreDataServiceKey).BootstrapHandler, telemetry.BootstrapHandler, httpServer.BootstrapHandler, diff --git a/internal/core/data/messaging/messaging.go b/internal/core/data/messaging/messaging.go deleted file mode 100644 index bdf07500d1..0000000000 --- a/internal/core/data/messaging/messaging.go +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright 2021 Intel Corp. - * - * 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 messaging - -import ( - "context" - "strings" - "sync" - - "github.com/edgexfoundry/go-mod-messaging/v2/messaging" - "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" - - bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" - bootstrapMessaging "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/messaging" - "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/startup" - bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v2/config" - "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - - "github.com/edgexfoundry/edgex-go/internal/core/data/container" -) - -// BootstrapHandler fulfills the BootstrapHandler contract. if enabled, tt creates and initializes the Messaging client -// and adds it to the DIC -func BootstrapHandler(ctx context.Context, wg *sync.WaitGroup, startupTimer startup.Timer, dic *di.Container) bool { - lc := bootstrapContainer.LoggingClientFrom(dic.Get) - - // Make sure the MessageBus password is not leaked into the Service Config that can be retrieved via the /config endpoint - messageBusInfo := deepCopy(container.ConfigurationFrom(dic.Get).MessageQueue) - - messageBusInfo.AuthMode = strings.ToLower(strings.TrimSpace(messageBusInfo.AuthMode)) - if len(messageBusInfo.AuthMode) > 0 && messageBusInfo.AuthMode != bootstrapMessaging.AuthModeNone { - if err := bootstrapMessaging.SetOptionsAuthData(&messageBusInfo, lc, dic); err != nil { - lc.Error(err.Error()) - return false - } - } - - msgClient, err := messaging.NewMessageClient( - types.MessageBusConfig{ - PublishHost: types.HostInfo{ - Host: messageBusInfo.Host, - Port: messageBusInfo.Port, - Protocol: messageBusInfo.Protocol, - }, - SubscribeHost: types.HostInfo{ - Host: messageBusInfo.Host, - Port: messageBusInfo.Port, - Protocol: messageBusInfo.Protocol, - }, - Type: messageBusInfo.Type, - Optional: messageBusInfo.Optional, - }) - - if err != nil { - lc.Errorf("Failed to create MessageClient: %v", err) - return false - } - - for startupTimer.HasNotElapsed() { - select { - case <-ctx.Done(): - return false - default: - err = msgClient.Connect() - if err != nil { - lc.Warnf("Unable to connect MessageBus: %w", err) - startupTimer.SleepForInterval() - continue - } - - wg.Add(1) - go func() { - defer wg.Done() - <-ctx.Done() - if msgClient != nil { - _ = msgClient.Disconnect() - } - lc.Infof("Disconnected from MessageBus") - }() - - dic.Update(di.ServiceConstructorMap{ - bootstrapContainer.MessagingClientName: func(get di.Get) interface{} { - return msgClient - }, - }) - - lc.Infof( - "Connected to %s Message Bus @ %s://%s:%d publishing on '%s' prefix topic with AuthMode='%s'", - messageBusInfo.Type, - messageBusInfo.Protocol, - messageBusInfo.Host, - messageBusInfo.Port, - messageBusInfo.PublishTopicPrefix, - messageBusInfo.AuthMode) - - return true - } - } - - lc.Error("Connecting to MessageBus time out") - return false -} - -func deepCopy(target bootstrapConfig.MessageBusInfo) bootstrapConfig.MessageBusInfo { - result := bootstrapConfig.MessageBusInfo{ - Type: target.Type, - Protocol: target.Protocol, - Host: target.Host, - Port: target.Port, - PublishTopicPrefix: target.PublishTopicPrefix, - SubscribeTopic: target.SubscribeTopic, - AuthMode: target.AuthMode, - SecretName: target.SecretName, - SubscribeEnabled: target.SubscribeEnabled, - } - result.Optional = make(map[string]string) - for key, value := range target.Optional { - result.Optional[key] = value - } - - return result -} diff --git a/internal/core/data/messaging/messaging_test.go b/internal/core/data/messaging/messaging_test.go deleted file mode 100644 index 557adcb099..0000000000 --- a/internal/core/data/messaging/messaging_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package messaging - -import ( - "context" - "os" - "sync" - "testing" - - "github.com/edgexfoundry/go-mod-messaging/v2/messaging" - "github.com/stretchr/testify/assert" - - "github.com/edgexfoundry/edgex-go/internal/core/data/config" - "github.com/edgexfoundry/edgex-go/internal/core/data/container" - bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" - "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/interfaces/mocks" - messaging2 "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/messaging" - "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/startup" - bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v2/config" - "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" -) - -var lc logger.LoggingClient -var dic *di.Container -var usernameSecretData = map[string]string{ - messaging2.SecretUsernameKey: "username", - messaging2.SecretPasswordKey: "password", -} - -func TestMain(m *testing.M) { - lc = logger.NewMockClient() - - dic = di.NewContainer(di.ServiceConstructorMap{ - bootstrapContainer.LoggingClientInterfaceName: func(get di.Get) interface{} { - return lc - }, - }) - - os.Exit(m.Run()) -} - -func TestBootstrapHandler(t *testing.T) { - validCreateClient := config.ConfigurationStruct{ - MessageQueue: bootstrapConfig.MessageBusInfo{ - Type: messaging.Redis, - Protocol: "redis", - Host: "localhost", - Port: 6379, - PublishTopicPrefix: "edgex/events/#", - AuthMode: messaging2.AuthModeUsernamePassword, - SecretName: "redisdb", - }, - } - - invalidSecrets := config.ConfigurationStruct{ - MessageQueue: bootstrapConfig.MessageBusInfo{ - AuthMode: messaging2.AuthModeCert, - SecretName: "redisdb", - }, - } - - invalidNoConnect := config.ConfigurationStruct{ - MessageQueue: bootstrapConfig.MessageBusInfo{ - Type: messaging.MQTT, // This will cause no connection since broker not available - Protocol: "tcp", - Host: "localhost", - Port: 8765, - AuthMode: messaging2.AuthModeUsernamePassword, - SecretName: "redisdb", - }, - } - - tests := []struct { - Name string - Config *config.ConfigurationStruct - ExpectedResult bool - ExpectClient bool - }{ - {"Valid - creates client", &validCreateClient, true, true}, - {"Invalid - secrets error", &invalidSecrets, false, false}, - {"Invalid - can't connect", &invalidNoConnect, false, false}, - } - - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - provider := &mocks.SecretProvider{} - provider.On("GetSecret", test.Config.MessageQueue.SecretName).Return(usernameSecretData, nil) - dic.Update(di.ServiceConstructorMap{ - container.ConfigurationName: func(get di.Get) interface{} { - return test.Config - }, - bootstrapContainer.SecretProviderName: func(get di.Get) interface{} { - return provider - }, - bootstrapContainer.MessagingClientName: func(get di.Get) interface{} { - return nil - }, - }) - - actual := BootstrapHandler(context.Background(), &sync.WaitGroup{}, startup.NewTimer(1, 1), dic) - assert.Equal(t, test.ExpectedResult, actual) - assert.Empty(t, test.Config.MessageQueue.Optional) - if test.ExpectClient { - assert.NotNil(t, bootstrapContainer.MessagingClientFrom(dic.Get)) - } else { - assert.Nil(t, bootstrapContainer.MessagingClientFrom(dic.Get)) - } - }) - } -} diff --git a/internal/core/metadata/application/device.go b/internal/core/metadata/application/device.go index 22aa9546dd..01f4ff5fa9 100644 --- a/internal/core/metadata/application/device.go +++ b/internal/core/metadata/application/device.go @@ -1,5 +1,6 @@ // // Copyright (C) 2020-2022 IOTech Ltd +// Copyright (C) 2022 Intel // // SPDX-License-Identifier: Apache-2.0 @@ -7,19 +8,24 @@ package application import ( "context" + "encoding/json" + goErrors "errors" "fmt" "github.com/edgexfoundry/edgex-go/internal/core/metadata/container" "github.com/edgexfoundry/edgex-go/internal/core/metadata/infrastructure/interfaces" "github.com/edgexfoundry/edgex-go/internal/pkg/correlation" - bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/requests" "github.com/edgexfoundry/go-mod-core-contracts/v2/errors" "github.com/edgexfoundry/go-mod-core-contracts/v2/models" + "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" + + "github.com/google/uuid" ) // The AddDevice function accepts the new device model from the controller function @@ -56,12 +62,22 @@ func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id stri addedDevice.Id, correlation.FromContext(ctx), ) - go addDeviceCallback(ctx, dic, dtos.FromDeviceModelToDTO(d)) + + device := dtos.FromDeviceModelToDTO(d) + go addDeviceCallback(ctx, dic, device) + + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error already has context. + lc.Error(err.Error()) + } + return addedDevice.Id, nil } // DeleteDeviceByName deletes the device by name func DeleteDeviceByName(name string, ctx context.Context, dic *di.Container) errors.EdgeX { + lc := bootstrapContainer.LoggingClientFrom(dic.Get) + if name == "" { return errors.NewCommonEdgeX(errors.KindContractInvalid, "name is empty", nil) } @@ -75,6 +91,12 @@ func DeleteDeviceByName(name string, ctx context.Context, dic *di.Container) err return errors.NewCommonEdgeXWrapper(err) } go deleteDeviceCallback(ctx, dic, device) + + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error already has context. + lc.Error(err.Error()) + } + return nil } @@ -165,6 +187,12 @@ func PatchDevice(dto dtos.UpdateDevice, ctx context.Context, dic *di.Container) go updateDeviceCallback(ctx, dic, oldServiceName, device) } go updateDeviceCallback(ctx, dic, device.ServiceName, device) + + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error already has context. + lc.Error(err.Error()) + } + return nil } @@ -237,3 +265,37 @@ func DevicesByProfileName(offset int, limit int, profileName string, dic *di.Con } return devices, totalCount, nil } + +var noMessagingClientError = goErrors.New("unable to publish Device System Event: MessageBus Client not available") + +func publishDeviceSystemEvent(action string, d models.Device, lc logger.LoggingClient, dic *di.Container) error { + device := dtos.FromDeviceModelToDTO(d) + systemEvent := dtos.NewSystemEvent(common.DeviceSystemEventType, action, common.CoreMetaDataServiceKey, device.ServiceName, nil, device) + + messagingClient := bootstrapContainer.MessagingClientFrom(dic.Get) + if messagingClient == nil { + return noMessagingClientError + } + + publishTopic := fmt.Sprintf("%s/%s/%s/%s/%s/%s", + common.SystemEventsPublishTopicPrefix, + systemEvent.Source, + systemEvent.Type, + systemEvent.Action, + systemEvent.Owner, + device.ProfileName) + + payload, _ := json.Marshal(systemEvent) + + envelope := types.NewMessageEnvelope(payload, context.Background()) + envelope.CorrelationID = uuid.NewString() + envelope.ContentType = common.ContentTypeJSON + + if err := messagingClient.Publish(envelope, publishTopic); err != nil { + return fmt.Errorf("unable to publish '%s' Device System Event for %s to %s: %s", action, device.Name, publishTopic, err.Error()) + } + + lc.Debugf("Published the `%s` Device System Event for device `%s` to %s", action, device.Name, publishTopic) + + return nil +} diff --git a/internal/core/metadata/application/device_test.go b/internal/core/metadata/application/device_test.go new file mode 100644 index 0000000000..7f023e047f --- /dev/null +++ b/internal/core/metadata/application/device_test.go @@ -0,0 +1,124 @@ +// +// Copyright (C) 2022 Intel +// +// SPDX-License-Identifier: Apache-2.0 + +package application + +import ( + "encoding/json" + "errors" + "fmt" + "testing" + + "github.com/edgexfoundry/go-mod-messaging/v2/messaging/mocks" + "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" + "github.com/edgexfoundry/go-mod-bootstrap/v2/di" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" + "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos" + "github.com/edgexfoundry/go-mod-core-contracts/v2/models" +) + +func TestPublishDeviceSystemEvent(t *testing.T) { + mockClient := &mocks.MessageClient{} + lc := logger.NewMockClient() + + expectedDevice := models.Device{ + Name: "Camera-Device", + Id: uuid.NewString(), + ServiceName: "Device-onvif-camera", + ProfileName: "onvif-camera", + } + + tests := []struct { + Name string + Action string + PubError bool + ClientMissing bool + }{ + {"Device Add", common.DeviceSystemEventActionAdd, false, false}, + {"Device Update", common.DeviceSystemEventActionUpdate, false, false}, + {"Device Delete", common.DeviceSystemEventActionDelete, false, false}, + {"Publish Error", common.DeviceSystemEventActionAdd, true, false}, + {"Client Missing Error", common.DeviceSystemEventActionAdd, false, true}, + } + + pubErrMsg := errors.New("publish failed") + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + validatePublishCallFunc := func(envelope types.MessageEnvelope, topic string) error { + assert.Equal(t, common.ContentTypeJSON, envelope.ContentType) + assert.NotEmpty(t, envelope.CorrelationID) + require.NotEmpty(t, envelope.Payload) + systemEvent := dtos.SystemEvent{} + err := json.Unmarshal(envelope.Payload, &systemEvent) + require.NoError(t, err) + + assert.Equal(t, common.ApiVersion, systemEvent.ApiVersion) + assert.Equal(t, common.DeviceSystemEventType, systemEvent.Type) + assert.Equal(t, test.Action, systemEvent.Action) + assert.Equal(t, common.CoreMetaDataServiceKey, systemEvent.Source) + assert.Equal(t, expectedDevice.ServiceName, systemEvent.Owner) + assert.NotZero(t, systemEvent.Timestamp) + + actualDevice := dtos.Device{} + err = systemEvent.DecodeDetails(&actualDevice) + require.NoError(t, err) + + assert.Equal(t, expectedDevice.Name, actualDevice.Name) + assert.Equal(t, expectedDevice.Id, actualDevice.Id) + assert.Equal(t, expectedDevice.ServiceName, actualDevice.ServiceName) + assert.Equal(t, expectedDevice.ProfileName, actualDevice.ProfileName) + return nil + } + + if test.PubError { + mockClient.On("Publish", mock.Anything, mock.Anything).Return(pubErrMsg).Once() + } else { + mockClient.On("Publish", mock.Anything, mock.Anything).Return(validatePublishCallFunc).Once() + } + + dic := di.NewContainer(di.ServiceConstructorMap{}) + + if !test.ClientMissing { + dic.Update(di.ServiceConstructorMap{ + container.MessagingClientName: func(get di.Get) interface{} { + return mockClient + }, + }) + } + + err := publishDeviceSystemEvent(test.Action, expectedDevice, lc, dic) + + if test.PubError { + require.Error(t, err) + assert.Contains(t, err.Error(), pubErrMsg.Error()) + return + } else if test.ClientMissing { + require.Error(t, err) + assert.Equal(t, noMessagingClientError, err) + return + } + + expectedTopic := fmt.Sprintf("%s/%s/%s/%s/%s/%s", + common.SystemEventsPublishTopicPrefix, + common.CoreMetaDataServiceKey, + common.DeviceSystemEventType, + test.Action, + expectedDevice.ServiceName, + expectedDevice.ProfileName) + + if !test.ClientMissing { + mockClient.AssertCalled(t, "Publish", mock.Anything, expectedTopic) + } + }) + } +} diff --git a/internal/core/metadata/config/config.go b/internal/core/metadata/config/config.go index 275eff97e5..8a033aba8a 100644 --- a/internal/core/metadata/config/config.go +++ b/internal/core/metadata/config/config.go @@ -26,6 +26,7 @@ type ConfigurationStruct struct { Notifications NotificationInfo Registry bootstrapConfig.RegistryInfo Service bootstrapConfig.ServiceInfo + MessageQueue bootstrapConfig.MessageBusInfo SecretStore bootstrapConfig.SecretStoreInfo } @@ -87,10 +88,11 @@ func (c *ConfigurationStruct) UpdateWritableFromRaw(rawWritable interface{}) boo func (c *ConfigurationStruct) GetBootstrap() bootstrapConfig.BootstrapConfiguration { // temporary until we can make backwards-breaking configuration.toml change return bootstrapConfig.BootstrapConfiguration{ - Clients: c.Clients, - Service: c.Service, - Registry: c.Registry, - SecretStore: c.SecretStore, + Clients: c.Clients, + Service: c.Service, + Registry: c.Registry, + SecretStore: c.SecretStore, + MessageQueue: c.MessageQueue, } } diff --git a/internal/core/metadata/main.go b/internal/core/metadata/main.go index e9b9a59b07..64cff6d72d 100644 --- a/internal/core/metadata/main.go +++ b/internal/core/metadata/main.go @@ -25,14 +25,16 @@ import ( pkgHandlers "github.com/edgexfoundry/edgex-go/internal/pkg/bootstrap/handlers" "github.com/edgexfoundry/edgex-go/internal/pkg/telemetry" + "github.com/gorilla/mux" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" + "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/flags" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/handlers" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/interfaces" "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/startup" "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - "github.com/edgexfoundry/go-mod-core-contracts/v2/common" - "github.com/gorilla/mux" ) func Main(ctx context.Context, cancel context.CancelFunc, router *mux.Router) { @@ -70,6 +72,7 @@ func Main(ctx context.Context, cancel context.CancelFunc, router *mux.Router) { true, []interfaces.BootstrapHandler{ pkgHandlers.NewDatabase(httpServer, configuration, container.DBClientInterfaceName).BootstrapHandler, // add v2 db client bootstrap handler + handlers.MessagingBootstrapHandler, NewBootstrap(router, common.CoreMetaDataServiceKey).BootstrapHandler, telemetry.BootstrapHandler, httpServer.BootstrapHandler, From cd0b95ca18468f06f9af24007c680fb313b5a1e7 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Mon, 25 Jul 2022 15:35:06 -0600 Subject: [PATCH 2/8] fix: Addressed PR feedback from Cloud Signed-off-by: Leonard Goodell --- go.sum | 2 + internal/core/metadata/application/device.go | 35 +++++------ .../core/metadata/application/device_test.go | 60 ++++++++++++++----- 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/go.sum b/go.sum index 1f7e84f10f..c863ac0b05 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfENpMvdbAXAI= github.com/eclipse/paho.mqtt.golang v1.4.1/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= +github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10 h1:6gvrvqpXWS68wDkRAzmnkblUBZIadGpjlGZXuahfgyQ= +github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10/go.mod h1:HTrESzn1iz6C3Sg+3ZDBtklpkCxHX0Cf8sGFAFlwM8s= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0 h1:AZeaAPJM5X93ITFgwbwluYDtYEJ7tkCMSlj35GwfLLU= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0/go.mod h1:YP17JhMnXTitowXE13QJwFaKo0oc03iyoKLjWAYl4FE= github.com/edgexfoundry/go-mod-messaging/v2 v2.2.1-dev.11 h1:mvVU/eRl5GGIH1r/PDRgK3AR8Zsq81Lsi9qjduPsoFk= diff --git a/internal/core/metadata/application/device.go b/internal/core/metadata/application/device.go index 01f4ff5fa9..75b78f3dd5 100644 --- a/internal/core/metadata/application/device.go +++ b/internal/core/metadata/application/device.go @@ -24,8 +24,6 @@ import ( "github.com/edgexfoundry/go-mod-core-contracts/v2/errors" "github.com/edgexfoundry/go-mod-core-contracts/v2/models" "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" - - "github.com/google/uuid" ) // The AddDevice function accepts the new device model from the controller function @@ -66,8 +64,8 @@ func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id stri device := dtos.FromDeviceModelToDTO(d) go addDeviceCallback(ctx, dic, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error already has context. + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. lc.Error(err.Error()) } @@ -92,8 +90,8 @@ func DeleteDeviceByName(name string, ctx context.Context, dic *di.Container) err } go deleteDeviceCallback(ctx, dic, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error already has context. + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. lc.Error(err.Error()) } @@ -188,8 +186,8 @@ func PatchDevice(dto dtos.UpdateDevice, ctx context.Context, dic *di.Container) } go updateDeviceCallback(ctx, dic, device.ServiceName, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error already has context. + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. lc.Error(err.Error()) } @@ -266,19 +264,20 @@ func DevicesByProfileName(offset int, limit int, profileName string, dic *di.Con return devices, totalCount, nil } -var noMessagingClientError = goErrors.New("unable to publish Device System Event: MessageBus Client not available") +var noMessagingClientError = errors.NewCommonEdgeXWrapper(goErrors.New("unable to publish Device System Event: MessageBus Client not available")) -func publishDeviceSystemEvent(action string, d models.Device, lc logger.LoggingClient, dic *di.Container) error { +func publishDeviceSystemEvent(action string, d models.Device, ctx context.Context, lc logger.LoggingClient, dic *di.Container) errors.EdgeX { device := dtos.FromDeviceModelToDTO(d) systemEvent := dtos.NewSystemEvent(common.DeviceSystemEventType, action, common.CoreMetaDataServiceKey, device.ServiceName, nil, device) messagingClient := bootstrapContainer.MessagingClientFrom(dic.Get) if messagingClient == nil { - return noMessagingClientError + return &noMessagingClientError } + config := container.ConfigurationFrom(dic.Get) publishTopic := fmt.Sprintf("%s/%s/%s/%s/%s/%s", - common.SystemEventsPublishTopicPrefix, + config.MessageQueue.PublishTopicPrefix, systemEvent.Source, systemEvent.Type, systemEvent.Action, @@ -286,16 +285,18 @@ func publishDeviceSystemEvent(action string, d models.Device, lc logger.LoggingC device.ProfileName) payload, _ := json.Marshal(systemEvent) - - envelope := types.NewMessageEnvelope(payload, context.Background()) - envelope.CorrelationID = uuid.NewString() + envelope := types.NewMessageEnvelope(payload, ctx) + // Correlation ID and Content type are set by the above factory function from the context of the request that + // triggered this System Event. We'll keep that Correlation ID, but need to make sure the Content Type is set appropriate + // for how the payload was encoded above. envelope.ContentType = common.ContentTypeJSON if err := messagingClient.Publish(envelope, publishTopic); err != nil { - return fmt.Errorf("unable to publish '%s' Device System Event for %s to %s: %s", action, device.Name, publishTopic, err.Error()) + msg := fmt.Sprintf("unable to publish '%s' Device System Event for device '%s' to topic '%s'", action, device.Name, publishTopic) + return errors.NewCommonEdgeX(errors.KindCommunicationError, msg, err) } - lc.Debugf("Published the `%s` Device System Event for device `%s` to %s", action, device.Name, publishTopic) + lc.Debugf("Published the '%s' Device System Event for device '%s' to topic '%s'", action, device.Name, publishTopic) return nil } diff --git a/internal/core/metadata/application/device_test.go b/internal/core/metadata/application/device_test.go index 7f023e047f..b8f854a623 100644 --- a/internal/core/metadata/application/device_test.go +++ b/internal/core/metadata/application/device_test.go @@ -6,11 +6,16 @@ package application import ( + "context" "encoding/json" - "errors" + goErrors "errors" "fmt" "testing" + "github.com/edgexfoundry/edgex-go/internal/core/metadata/config" + "github.com/edgexfoundry/edgex-go/internal/core/metadata/container" + bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v2/config" + "github.com/edgexfoundry/go-mod-core-contracts/v2/errors" "github.com/edgexfoundry/go-mod-messaging/v2/messaging/mocks" "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" "github.com/google/uuid" @@ -18,7 +23,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" + bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" "github.com/edgexfoundry/go-mod-bootstrap/v2/di" "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" "github.com/edgexfoundry/go-mod-core-contracts/v2/common" @@ -27,7 +32,6 @@ import ( ) func TestPublishDeviceSystemEvent(t *testing.T) { - mockClient := &mocks.MessageClient{} lc := logger.NewMockClient() expectedDevice := models.Device{ @@ -37,6 +41,9 @@ func TestPublishDeviceSystemEvent(t *testing.T) { ProfileName: "onvif-camera", } + expectedCorrelationID := uuid.NewString() + expectedPublishTopicPrefix := "events/system-event" + tests := []struct { Name string Action string @@ -46,17 +53,26 @@ func TestPublishDeviceSystemEvent(t *testing.T) { {"Device Add", common.DeviceSystemEventActionAdd, false, false}, {"Device Update", common.DeviceSystemEventActionUpdate, false, false}, {"Device Delete", common.DeviceSystemEventActionDelete, false, false}, - {"Publish Error", common.DeviceSystemEventActionAdd, true, false}, {"Client Missing Error", common.DeviceSystemEventActionAdd, false, true}, + {"Publish Error", common.DeviceSystemEventActionAdd, true, false}, } - pubErrMsg := errors.New("publish failed") + pubErrMsg := errors.NewCommonEdgeXWrapper(goErrors.New("publish failed")) + + dic := di.NewContainer(di.ServiceConstructorMap{ + container.ConfigurationName: func(get di.Get) interface{} { + return &config.ConfigurationStruct{ + MessageQueue: bootstrapConfig.MessageBusInfo{ + PublishTopicPrefix: expectedPublishTopicPrefix}, + } + }, + }) for _, test := range tests { t.Run(test.Name, func(t *testing.T) { validatePublishCallFunc := func(envelope types.MessageEnvelope, topic string) error { assert.Equal(t, common.ContentTypeJSON, envelope.ContentType) - assert.NotEmpty(t, envelope.CorrelationID) + assert.Equal(t, expectedCorrelationID, envelope.CorrelationID) require.NotEmpty(t, envelope.Payload) systemEvent := dtos.SystemEvent{} err := json.Unmarshal(envelope.Payload, &systemEvent) @@ -80,36 +96,48 @@ func TestPublishDeviceSystemEvent(t *testing.T) { return nil } + mockClient := &mocks.MessageClient{} + if test.PubError { - mockClient.On("Publish", mock.Anything, mock.Anything).Return(pubErrMsg).Once() + mockClient.On("Publish", mock.Anything, mock.Anything).Return(pubErrMsg) } else { - mockClient.On("Publish", mock.Anything, mock.Anything).Return(validatePublishCallFunc).Once() + mockClient.On("Publish", mock.Anything, mock.Anything).Return(validatePublishCallFunc) } - dic := di.NewContainer(di.ServiceConstructorMap{}) - - if !test.ClientMissing { + if test.ClientMissing { dic.Update(di.ServiceConstructorMap{ - container.MessagingClientName: func(get di.Get) interface{} { + bootstrapContainer.MessagingClientName: func(get di.Get) interface{} { + return nil + }, + }) + } else { + dic.Update(di.ServiceConstructorMap{ + bootstrapContainer.MessagingClientName: func(get di.Get) interface{} { return mockClient }, }) } - err := publishDeviceSystemEvent(test.Action, expectedDevice, lc, dic) + // Use CBOR to make sure publisher override with JSON properly + ctx := context.WithValue(context.Background(), common.ContentType, common.ContentTypeCBOR) + ctx = context.WithValue(ctx, common.CorrelationHeader, expectedCorrelationID) + + err := publishDeviceSystemEvent(test.Action, expectedDevice, ctx, lc, dic) if test.PubError { require.Error(t, err) assert.Contains(t, err.Error(), pubErrMsg.Error()) return - } else if test.ClientMissing { + } + + if test.ClientMissing { require.Error(t, err) - assert.Equal(t, noMessagingClientError, err) + assert.Equal(t, &noMessagingClientError, err) return } expectedTopic := fmt.Sprintf("%s/%s/%s/%s/%s/%s", - common.SystemEventsPublishTopicPrefix, + expectedPublishTopicPrefix, common.CoreMetaDataServiceKey, common.DeviceSystemEventType, test.Action, From 1fb3709a900fef8f42057a4471cf0a7aa8a5e673 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Tue, 26 Jul 2022 12:21:19 -0600 Subject: [PATCH 3/8] fix: Address PR feedback on using go func Signed-off-by: Leonard Goodell --- internal/core/metadata/application/device.go | 30 ++++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/internal/core/metadata/application/device.go b/internal/core/metadata/application/device.go index 75b78f3dd5..b948de14ef 100644 --- a/internal/core/metadata/application/device.go +++ b/internal/core/metadata/application/device.go @@ -64,10 +64,12 @@ func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id stri device := dtos.FromDeviceModelToDTO(d) go addDeviceCallback(ctx, dic, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } + go func() { + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. + lc.Error(err.Error()) + } + }() return addedDevice.Id, nil } @@ -90,10 +92,12 @@ func DeleteDeviceByName(name string, ctx context.Context, dic *di.Container) err } go deleteDeviceCallback(ctx, dic, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } + go func() { + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. + lc.Error(err.Error()) + } + }() return nil } @@ -186,10 +190,12 @@ func PatchDevice(dto dtos.UpdateDevice, ctx context.Context, dic *di.Container) } go updateDeviceCallback(ctx, dic, device.ServiceName, device) - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } + go func() { + if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, ctx, lc, dic); err != nil { + // Don't fail request if couldn't publish, just log it. Error message already has context. + lc.Error(err.Error()) + } + }() return nil } From 348c9fcd81b28ae0b629d817f45cdb40bc994cb7 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Wed, 27 Jul 2022 10:16:19 -0600 Subject: [PATCH 4/8] refact: Reworked error handling and unit testing of errors Signed-off-by: Leonard Goodell --- internal/core/metadata/application/device.go | 39 ++++++------------- .../core/metadata/application/device_test.go | 26 ++++++------- 2 files changed, 23 insertions(+), 42 deletions(-) diff --git a/internal/core/metadata/application/device.go b/internal/core/metadata/application/device.go index b948de14ef..6c34b023f3 100644 --- a/internal/core/metadata/application/device.go +++ b/internal/core/metadata/application/device.go @@ -64,12 +64,7 @@ func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id stri device := dtos.FromDeviceModelToDTO(d) go addDeviceCallback(ctx, dic, device) - go func() { - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } - }() + go publishDeviceSystemEvent(common.DeviceSystemEventActionAdd, d.ServiceName, d, ctx, lc, dic) return addedDevice.Id, nil } @@ -92,12 +87,7 @@ func DeleteDeviceByName(name string, ctx context.Context, dic *di.Container) err } go deleteDeviceCallback(ctx, dic, device) - go func() { - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } - }() + go publishDeviceSystemEvent(common.DeviceSystemEventActionDelete, device.ServiceName, device, ctx, lc, dic) return nil } @@ -187,15 +177,11 @@ func PatchDevice(dto dtos.UpdateDevice, ctx context.Context, dic *di.Container) if oldServiceName != "" { go updateDeviceCallback(ctx, dic, oldServiceName, device) + go publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, oldServiceName, device, ctx, lc, dic) } - go updateDeviceCallback(ctx, dic, device.ServiceName, device) - go func() { - if err := publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device, ctx, lc, dic); err != nil { - // Don't fail request if couldn't publish, just log it. Error message already has context. - lc.Error(err.Error()) - } - }() + go updateDeviceCallback(ctx, dic, device.ServiceName, device) + go publishDeviceSystemEvent(common.DeviceSystemEventActionUpdate, device.ServiceName, device, ctx, lc, dic) return nil } @@ -270,15 +256,16 @@ func DevicesByProfileName(offset int, limit int, profileName string, dic *di.Con return devices, totalCount, nil } -var noMessagingClientError = errors.NewCommonEdgeXWrapper(goErrors.New("unable to publish Device System Event: MessageBus Client not available")) +var noMessagingClientError = goErrors.New(": MessageBus Client not available") -func publishDeviceSystemEvent(action string, d models.Device, ctx context.Context, lc logger.LoggingClient, dic *di.Container) errors.EdgeX { +func publishDeviceSystemEvent(action string, owner string, d models.Device, ctx context.Context, lc logger.LoggingClient, dic *di.Container) { device := dtos.FromDeviceModelToDTO(d) - systemEvent := dtos.NewSystemEvent(common.DeviceSystemEventType, action, common.CoreMetaDataServiceKey, device.ServiceName, nil, device) + systemEvent := dtos.NewSystemEvent(common.DeviceSystemEventType, action, common.CoreMetaDataServiceKey, owner, nil, device) messagingClient := bootstrapContainer.MessagingClientFrom(dic.Get) if messagingClient == nil { - return &noMessagingClientError + lc.Errorf("unable to publish Device System Event: %v", noMessagingClientError) + return } config := container.ConfigurationFrom(dic.Get) @@ -298,11 +285,9 @@ func publishDeviceSystemEvent(action string, d models.Device, ctx context.Contex envelope.ContentType = common.ContentTypeJSON if err := messagingClient.Publish(envelope, publishTopic); err != nil { - msg := fmt.Sprintf("unable to publish '%s' Device System Event for device '%s' to topic '%s'", action, device.Name, publishTopic) - return errors.NewCommonEdgeX(errors.KindCommunicationError, msg, err) + lc.Errorf("unable to publish '%s' Device System Event for device '%s' to topic '%s': %v", action, device.Name, publishTopic, err) + return } lc.Debugf("Published the '%s' Device System Event for device '%s' to topic '%s'", action, device.Name, publishTopic) - - return nil } diff --git a/internal/core/metadata/application/device_test.go b/internal/core/metadata/application/device_test.go index b8f854a623..925cc0b814 100644 --- a/internal/core/metadata/application/device_test.go +++ b/internal/core/metadata/application/device_test.go @@ -15,6 +15,7 @@ import ( "github.com/edgexfoundry/edgex-go/internal/core/metadata/config" "github.com/edgexfoundry/edgex-go/internal/core/metadata/container" bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v2/config" + mocks2 "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger/mocks" "github.com/edgexfoundry/go-mod-core-contracts/v2/errors" "github.com/edgexfoundry/go-mod-messaging/v2/messaging/mocks" "github.com/edgexfoundry/go-mod-messaging/v2/pkg/types" @@ -25,15 +26,12 @@ import ( bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container" "github.com/edgexfoundry/go-mod-bootstrap/v2/di" - "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" "github.com/edgexfoundry/go-mod-core-contracts/v2/common" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos" "github.com/edgexfoundry/go-mod-core-contracts/v2/models" ) func TestPublishDeviceSystemEvent(t *testing.T) { - lc := logger.NewMockClient() - expectedDevice := models.Device{ Name: "Camera-Device", Id: uuid.NewString(), @@ -97,14 +95,18 @@ func TestPublishDeviceSystemEvent(t *testing.T) { } mockClient := &mocks.MessageClient{} + mockLogger := &mocks2.LoggingClient{} + mockLogger.On("Debugf", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() if test.PubError { mockClient.On("Publish", mock.Anything, mock.Anything).Return(pubErrMsg) + mockLogger.On("Errorf", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() } else { mockClient.On("Publish", mock.Anything, mock.Anything).Return(validatePublishCallFunc) } if test.ClientMissing { + mockLogger.On("Errorf", mock.Anything, mock.Anything).Return() dic.Update(di.ServiceConstructorMap{ bootstrapContainer.MessagingClientName: func(get di.Get) interface{} { return nil @@ -118,21 +120,14 @@ func TestPublishDeviceSystemEvent(t *testing.T) { }) } - // Use CBOR to make sure publisher override with JSON properly + // Use CBOR to make sure publisher overrides with JSON properly ctx := context.WithValue(context.Background(), common.ContentType, common.ContentTypeCBOR) ctx = context.WithValue(ctx, common.CorrelationHeader, expectedCorrelationID) - err := publishDeviceSystemEvent(test.Action, expectedDevice, ctx, lc, dic) - - if test.PubError { - require.Error(t, err) - assert.Contains(t, err.Error(), pubErrMsg.Error()) - return - } + publishDeviceSystemEvent(test.Action, expectedDevice.ServiceName, expectedDevice, ctx, mockLogger, dic) if test.ClientMissing { - require.Error(t, err) - assert.Equal(t, &noMessagingClientError, err) + mockLogger.AssertCalled(t, "Errorf", mock.Anything, noMessagingClientError) return } @@ -143,9 +138,10 @@ func TestPublishDeviceSystemEvent(t *testing.T) { test.Action, expectedDevice.ServiceName, expectedDevice.ProfileName) + mockClient.AssertCalled(t, "Publish", mock.Anything, expectedTopic) - if !test.ClientMissing { - mockClient.AssertCalled(t, "Publish", mock.Anything, expectedTopic) + if test.PubError { + mockLogger.AssertCalled(t, "Errorf", mock.Anything, mock.Anything, mock.Anything, mock.Anything, pubErrMsg) } }) } From 058deb0066f883b9aa6f7fcc59b8cfc30c2963b0 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Wed, 27 Jul 2022 10:28:20 -0600 Subject: [PATCH 5/8] build: Updated to latest go-mods Signed-off-by: Leonard Goodell --- go.sum | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/go.sum b/go.sum index c863ac0b05..d21e5bd5c0 100644 --- a/go.sum +++ b/go.sum @@ -36,12 +36,14 @@ github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10 h1:6gvrvqpXWS68wDkRAzm github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10/go.mod h1:HTrESzn1iz6C3Sg+3ZDBtklpkCxHX0Cf8sGFAFlwM8s= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0 h1:AZeaAPJM5X93ITFgwbwluYDtYEJ7tkCMSlj35GwfLLU= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0/go.mod h1:YP17JhMnXTitowXE13QJwFaKo0oc03iyoKLjWAYl4FE= -github.com/edgexfoundry/go-mod-messaging/v2 v2.2.1-dev.11 h1:mvVU/eRl5GGIH1r/PDRgK3AR8Zsq81Lsi9qjduPsoFk= -github.com/edgexfoundry/go-mod-messaging/v2 v2.2.1-dev.11/go.mod h1:h7iBbErPlPBEjYoO5UpwdFxR+Tqg/eObEbNGy2INVlo= +github.com/edgexfoundry/go-mod-core-contracts/v2 v2.3.0-dev.13 h1:lPjtuVk2QXoUxs6sAsb0qflxmREB5kgHIjFrkNNnx6A= +github.com/edgexfoundry/go-mod-core-contracts/v2 v2.3.0-dev.13/go.mod h1:YdJ0iBWad86sgOs6am01mE3IAX6d22H08f/enVho4TU= +github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12 h1:YdO9V8pSFK3L2FSpPru3OulK0kFCt96+tsdxTtkfeqk= +github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12/go.mod h1:yLJ9EK4Feg409FDr0oP87LbaRLyOSGJk/ikaIfEDKcI= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0 h1:dk9ul1t7INAiyZXeu/GrpinFE3qOekdy8uZOqEGgIiE= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0/go.mod h1:DUQRnAd5fVzoROc5SI+PTFUD/vCNeZmZHBMrLElbmwI= -github.com/edgexfoundry/go-mod-secrets/v2 v2.2.1-dev.5 h1:B6LCod0L4qh/+zZdzoMucL7lArZrT1NIpT5naya+CXU= -github.com/edgexfoundry/go-mod-secrets/v2 v2.2.1-dev.5/go.mod h1:h/FohFNY8xHalioLg1bhjAuEj0z+danSDtixirvaXmQ= +github.com/edgexfoundry/go-mod-secrets/v2 v2.3.0-dev.5 h1:wksbHWGDllkrkjoeRTrhcQcPaP5iiub/i2EuwHyPmEo= +github.com/edgexfoundry/go-mod-secrets/v2 v2.3.0-dev.5/go.mod h1:h/FohFNY8xHalioLg1bhjAuEj0z+danSDtixirvaXmQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -144,6 +146,8 @@ github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -170,6 +174,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/consulstructure v0.0.0-20190329231841-56fdc4d2da54 h1:DcITQwl3ymmg7i1XfwpZFs/TPv2PuTwxE8bnuKVtKlk= github.com/mitchellh/consulstructure v0.0.0-20190329231841-56fdc4d2da54/go.mod h1:dIfpPVUR+ZfkzkDcKnn+oPW1jKeXe4WlNWc7rIXOVxM= @@ -184,6 +190,15 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= +github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= +github.com/nats-io/nats-server/v2 v2.7.4 h1:c+BZJ3rGzUKCBIM4IXO8uNT2u1vajGbD1kPA6wqCEaM= +github.com/nats-io/nats.go v1.16.0 h1:zvLE7fGBQYW6MWaFaRdsgm9qT39PJDQoju+DS8KsO1g= +github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -236,8 +251,10 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -255,6 +272,7 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -270,6 +288,7 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -301,6 +320,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= From 29ffd965fa8419669e59c50361a9bcc36f344f53 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Wed, 27 Jul 2022 11:09:05 -0600 Subject: [PATCH 6/8] fix: Added the PublishTopicPrefix to MessageQueue config Signed-off-by: Leonard Goodell --- cmd/core-metadata/res/configuration.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/core-metadata/res/configuration.toml b/cmd/core-metadata/res/configuration.toml index 7bb9f717ae..7e3b9d6daa 100644 --- a/cmd/core-metadata/res/configuration.toml +++ b/cmd/core-metadata/res/configuration.toml @@ -61,6 +61,7 @@ Protocol = "redis" Host = "localhost" Port = 6379 Type = "redis" +PublishTopicPrefix = "edgex/system-events" # ///// will be added to this Publish Topic prefix AuthMode = "usernamepassword" # required for redis messagebus (secure or insecure). SecretName = "redisdb" [MessageQueue.Optional] From 117e2df7b6cae2ee87dd30406dcca0dd0a184a47 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Wed, 27 Jul 2022 15:39:53 -0600 Subject: [PATCH 7/8] fix: Addressed linter issues in unit test Signed-off-by: Leonard Goodell --- internal/core/metadata/application/device_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/core/metadata/application/device_test.go b/internal/core/metadata/application/device_test.go index 925cc0b814..8541c7ba0c 100644 --- a/internal/core/metadata/application/device_test.go +++ b/internal/core/metadata/application/device_test.go @@ -121,7 +121,11 @@ func TestPublishDeviceSystemEvent(t *testing.T) { } // Use CBOR to make sure publisher overrides with JSON properly + // lint:ignore SA1029 legacy + // nolint:staticcheck // See golangci-lint #741 ctx := context.WithValue(context.Background(), common.ContentType, common.ContentTypeCBOR) + // lint:ignore SA1029 legacy + // nolint:staticcheck // See golangci-lint #741 ctx = context.WithValue(ctx, common.CorrelationHeader, expectedCorrelationID) publishDeviceSystemEvent(test.Action, expectedDevice.ServiceName, expectedDevice, ctx, mockLogger, dic) From cb23cb096a40bcf1b7afd5b14df285b5ab964b07 Mon Sep 17 00:00:00 2001 From: Leonard Goodell Date: Thu, 28 Jul 2022 10:41:19 -0600 Subject: [PATCH 8/8] fix: Reverted go-mod-serects version Newest version may be causing issue and not needed in this PR. Signed-off-by: Leonard Goodell --- go.mod | 5 ----- go.sum | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 497487db62..65897c23e0 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,5 @@ module github.com/edgexfoundry/edgex-go -replace ( - github.com/edgexfoundry/go-mod-bootstrap/v2 => ../MODS/go-mod-bootstrap - github.com/edgexfoundry/go-mod-core-contracts/v2 => ../MODS/go-mod-core-contracts -) - require ( bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690 github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11 diff --git a/go.sum b/go.sum index d21e5bd5c0..d320486c67 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfENpMvdbAXAI= github.com/eclipse/paho.mqtt.golang v1.4.1/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= -github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10 h1:6gvrvqpXWS68wDkRAzmnkblUBZIadGpjlGZXuahfgyQ= -github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.10/go.mod h1:HTrESzn1iz6C3Sg+3ZDBtklpkCxHX0Cf8sGFAFlwM8s= +github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11 h1:HQpkdjcD6nVimvXYtpVbzJNBOOtcoFOcSLN8uyiBkvs= +github.com/edgexfoundry/go-mod-bootstrap/v2 v2.3.0-dev.11/go.mod h1:HTrESzn1iz6C3Sg+3ZDBtklpkCxHX0Cf8sGFAFlwM8s= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0 h1:AZeaAPJM5X93ITFgwbwluYDtYEJ7tkCMSlj35GwfLLU= github.com/edgexfoundry/go-mod-configuration/v2 v2.2.0/go.mod h1:YP17JhMnXTitowXE13QJwFaKo0oc03iyoKLjWAYl4FE= github.com/edgexfoundry/go-mod-core-contracts/v2 v2.3.0-dev.13 h1:lPjtuVk2QXoUxs6sAsb0qflxmREB5kgHIjFrkNNnx6A= @@ -42,8 +42,8 @@ github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12 h1:YdO9V8pSFK3L2FSpPru github.com/edgexfoundry/go-mod-messaging/v2 v2.3.0-dev.12/go.mod h1:yLJ9EK4Feg409FDr0oP87LbaRLyOSGJk/ikaIfEDKcI= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0 h1:dk9ul1t7INAiyZXeu/GrpinFE3qOekdy8uZOqEGgIiE= github.com/edgexfoundry/go-mod-registry/v2 v2.2.0/go.mod h1:DUQRnAd5fVzoROc5SI+PTFUD/vCNeZmZHBMrLElbmwI= -github.com/edgexfoundry/go-mod-secrets/v2 v2.3.0-dev.5 h1:wksbHWGDllkrkjoeRTrhcQcPaP5iiub/i2EuwHyPmEo= -github.com/edgexfoundry/go-mod-secrets/v2 v2.3.0-dev.5/go.mod h1:h/FohFNY8xHalioLg1bhjAuEj0z+danSDtixirvaXmQ= +github.com/edgexfoundry/go-mod-secrets/v2 v2.2.1-dev.5 h1:B6LCod0L4qh/+zZdzoMucL7lArZrT1NIpT5naya+CXU= +github.com/edgexfoundry/go-mod-secrets/v2 v2.2.1-dev.5/go.mod h1:h/FohFNY8xHalioLg1bhjAuEj0z+danSDtixirvaXmQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=