Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3a56396
docs: Update CoreData API doc (#5127)
weichou1229 Apr 8, 2025
db0fc15
fix: Allow any value by setting additionalProperties: true
jumpingliu Apr 11, 2025
b4e1559
docs: update core-metadata API doc with correct sample
judehung Apr 14, 2025
78abf55
feat: Query events without total count (#5135)
weichou1229 Apr 21, 2025
7374d97
fix: added missing retention field on core-metadata API docs
jumpingliu May 6, 2025
b6f448d
fix: Add missing properties in UpdateDeviceService schema
yichun-chou May 23, 2025
340b319
docs: Correct schema definition for discoveredDevice
yichun-chou May 28, 2025
a14c023
docs: Correct typo from allof to allOf in discoveredDevice schema
yichun-chou May 28, 2025
85775da
fix: CoreCommand GET /device/all API check profile is empty (#5164)
weichou1229 May 29, 2025
cf15865
fix: Fix CoreCommand GET /device/all API incorrect totalCount (#5174)
weichou1229 Jun 9, 2025
0ed5dde
fix: Windows path in db init sql (#5170)
cloudxxx8 Jun 5, 2025
59ece57
fix: Fix event query incorrect return data when enabling EventPurge (…
weichou1229 Jun 10, 2025
198b64e
docs: Add missing ObjectReading in Event Readings schema
yichun-chou Jun 13, 2025
cbdcbb1
docs: Add missing jsonObject param in GET /device/name/{name}/{command}
yichun-chou Jun 16, 2025
a698ce4
fix: Run MessageBus command request processing in goroutines (#5186)
FelixTing Jun 18, 2025
e6d2a53
fix: CoreData apply default retention policy to none autoEvent (#5189)
weichou1229 Jun 20, 2025
72e010c
feat: Add event_id index on Core Data reading table (#5190)
weichou1229 Jun 23, 2025
a425050
docs: Correct Readings API schema in document
yichun-chou Jun 24, 2025
aa52f99
feat: Publish key change event after key deletion (#5200)
FelixTing Jul 2, 2025
efad9a1
fix: Fix two SonarQube scan failures
judehung Aug 8, 2025
738e5d8
build(deps): Upgrade EdgeX go modules
FelixTing Nov 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ go 1.23
require (
github.com/blang/semver/v4 v4.0.0
github.com/eclipse/paho.mqtt.golang v1.5.0
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.3
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.1
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.1
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.1
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.4
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.2
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.2
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.2
github.com/edgexfoundry/go-mod-secrets/v4 v4.0.1
github.com/fxamacker/cbor/v2 v2.7.0
github.com/go-co-op/gocron/v2 v2.16.0
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.3 h1:hEZrqu1Q7psVD3U9uXThlhyH+7Si0kKwgy4S88Wr/wc=
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.3/go.mod h1:eSj+XlUqX7NmVmj4aTy9Tji0LcjKH1Cidnz9sm+TlpM=
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.1 h1:yU3YhRrxrTzF4ERhf0TUJQ0XhEPWGjQutnAWS2++QT4=
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.1/go.mod h1:exeeN1OQkpWvKCH+FWPHXuBiQIyvzwWIS6LXk8c79aM=
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.1 h1:gLgs/oTNdIb0qbyhPGFOhS7t+mNuLmlDvdgu9qVtVnw=
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.1/go.mod h1:AF1bbO7aA1ZdtZ7r/lQHV4OjiHtSzK5iDiW+PqWDCUc=
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.1 h1:q2FZ+O1CYs5W2crQaDZ0WYyIWFh9pNUumdbQ2SP0YWs=
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.1/go.mod h1:vlu2E7wnFxhYqmxP/XmryRaX1EdJu0fCMbxS/nb+1dE=
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.4 h1:WWt/QcfEzfaj0jF/oAFmeGz5rE3SGi4gXQBzvv0Phzo=
github.com/edgexfoundry/go-mod-bootstrap/v4 v4.0.4/go.mod h1:BTYaYltpqas2XO+xcUT4sIRAHoAz/Xk/z21tpBP5nk4=
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.2 h1:quoEb8V1hJEu69yIPOHvyNao6MeitqxzS7qFGqDGnOo=
github.com/edgexfoundry/go-mod-configuration/v4 v4.0.2/go.mod h1:nJCcQr9NGJnNHMF+Nk/f68sHZTfGfb2F57Yd8T80Tz0=
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.2 h1:U1iXpuRmAm1EG6ld7VSEoIwxTOsi/ipg3GtYWsAZ1AI=
github.com/edgexfoundry/go-mod-core-contracts/v4 v4.0.2/go.mod h1:AF1bbO7aA1ZdtZ7r/lQHV4OjiHtSzK5iDiW+PqWDCUc=
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.2 h1:/YARz87MiIUeOZhNmBQpaUjCeL5zM5BalUSFYo9iF/0=
github.com/edgexfoundry/go-mod-messaging/v4 v4.0.2/go.mod h1:/skwSGlxA9qe6b5ZsSRIbAB9yw3XV8QFcEmEW9CxEw4=
github.com/edgexfoundry/go-mod-registry/v4 v4.0.1 h1:U5HcQ4dChjrC1ZQttzP4SmWZ11xjTUzzKa55Pk3t8Z4=
github.com/edgexfoundry/go-mod-registry/v4 v4.0.1/go.mod h1:qKkvkSOdDDQZMeeDYI4nOhjsx719N1Dp26AhMMvMGuY=
github.com/edgexfoundry/go-mod-secrets/v4 v4.0.1 h1:YUQIUvMzQSZLR/bR4qNLMw6woCZo3RZJWaGd2i/6TsA=
Expand Down
13 changes: 8 additions & 5 deletions internal/core/command/application/command.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (C) 2021 IOTech Ltd
// Copyright (C) 2021-2025 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -43,8 +43,11 @@ func AllCommands(offset int, limit int, dic *di.Container) (deviceCoreCommands [
configuration := commandContainer.ConfigurationFrom(dic.Get)
serviceUrl := configuration.Service.Url()

deviceCoreCommands = make([]dtos.DeviceCoreCommand, len(multiDevicesResponse.Devices))
for i, device := range multiDevicesResponse.Devices {
for _, device := range multiDevicesResponse.Devices {
if len(device.ProfileName) == 0 {
// if the profile is not set, skip the profile query
continue
}
deviceProfileResponse, err := dpc.DeviceProfileByName(context.Background(), device.ProfileName)
if err != nil {
return deviceCoreCommands, totalCount, errors.NewCommonEdgeXWrapper(err)
Expand All @@ -53,11 +56,11 @@ func AllCommands(offset int, limit int, dic *di.Container) (deviceCoreCommands [
if err != nil {
return nil, totalCount, errors.NewCommonEdgeXWrapper(err)
}
deviceCoreCommands[i] = dtos.DeviceCoreCommand{
deviceCoreCommands = append(deviceCoreCommands, dtos.DeviceCoreCommand{
DeviceName: device.Name,
ProfileName: device.ProfileName,
CoreCommands: commands,
}
})
}
return deviceCoreCommands, multiDevicesResponse.TotalCount, nil
}
Expand Down
76 changes: 73 additions & 3 deletions internal/core/command/application/command_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
//
// Copyright (C) 2021 IOTech Ltd
// Copyright (C) 2021-2025 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

package application

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/edgexfoundry/edgex-go/internal/core/command/config"
"github.com/edgexfoundry/edgex-go/internal/core/command/container"

bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/container"
bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v4/config"
"github.com/edgexfoundry/go-mod-bootstrap/v4/di"
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/interfaces/mocks"
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
"github.com/edgexfoundry/go-mod-core-contracts/v4/dtos"

"github.com/stretchr/testify/assert"
dtosCommon "github.com/edgexfoundry/go-mod-core-contracts/v4/dtos/common"
"github.com/edgexfoundry/go-mod-core-contracts/v4/dtos/responses"
)

const (
Expand Down Expand Up @@ -97,3 +106,64 @@ func TestBuildCoreCommands(t *testing.T) {

assert.ElementsMatch(t, expectedCoreCommand, result)
}

func TestAllCommands(t *testing.T) {
ctx := context.Background()
device1 := dtos.Device{Name: "test-device-1", ProfileName: "test-profile-1"}
device2 := dtos.Device{Name: "test-device-2", ProfileName: "test-profile-2"}
device3 := dtos.Device{Name: "test-device-3", ProfileName: ""}

dic := di.NewContainer(di.ServiceConstructorMap{})
dc := &mocks.DeviceClient{}
dpc := &mocks.DeviceProfileClient{}
dpc.On("DeviceProfileByName", ctx, device1.ProfileName).Return(responses.DeviceProfileResponse{}, nil)
dpc.On("DeviceProfileByName", ctx, device2.ProfileName).Return(responses.DeviceProfileResponse{}, nil)
dic.Update(di.ServiceConstructorMap{
container.ConfigurationName: func(get di.Get) interface{} {
return &config.ConfigurationStruct{
Service: bootstrapConfig.ServiceInfo{
Host: "localhost",
Port: 59882,
},
}
},
bootstrapContainer.DeviceClientName: func(get di.Get) interface{} {
return dc
},
bootstrapContainer.DeviceProfileClientName: func(get di.Get) interface{} {
return dpc
},
})

tests := []struct {
name string
multiDevicesResponse responses.MultiDevicesResponse
expectedTotalCount uint32
}{
{
name: "query the commands",
multiDevicesResponse: responses.MultiDevicesResponse{
BaseWithTotalCountResponse: dtosCommon.BaseWithTotalCountResponse{TotalCount: 2},
Devices: []dtos.Device{device1, device2},
},
expectedTotalCount: 2,
},
{
name: "device has empty profile",
multiDevicesResponse: responses.MultiDevicesResponse{
BaseWithTotalCountResponse: dtosCommon.BaseWithTotalCountResponse{TotalCount: 2},
Devices: []dtos.Device{device1, device3},
},
expectedTotalCount: 2,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var labels []string
dc.On("AllDevices", ctx, labels, 0, 0).Return(tt.multiDevicesResponse, nil).Once()
_, count, err := AllCommands(0, 0, dic)
require.NoError(t, err)
assert.Equal(t, tt.expectedTotalCount, count)
})
}
}
8 changes: 6 additions & 2 deletions internal/core/command/controller/messaging/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ func SubscribeCommandRequests(ctx context.Context, requestTimeout time.Duration,
case err = <-messageErrors:
lc.Error(err.Error())
case requestEnvelope := <-messages:
processDeviceCommandRequest(messageBus, requestEnvelope, baseTopic, requestTimeout, lc, dic)
go func() {
processDeviceCommandRequest(messageBus, requestEnvelope, baseTopic, requestTimeout, lc, dic)
}()
}
}
}()
Expand Down Expand Up @@ -211,7 +213,9 @@ func SubscribeCommandQueryRequests(ctx context.Context, dic *di.Container) error
case err = <-messageErrors:
lc.Error(err.Error())
case requestEnvelope := <-messages:
processCommandQueryRequest(messageBus, requestEnvelope, baseTopic, lc, dic)
go func() {
processCommandQueryRequest(messageBus, requestEnvelope, baseTopic, lc, dic)
}()
}
}
}()
Expand Down
56 changes: 34 additions & 22 deletions internal/core/data/application/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ func (a *CoreDataApp) DeleteEventsByDeviceName(deviceName string, dic *di.Contai
// AllEvents query events by offset and limit
func (a *CoreDataApp) AllEvents(offset int, limit int, dic *di.Container) (events []dtos.Event, totalCount uint32, err errors.EdgeX) {
dbClient := container.DBClientFrom(dic.Get)
totalCount, err = dbClient.EventTotalCount()
if err != nil {
return events, totalCount, errors.NewCommonEdgeXWrapper(err)
}
cont, err := utils.CheckCountRange(totalCount, offset, limit)
if !cont {
return []dtos.Event{}, totalCount, err
}

eventModels, err := dbClient.AllEvents(offset, limit)
if err != nil {
Expand All @@ -207,6 +199,18 @@ func (a *CoreDataApp) AllEvents(offset int, limit int, dic *di.Container) (event
for i, e := range eventModels {
events[i] = dtos.FromEventModelToDTO(e)
}
if offset < 0 {
return events, 0, err // skip total count
}

totalCount, err = dbClient.EventTotalCount()
if err != nil {
return events, totalCount, errors.NewCommonEdgeXWrapper(err)
}
cont, err := utils.CheckCountRange(totalCount, offset, limit)
if !cont {
return []dtos.Event{}, totalCount, err
}
return events, totalCount, nil
}

Expand All @@ -216,14 +220,6 @@ func (a *CoreDataApp) EventsByDeviceName(offset int, limit int, name string, dic
return events, totalCount, errors.NewCommonEdgeX(errors.KindContractInvalid, "name is empty", nil)
}
dbClient := container.DBClientFrom(dic.Get)
totalCount, err = dbClient.EventCountByDeviceName(name)
if err != nil {
return events, totalCount, errors.NewCommonEdgeXWrapper(err)
}
cont, err := utils.CheckCountRange(totalCount, offset, limit)
if !cont {
return []dtos.Event{}, totalCount, err
}

eventModels, err := dbClient.EventsByDeviceName(offset, limit, name)
if err != nil {
Expand All @@ -233,20 +229,24 @@ func (a *CoreDataApp) EventsByDeviceName(offset int, limit int, name string, dic
for i, e := range eventModels {
events[i] = dtos.FromEventModelToDTO(e)
}
return events, totalCount, nil
}
if offset < 0 {
return events, 0, err // skip total count
}

// EventsByTimeRange query events with offset, limit and time range
func (a *CoreDataApp) EventsByTimeRange(startTime int64, endTime int64, offset int, limit int, dic *di.Container) (events []dtos.Event, totalCount uint32, err errors.EdgeX) {
dbClient := container.DBClientFrom(dic.Get)
totalCount, err = dbClient.EventCountByTimeRange(startTime, endTime)
totalCount, err = dbClient.EventCountByDeviceName(name)
if err != nil {
return events, totalCount, errors.NewCommonEdgeXWrapper(err)
}
cont, err := utils.CheckCountRange(totalCount, offset, limit)
if !cont {
return []dtos.Event{}, totalCount, err
}
return events, totalCount, nil
}

// EventsByTimeRange query events with offset, limit and time range
func (a *CoreDataApp) EventsByTimeRange(startTime int64, endTime int64, offset int, limit int, dic *di.Container) (events []dtos.Event, totalCount uint32, err errors.EdgeX) {
dbClient := container.DBClientFrom(dic.Get)

eventModels, err := dbClient.EventsByTimeRange(startTime, endTime, offset, limit)
if err != nil {
Expand All @@ -256,6 +256,18 @@ func (a *CoreDataApp) EventsByTimeRange(startTime int64, endTime int64, offset i
for i, e := range eventModels {
events[i] = dtos.FromEventModelToDTO(e)
}
if offset < 0 {
return events, 0, err // skip total count
}

totalCount, err = dbClient.EventCountByTimeRange(startTime, endTime)
if err != nil {
return events, totalCount, errors.NewCommonEdgeXWrapper(err)
}
cont, err := utils.CheckCountRange(totalCount, offset, limit)
if !cont {
return []dtos.Event{}, totalCount, err
}
return events, totalCount, nil
}

Expand Down
Loading