Skip to content

Commit b14a57b

Browse files
committed
ns: Remove MAC settings profile reference on batch end device delete
1 parent 4d2a9e9 commit b14a57b

6 files changed

Lines changed: 160 additions & 5 deletions

File tree

pkg/networkserver/grpc_deviceregistry.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,27 @@ func (srv *nsEndDeviceBatchRegistry) Delete(
16661666
); err != nil {
16671667
return nil, err
16681668
}
1669-
deleted, err := srv.devices.BatchDelete(ctx, req.ApplicationIds, req.DeviceIds)
1669+
deleted, err := srv.devices.BatchDelete(ctx, req.ApplicationIds, req.DeviceIds, func(dev *ttnpb.EndDevice) error {
1670+
if dev == nil {
1671+
return errDeviceNotFound.New()
1672+
}
1673+
if dev.MacSettingsProfileIds != nil {
1674+
_, err := srv.macSettingsProfiles.Set(
1675+
ctx,
1676+
dev.MacSettingsProfileIds,
1677+
[]string{"ids", "mac_settings", "end_devices_count"},
1678+
func(_ context.Context, existing *ttnpb.MACSettingsProfile) (*ttnpb.MACSettingsProfile, []string, error) {
1679+
if existing.EndDevicesCount > 0 {
1680+
existing.EndDevicesCount--
1681+
}
1682+
return existing, []string{"ids", "mac_settings", "end_devices_count"}, nil
1683+
})
1684+
if err != nil {
1685+
return err
1686+
}
1687+
}
1688+
return nil
1689+
})
16701690
if err != nil {
16711691
logRegistryRPCError(ctx, err, "Failed to delete device from registry")
16721692
return nil, err

pkg/networkserver/grpc_deviceregistry_test.go

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,12 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
15961596
KekLabel: "test",
15971597
},
15981598
},
1599+
MacSettingsProfileIds: &ttnpb.MACSettingsProfileIdentifiers{
1600+
ProfileId: "test-mac-settings-profile-id",
1601+
ApplicationIds: &ttnpb.ApplicationIdentifiers{
1602+
ApplicationId: registeredApplicationID,
1603+
},
1604+
},
15991605
}
16001606
dev2 := ttnpb.Clone(dev1)
16011607
dev2.Ids.DeviceId = "test-device-2"
@@ -1614,10 +1620,18 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
16141620
ctx context.Context,
16151621
appIDs *ttnpb.ApplicationIdentifiers,
16161622
deviceIDs []string,
1623+
callback func(dev *ttnpb.EndDevice) error,
16171624
) ([]*ttnpb.EndDeviceIdentifiers, error)
1625+
SetFunc func(
1626+
context.Context,
1627+
*ttnpb.MACSettingsProfileIdentifiers,
1628+
[]string,
1629+
func(context.Context, *ttnpb.MACSettingsProfile) (*ttnpb.MACSettingsProfile, []string, error),
1630+
) (*ttnpb.MACSettingsProfile, error)
16181631
Request *ttnpb.BatchDeleteEndDevicesRequest
16191632
ErrorAssertion func(*testing.T, error) bool
16201633
BatchDeleteCalls uint64
1634+
SetCalls uint64
16211635
}{
16221636
{
16231637
Name: "No device write rights",
@@ -1636,6 +1650,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
16361650
ctx context.Context,
16371651
appIDs *ttnpb.ApplicationIdentifiers,
16381652
deviceIDs []string,
1653+
_ func(dev *ttnpb.EndDevice) error,
16391654
) ([]*ttnpb.EndDeviceIdentifiers, error) {
16401655
err := errors.New("BatchDeleteFunc must not be called")
16411656
test.MustTFromContext(ctx).Error(err)
@@ -1675,6 +1690,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
16751690
BatchDeleteFunc: func(ctx context.Context,
16761691
appIDs *ttnpb.ApplicationIdentifiers,
16771692
deviceIDs []string,
1693+
_ func(dev *ttnpb.EndDevice) error,
16781694
) ([]*ttnpb.EndDeviceIdentifiers, error) {
16791695
// Devices not found are skipped.
16801696
return nil, nil
@@ -1714,6 +1730,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
17141730
ctx context.Context,
17151731
appIDs *ttnpb.ApplicationIdentifiers,
17161732
deviceIDs []string,
1733+
_ func(dev *ttnpb.EndDevice) error,
17171734
) ([]*ttnpb.EndDeviceIdentifiers, error) {
17181735
err := errors.New("BatchDeleteFunc must not be called")
17191736
test.MustTFromContext(ctx).Error(err)
@@ -1752,6 +1769,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
17521769
ctx context.Context,
17531770
appIDs *ttnpb.ApplicationIdentifiers,
17541771
deviceIDs []string,
1772+
_ func(dev *ttnpb.EndDevice) error,
17551773
) ([]*ttnpb.EndDeviceIdentifiers, error) {
17561774
err := errors.New("BatchDeleteFunc must not be called")
17571775
test.MustTFromContext(ctx).Error(err)
@@ -1784,6 +1802,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
17841802
ctx context.Context,
17851803
appIDs *ttnpb.ApplicationIdentifiers,
17861804
deviceIDs []string,
1805+
_ func(dev *ttnpb.EndDevice) error,
17871806
) ([]*ttnpb.EndDeviceIdentifiers, error) {
17881807
a := assertions.New(test.MustTFromContext(ctx))
17891808
a.So(deviceIDs, should.HaveLength, 1)
@@ -1818,6 +1837,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
18181837
ctx context.Context,
18191838
appIDs *ttnpb.ApplicationIdentifiers,
18201839
deviceIDs []string,
1840+
_ func(dev *ttnpb.EndDevice) error,
18211841
) ([]*ttnpb.EndDeviceIdentifiers, error) {
18221842
a := assertions.New(test.MustTFromContext(ctx))
18231843
a.So(deviceIDs, should.HaveLength, 3)
@@ -1866,6 +1886,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
18661886
ctx context.Context,
18671887
appIDs *ttnpb.ApplicationIdentifiers,
18681888
deviceIDs []string,
1889+
_ func(dev *ttnpb.EndDevice) error,
18691890
) ([]*ttnpb.EndDeviceIdentifiers, error) {
18701891
a := assertions.New(test.MustTFromContext(ctx))
18711892
a.So(appIDs, should.Resemble, registeredApplicationIDs)
@@ -1896,14 +1917,100 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
18961917
},
18971918
BatchDeleteCalls: 1,
18981919
},
1920+
{
1921+
Name: "Valid Batch with MAC settings profile",
1922+
ContextFunc: func(ctx context.Context) context.Context {
1923+
return rights.NewContext(ctx, &rights.Rights{
1924+
ApplicationRights: *rights.NewMap(map[string]*ttnpb.Rights{
1925+
unique.ID(test.Context(), registeredApplicationIDs): {
1926+
Rights: []ttnpb.Right{
1927+
ttnpb.Right_RIGHT_APPLICATION_DEVICES_WRITE,
1928+
},
1929+
},
1930+
}),
1931+
})
1932+
},
1933+
BatchDeleteFunc: func(
1934+
ctx context.Context,
1935+
appIDs *ttnpb.ApplicationIdentifiers,
1936+
deviceIDs []string,
1937+
callback func(dev *ttnpb.EndDevice) error,
1938+
) ([]*ttnpb.EndDeviceIdentifiers, error) {
1939+
a := assertions.New(test.MustTFromContext(ctx))
1940+
a.So(appIDs, should.Resemble, registeredApplicationIDs)
1941+
a.So(deviceIDs, should.HaveLength, 3)
1942+
for _, devID := range deviceIDs {
1943+
switch devID {
1944+
case dev1.GetIds().DeviceId:
1945+
err := callback(dev1)
1946+
a.So(err, should.BeNil)
1947+
case dev2.GetIds().DeviceId:
1948+
err := callback(dev2)
1949+
a.So(err, should.BeNil)
1950+
case dev3.GetIds().DeviceId:
1951+
err := callback(dev3)
1952+
a.So(err, should.BeNil)
1953+
default:
1954+
t.Error("Unknown device ID: ", devID)
1955+
}
1956+
}
1957+
return []*ttnpb.EndDeviceIdentifiers{
1958+
dev1.Ids,
1959+
dev2.Ids,
1960+
dev3.Ids,
1961+
}, nil
1962+
},
1963+
SetFunc: func(
1964+
ctx context.Context,
1965+
ids *ttnpb.MACSettingsProfileIdentifiers,
1966+
paths []string,
1967+
f func(context.Context, *ttnpb.MACSettingsProfile) (*ttnpb.MACSettingsProfile, []string, error),
1968+
) (*ttnpb.MACSettingsProfile, error) {
1969+
a := assertions.New(test.MustTFromContext(ctx))
1970+
a.So(ids, should.Resemble, &ttnpb.MACSettingsProfileIdentifiers{
1971+
ProfileId: "test-mac-settings-profile-id",
1972+
ApplicationIds: &ttnpb.ApplicationIdentifiers{ApplicationId: registeredApplicationID},
1973+
})
1974+
a.So(paths, should.Equal, []string{"ids", "mac_settings", "end_devices_count"})
1975+
profile, sets, err := f(ctx, &ttnpb.MACSettingsProfile{
1976+
Ids: &ttnpb.MACSettingsProfileIdentifiers{
1977+
ProfileId: "test-mac-settings-profile-id",
1978+
ApplicationIds: &ttnpb.ApplicationIdentifiers{ApplicationId: registeredApplicationID},
1979+
},
1980+
EndDevicesCount: 1,
1981+
})
1982+
if !a.So(err, should.BeNil) {
1983+
return nil, err
1984+
}
1985+
a.So(sets, should.Equal, []string{"ids", "mac_settings", "end_devices_count"})
1986+
a.So(profile, should.Resemble, &ttnpb.MACSettingsProfile{
1987+
Ids: &ttnpb.MACSettingsProfileIdentifiers{
1988+
ProfileId: "test-mac-settings-profile-id",
1989+
ApplicationIds: &ttnpb.ApplicationIdentifiers{ApplicationId: registeredApplicationID},
1990+
},
1991+
EndDevicesCount: 0,
1992+
})
1993+
return profile, nil
1994+
},
1995+
Request: &ttnpb.BatchDeleteEndDevicesRequest{
1996+
ApplicationIds: registeredApplicationIDs,
1997+
DeviceIds: []string{
1998+
dev1.Ids.DeviceId,
1999+
dev2.Ids.DeviceId,
2000+
dev3.Ids.DeviceId,
2001+
},
2002+
},
2003+
BatchDeleteCalls: 1,
2004+
SetCalls: 3,
2005+
},
18992006
} {
19002007
tc := tc
19012008
test.RunSubtest(t, test.SubtestConfig{
19022009
Name: tc.Name,
19032010
Parallel: true,
19042011
Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
19052012
t.Helper()
1906-
var batchDeleteCalls uint64
2013+
var batchDeleteCalls, setCalls uint64
19072014
ns, ctx, env, stop := StartTest(
19082015
ctx,
19092016
TestConfig{
@@ -1913,9 +2020,21 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
19132020
ctx context.Context,
19142021
appIDs *ttnpb.ApplicationIdentifiers,
19152022
deviceIDs []string,
2023+
callback func(dev *ttnpb.EndDevice) error,
19162024
) ([]*ttnpb.EndDeviceIdentifiers, error) {
19172025
atomic.AddUint64(&batchDeleteCalls, 1)
1918-
return tc.BatchDeleteFunc(ctx, appIDs, deviceIDs)
2026+
return tc.BatchDeleteFunc(ctx, appIDs, deviceIDs, callback)
2027+
},
2028+
},
2029+
MACSettingsProfileRegistry: &MockMACSettingsProfileRegistry{
2030+
SetFunc: func(
2031+
ctx context.Context,
2032+
ids *ttnpb.MACSettingsProfileIdentifiers,
2033+
paths []string,
2034+
f func(context.Context, *ttnpb.MACSettingsProfile) (*ttnpb.MACSettingsProfile, []string, error),
2035+
) (*ttnpb.MACSettingsProfile, error) {
2036+
atomic.AddUint64(&setCalls, 1)
2037+
return tc.SetFunc(ctx, ids, paths, f)
19192038
},
19202039
},
19212040
},
@@ -1939,6 +2058,7 @@ func TestDeviceRegistryBatchDelete(t *testing.T) { // nolint:paralleltest
19392058

19402059
_, err := ttnpb.NewNsEndDeviceBatchRegistryClient(ns.LoopbackConn()).Delete(ctx, req)
19412060
a.So(batchDeleteCalls, should.Equal, tc.BatchDeleteCalls)
2061+
a.So(setCalls, should.Equal, tc.SetCalls)
19422062
if tc.ErrorAssertion != nil {
19432063
a.So(tc.ErrorAssertion(t, err), should.BeTrue)
19442064
} else {

pkg/networkserver/internal/test/shared/device_registry.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,11 @@ func handleDeviceRegistryTest(ctx context.Context, reg DeviceRegistry) {
500500
// This unknown device will be ignored.
501501
"test-dev-4",
502502
},
503+
func(stored *ttnpb.EndDevice) error {
504+
a.So(stored, should.NotBeNil)
505+
a.So(stored.MacSettingsProfileIds, should.Resemble, macSettingsProfileID)
506+
return nil
507+
},
503508
)
504509
if !a.So(err, should.BeNil) {
505510
t.Fatalf("BatchDelete failed with: %s", errors.Stack(err))

pkg/networkserver/networkserver_util_internal_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2547,6 +2547,7 @@ type MockDeviceRegistry struct {
25472547
ctx context.Context,
25482548
appIDs *ttnpb.ApplicationIdentifiers,
25492549
deviceIDs []string,
2550+
callback func(dev *ttnpb.EndDevice) error,
25502551
) ([]*ttnpb.EndDeviceIdentifiers, error)
25512552
BatchSetByIDFunc func(
25522553
ctx context.Context,
@@ -2603,11 +2604,12 @@ func (m MockDeviceRegistry) BatchDelete(
26032604
ctx context.Context,
26042605
appIDs *ttnpb.ApplicationIdentifiers,
26052606
deviceIDs []string,
2607+
callback func(dev *ttnpb.EndDevice) error,
26062608
) ([]*ttnpb.EndDeviceIdentifiers, error) {
26072609
if m.BatchDeleteFunc == nil {
26082610
panic("BatchDeleteFunc called, but not set")
26092611
}
2610-
return m.BatchDeleteFunc(ctx, appIDs, deviceIDs)
2612+
return m.BatchDeleteFunc(ctx, appIDs, deviceIDs, callback)
26112613
}
26122614

26132615
// BatchSetByID calls BatchSetByIDFunc if set and panics otherwise.

pkg/networkserver/redis/registry.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ func (r *DeviceRegistry) BatchDelete(
10501050
ctx context.Context,
10511051
appIDs *ttnpb.ApplicationIdentifiers,
10521052
deviceIDs []string,
1053+
callback func(dev *ttnpb.EndDevice) error,
10531054
) ([]*ttnpb.EndDeviceIdentifiers, error) {
10541055
var (
10551056
uidKeys = make([]string, 0, len(deviceIDs))
@@ -1089,6 +1090,11 @@ func (r *DeviceRegistry) BatchDelete(
10891090
log.FromContext(ctx).WithError(err).Warn("Failed to decode stored end device")
10901091
continue
10911092
}
1093+
if callback != nil {
1094+
if err := callback(dev); err != nil {
1095+
return err
1096+
}
1097+
}
10921098
ret = append(ret, dev.Ids)
10931099
uid := unique.ID(ctx, dev.GetIds())
10941100
if dev.Ids.JoinEui != nil && dev.Ids.DevEui != nil {

pkg/networkserver/registry.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type DeviceRegistry interface {
5050
ctx context.Context,
5151
appIDs *ttnpb.ApplicationIdentifiers,
5252
deviceIDs []string,
53+
callback func(dev *ttnpb.EndDevice) error,
5354
) ([]*ttnpb.EndDeviceIdentifiers, error)
5455
BatchSetByID(
5556
ctx context.Context,
@@ -154,8 +155,9 @@ func (w replacedEndDeviceFieldRegistryWrapper) BatchDelete(
154155
ctx context.Context,
155156
appIDs *ttnpb.ApplicationIdentifiers,
156157
deviceIDs []string,
158+
callback func(dev *ttnpb.EndDevice) error,
157159
) ([]*ttnpb.EndDeviceIdentifiers, error) {
158-
return w.DeviceRegistry.BatchDelete(ctx, appIDs, deviceIDs)
160+
return w.DeviceRegistry.BatchDelete(ctx, appIDs, deviceIDs, callback)
159161
}
160162

161163
func (w replacedEndDeviceFieldRegistryWrapper) Range(ctx context.Context, paths []string, f func(context.Context, *ttnpb.EndDeviceIdentifiers, *ttnpb.EndDevice) bool) error {

0 commit comments

Comments
 (0)