133 lines
4.8 KiB
Go
133 lines
4.8 KiB
Go
// -*- Mode: Go; indent-tabs-mode: t -*-
|
|
//
|
|
// Copyright (C) 2017-2018 Canonical Ltd
|
|
// Copyright (C) 2018-2025 IOTech Ltd
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package common
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/edgexfoundry/device-sdk-go/v4/internal/cache"
|
|
"github.com/edgexfoundry/device-sdk-go/v4/internal/container"
|
|
|
|
bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/container"
|
|
bootstrapInterfaces "github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/interfaces"
|
|
"github.com/edgexfoundry/go-mod-bootstrap/v4/di"
|
|
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/interfaces"
|
|
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/logger"
|
|
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
|
|
"github.com/edgexfoundry/go-mod-core-contracts/v4/dtos"
|
|
"github.com/edgexfoundry/go-mod-core-contracts/v4/dtos/requests"
|
|
"github.com/edgexfoundry/go-mod-messaging/v4/pkg/types"
|
|
|
|
gometrics "github.com/rcrowley/go-metrics"
|
|
)
|
|
|
|
const (
|
|
eventsSentName = "EventsSent"
|
|
readingsSentName = "ReadingsSent"
|
|
DeviceServiceEventPrefix = "device"
|
|
)
|
|
|
|
// TODO: Refactor code in 3.0 to encapsulate this in a struct, factory func and
|
|
var eventsSent gometrics.Counter
|
|
var readingsSent gometrics.Counter
|
|
|
|
func UpdateOperatingState(name string, state string, lc logger.LoggingClient, dc interfaces.DeviceClient) {
|
|
device := dtos.UpdateDevice{
|
|
Name: &name,
|
|
OperatingState: &state,
|
|
}
|
|
|
|
req := requests.NewUpdateDeviceRequest(device)
|
|
_, err := dc.Update(context.Background(), []requests.UpdateDeviceRequest{req})
|
|
if err != nil {
|
|
lc.Errorf("failed to update OperatingState for Device %s in Core Metadata: %v", name, err)
|
|
}
|
|
}
|
|
|
|
func SendEvent(event *dtos.Event, correlationID string, dic *di.Container) {
|
|
lc := bootstrapContainer.LoggingClientFrom(dic.Get)
|
|
configuration := container.ConfigurationFrom(dic.Get)
|
|
ctx := context.WithValue(context.Background(), common.CorrelationHeader, correlationID) // nolint: staticcheck
|
|
req := requests.NewAddEventRequest(*event)
|
|
encoding := req.GetEncodingContentType()
|
|
ctx = context.WithValue(ctx, common.ContentType, encoding) // nolint: staticcheck
|
|
envelope := types.NewMessageEnvelope(req, ctx)
|
|
|
|
sent := false
|
|
mc := bootstrapContainer.MessagingClientFrom(dic.Get)
|
|
serviceName := container.DeviceServiceFrom(dic.Get).Name
|
|
publishTopic := common.NewPathBuilder().EnableNameFieldEscape(configuration.Service.EnableNameFieldEscape).
|
|
SetPath(configuration.MessageBus.GetBaseTopicPrefix()).SetPath(common.EventsPublishTopic).SetPath(DeviceServiceEventPrefix).
|
|
SetNameFieldPath(serviceName).SetNameFieldPath(event.ProfileName).SetNameFieldPath(event.DeviceName).SetNameFieldPath(event.SourceName).BuildPath()
|
|
err := mc.PublishWithSizeLimit(envelope, publishTopic, configuration.MaxEventSize)
|
|
if err != nil {
|
|
lc.Errorf("Failed to publish event to MessageBus: %s", err)
|
|
return
|
|
}
|
|
lc.Debugf("Event(profileName: %s, deviceName: %s, sourceName: %s, id: %s) published to MessageBus on topic: %s",
|
|
event.ProfileName, event.DeviceName, event.SourceName, event.Id, publishTopic)
|
|
sent = true
|
|
|
|
if sent && eventsSent != nil && readingsSent != nil {
|
|
eventsSent.Inc(1)
|
|
readingsSent.Inc(int64(len(event.Readings)))
|
|
}
|
|
}
|
|
|
|
func InitializeSentMetrics(lc logger.LoggingClient, dic *di.Container) {
|
|
eventsSent = gometrics.NewCounter()
|
|
readingsSent = gometrics.NewCounter()
|
|
|
|
metricsManager := bootstrapContainer.MetricsManagerFrom(dic.Get)
|
|
if metricsManager != nil {
|
|
registerMetric(metricsManager, lc, eventsSentName, eventsSent)
|
|
registerMetric(metricsManager, lc, readingsSentName, readingsSent)
|
|
} else {
|
|
lc.Warn("MetricsManager not available to register Event/Reading Sent metrics")
|
|
}
|
|
}
|
|
|
|
func registerMetric(metricsManager bootstrapInterfaces.MetricsManager, lc logger.LoggingClient, name string, metric interface{}) {
|
|
err := metricsManager.Register(name, metric, nil)
|
|
if err != nil {
|
|
lc.Errorf("unable to register %s metric. Metric will not be reported: %v", name, err)
|
|
} else {
|
|
lc.Debugf("%s metric has been registered and will be reported (if enabled)", name)
|
|
}
|
|
}
|
|
|
|
func AddEventTags(event *dtos.Event) {
|
|
if event.Tags == nil {
|
|
event.Tags = make(map[string]interface{})
|
|
}
|
|
cmd, cmdExist := cache.Profiles().DeviceCommand(event.ProfileName, event.SourceName)
|
|
if cmdExist && len(cmd.Tags) > 0 {
|
|
for k, v := range cmd.Tags {
|
|
event.Tags[k] = v
|
|
}
|
|
}
|
|
device, deviceExist := cache.Devices().ForName(event.DeviceName)
|
|
if deviceExist && len(device.Tags) > 0 {
|
|
for k, v := range device.Tags {
|
|
event.Tags[k] = v
|
|
}
|
|
}
|
|
}
|
|
|
|
func AddReadingTags(reading *dtos.BaseReading) {
|
|
dr, drExist := cache.Profiles().DeviceResource(reading.ProfileName, reading.ResourceName)
|
|
if drExist && len(dr.Tags) > 0 {
|
|
if reading.Tags == nil {
|
|
reading.Tags = make(map[string]interface{})
|
|
}
|
|
for k, v := range dr.Tags {
|
|
reading.Tags[k] = v
|
|
}
|
|
}
|
|
}
|