Skip to content

Commit 495c4e7

Browse files
heiytorgustavosbarreto
authored andcommitted
refactor(api): replace DeviceLookup with DeviceResolve
1 parent 0b8d2f4 commit 495c4e7

File tree

7 files changed

+45
-162
lines changed

7 files changed

+45
-162
lines changed

api/services/device.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,14 @@ func (s *service) RenameDevice(ctx context.Context, uid models.UID, name, tenant
190190
// It receives a context, used to "control" the request flow and, the namespace name from a models.Namespace and a
191191
// device name from models.Device.
192192
func (s *service) LookupDevice(ctx context.Context, namespace, name string) (*models.Device, error) {
193-
device, err := s.store.DeviceLookup(ctx, namespace, name)
193+
n, err := s.store.NamespaceGetByName(ctx, namespace)
194+
if err != nil {
195+
return nil, NewErrNamespaceNotFound(namespace, err)
196+
}
197+
198+
device, err := s.store.DeviceResolve(ctx, store.DeviceHostnameResolver, name, s.store.Options().InNamespace(n.TenantID))
194199
if err != nil || device == nil {
195-
return nil, NewErrDeviceLookupNotFound(namespace, name, err)
200+
return nil, NewErrDeviceNotFound(models.UID(name), err)
196201
}
197202

198203
return device, nil

api/services/device_test.go

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,9 @@ func TestRenameDevice(t *testing.T) {
11771177
}
11781178

11791179
func TestLookupDevice(t *testing.T) {
1180-
mock := new(storemock.Store)
1180+
storeMock := new(storemock.Store)
1181+
queryOptionsMock := new(storemock.QueryOptions)
1182+
storeMock.On("Options").Return(queryOptionsMock)
11811183

11821184
ctx := context.TODO()
11831185

@@ -1194,37 +1196,60 @@ func TestLookupDevice(t *testing.T) {
11941196
expected Expected
11951197
}{
11961198
{
1197-
description: "fails when store device lookup fails",
1199+
description: "fails when namespace does not exists",
11981200
namespace: "namespace",
11991201
device: &models.Device{UID: "uid", Name: "name", TenantID: "tenant", Identity: &models.DeviceIdentity{MAC: "00:00:00:00:00:00"}, Status: "accepted"},
1200-
requiredMocks: func(device *models.Device, namespace string) {
1201-
mock.On("DeviceLookup", ctx, namespace, device.Name).Return(nil, errors.New("error", "", 0)).Once()
1202+
requiredMocks: func(_ *models.Device, namespace string) {
1203+
storeMock.
1204+
On("NamespaceGetByName", ctx, namespace).
1205+
Return(nil, errors.New("error", "", 0)).
1206+
Once()
12021207
},
12031208
expected: Expected{
12041209
nil,
1205-
NewErrDeviceLookupNotFound("namespace", "name", errors.New("error", "", 0)),
1210+
NewErrNamespaceNotFound("namespace", errors.New("error", "", 0)),
12061211
},
12071212
},
12081213
{
1209-
description: "fails when the device is not found",
1214+
description: "fails when namespace does not exists",
12101215
namespace: "namespace",
12111216
device: &models.Device{UID: "uid", Name: "name", TenantID: "tenant", Identity: &models.DeviceIdentity{MAC: "00:00:00:00:00:00"}, Status: "accepted"},
12121217
requiredMocks: func(device *models.Device, namespace string) {
1213-
mock.On("DeviceLookup", ctx, namespace, device.Name).
1214-
Return(nil, store.ErrNoDocuments).Once()
1218+
storeMock.
1219+
On("NamespaceGetByName", ctx, namespace).
1220+
Return(&models.Namespace{TenantID: "00000000-0000-0000-0000-000000000000"}, nil).
1221+
Once()
1222+
queryOptionsMock.
1223+
On("InNamespace", "00000000-0000-0000-0000-000000000000").
1224+
Return(nil).
1225+
Once()
1226+
storeMock.
1227+
On("DeviceResolve", ctx, store.DeviceHostnameResolver, "name", mock.AnythingOfType("store.QueryOption")).
1228+
Return(nil, errors.New("error", "", 0)).
1229+
Once()
12151230
},
12161231
expected: Expected{
12171232
nil,
1218-
NewErrDeviceLookupNotFound("namespace", "name", store.ErrNoDocuments),
1233+
NewErrDeviceNotFound(models.UID("name"), errors.New("error", "", 0)),
12191234
},
12201235
},
12211236
{
12221237
description: "succeeds",
12231238
namespace: "namespace",
12241239
device: &models.Device{UID: "uid", Name: "name", TenantID: "tenant", Identity: &models.DeviceIdentity{MAC: "00:00:00:00:00:00"}, Status: "accepted"},
12251240
requiredMocks: func(device *models.Device, namespace string) {
1226-
mock.On("DeviceLookup", ctx, namespace, device.Name).
1227-
Return(device, nil).Once()
1241+
storeMock.
1242+
On("NamespaceGetByName", ctx, namespace).
1243+
Return(&models.Namespace{TenantID: "00000000-0000-0000-0000-000000000000"}, nil).
1244+
Once()
1245+
queryOptionsMock.
1246+
On("InNamespace", "00000000-0000-0000-0000-000000000000").
1247+
Return(nil).
1248+
Once()
1249+
storeMock.
1250+
On("DeviceResolve", ctx, store.DeviceHostnameResolver, "name", mock.AnythingOfType("store.QueryOption")).
1251+
Return(device, nil).
1252+
Once()
12281253
},
12291254
expected: Expected{
12301255
&models.Device{UID: "uid", Name: "name", TenantID: "tenant", Identity: &models.DeviceIdentity{MAC: "00:00:00:00:00:00"}, Status: "accepted"},
@@ -1237,12 +1262,12 @@ func TestLookupDevice(t *testing.T) {
12371262
t.Run(tc.description, func(t *testing.T) {
12381263
tc.requiredMocks(tc.device, tc.namespace)
12391264

1240-
service := NewService(store.Store(mock), privateKey, publicKey, storecache.NewNullCache(), clientMock)
1265+
service := NewService(store.Store(storeMock), privateKey, publicKey, storecache.NewNullCache(), clientMock)
12411266
returnedDevice, err := service.LookupDevice(ctx, tc.namespace, tc.device.Name)
12421267
assert.Equal(t, tc.expected, Expected{returnedDevice, err})
12431268
})
12441269
}
1245-
mock.AssertExpectations(t)
1270+
storeMock.AssertExpectations(t)
12461271
}
12471272

12481273
func TestOfflineDevice(t *testing.T) {

api/services/errors.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package services
22

33
import (
44
stderrors "errors"
5-
"fmt"
65

76
"github.com/shellhub-io/shellhub/pkg/errors"
87
"github.com/shellhub-io/shellhub/pkg/models"
@@ -100,7 +99,6 @@ var (
10099
ErrDeviceNotFound = errors.New("device not found", ErrLayer, ErrCodeNotFound)
101100
ErrDeviceInvalid = errors.New("device invalid", ErrLayer, ErrCodeInvalid)
102101
ErrDeviceDuplicated = errors.New("device duplicated", ErrLayer, ErrCodeDuplicated)
103-
ErrDeviceLookupNotFound = errors.New("device lookup not found", ErrLayer, ErrCodeNotFound)
104102
ErrDeviceLimit = errors.New("device limit reached", ErrLayer, ErrCodePayment)
105103
ErrDeviceStatusInvalid = errors.New("device status invalid", ErrLayer, ErrCodeInvalid)
106104
ErrDeviceStatusAccepted = errors.New("device status accepted", ErrLayer, ErrCodeInvalid)
@@ -378,11 +376,6 @@ func NewErrDeviceDuplicated(name string, next error) error {
378376
return NewErrDuplicated(ErrDeviceDuplicated, []string{name}, next)
379377
}
380378

381-
// NewErrDeviceLookupNotFound returns an error to be used when the device lookup is not found.
382-
func NewErrDeviceLookupNotFound(namespace, name string, next error) error {
383-
return NewErrNotFound(ErrDeviceLookupNotFound, fmt.Sprintf("device %s on namespace %s", name, namespace), next)
384-
}
385-
386379
// NewErrDeviceLimit returns an error to be used when the device limit is reached.
387380
func NewErrDeviceLimit(limit int, next error) error {
388381
return NewErrLimit(ErrDeviceLimit, limit, next)

api/store/device.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ type DeviceStore interface {
5353
DeviceDelete(ctx context.Context, uid models.UID) error
5454
DeviceCreate(ctx context.Context, d models.Device, hostname string) error
5555
DeviceRename(ctx context.Context, uid models.UID, hostname string) error
56-
DeviceLookup(ctx context.Context, namespace, hostname string) (*models.Device, error)
5756
DeviceUpdateStatus(ctx context.Context, uid models.UID, status models.DeviceStatus) error
5857
DeviceSetPosition(ctx context.Context, uid models.UID, position models.DevicePosition) error
5958
DeviceListByUsage(ctx context.Context, tenantID string) ([]models.UID, error)

api/store/mocks/store.go

Lines changed: 0 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/store/mongo/device.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -321,20 +321,6 @@ func (s *Store) DeviceRename(ctx context.Context, uid models.UID, hostname strin
321321
return nil
322322
}
323323

324-
func (s *Store) DeviceLookup(ctx context.Context, namespace, hostname string) (*models.Device, error) {
325-
ns := new(models.Namespace)
326-
if err := s.db.Collection("namespaces").FindOne(ctx, bson.M{"name": namespace}).Decode(&ns); err != nil {
327-
return nil, FromMongoError(err)
328-
}
329-
330-
device := new(models.Device)
331-
if err := s.db.Collection("devices").FindOne(ctx, bson.M{"tenant_id": ns.TenantID, "name": hostname, "status": "accepted"}).Decode(&device); err != nil {
332-
return nil, FromMongoError(err)
333-
}
334-
335-
return device, nil
336-
}
337-
338324
// DeviceUpdateStatus updates the status of a specific device in the devices collection
339325
func (s *Store) DeviceUpdateStatus(ctx context.Context, uid models.UID, status models.DeviceStatus) error {
340326
updateOptions := options.FindOneAndUpdate().SetReturnDocument(options.After)

api/store/mongo/device_test.go

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -658,101 +658,6 @@ func TestDeviceResolve(t *testing.T) {
658658
}
659659
}
660660

661-
func TestDeviceLookup(t *testing.T) {
662-
type Expected struct {
663-
dev *models.Device
664-
err error
665-
}
666-
cases := []struct {
667-
description string
668-
namespace string
669-
hostname string
670-
fixtures []string
671-
expected Expected
672-
}{
673-
{
674-
description: "fails when namespace does not exist",
675-
namespace: "nonexistent",
676-
hostname: "device-3",
677-
fixtures: []string{fixtureNamespaces, fixtureDevices},
678-
expected: Expected{
679-
dev: nil,
680-
err: store.ErrNoDocuments,
681-
},
682-
},
683-
{
684-
description: "fails when device does not exist due to name",
685-
namespace: "namespace-1",
686-
hostname: "nonexistent",
687-
fixtures: []string{fixtureNamespaces, fixtureDevices},
688-
expected: Expected{
689-
dev: nil,
690-
err: store.ErrNoDocuments,
691-
},
692-
},
693-
{
694-
description: "fails when device does not exist due to tenant-id",
695-
namespace: "namespace-1",
696-
hostname: "invalid_tenant",
697-
fixtures: []string{fixtureNamespaces, fixtureDevices},
698-
expected: Expected{
699-
dev: nil,
700-
err: store.ErrNoDocuments,
701-
},
702-
},
703-
{
704-
description: "fails when device does not exist due to status other than accepted",
705-
namespace: "namespace-1",
706-
hostname: "pending",
707-
fixtures: []string{fixtureNamespaces, fixtureDevices},
708-
expected: Expected{
709-
dev: nil,
710-
err: store.ErrNoDocuments,
711-
},
712-
},
713-
{
714-
description: "succeeds when namespace exists and hostname status is accepted",
715-
namespace: "namespace-1",
716-
hostname: "device-3",
717-
fixtures: []string{fixtureNamespaces, fixtureDevices},
718-
expected: Expected{
719-
dev: &models.Device{
720-
CreatedAt: time.Date(2023, 1, 3, 12, 0, 0, 0, time.UTC),
721-
StatusUpdatedAt: time.Date(2023, 1, 3, 12, 0, 0, 0, time.UTC),
722-
LastSeen: time.Date(2023, 1, 3, 12, 0, 0, 0, time.UTC),
723-
UID: "2300230e3ca2f637636b4d025d2235269014865db5204b6d115386cbee89809c",
724-
Name: "device-3",
725-
Identity: &models.DeviceIdentity{MAC: "mac-3"},
726-
Info: nil,
727-
PublicKey: "",
728-
TenantID: "00000000-0000-4000-0000-000000000000",
729-
Online: false,
730-
Status: "accepted",
731-
RemoteAddr: "",
732-
Position: nil,
733-
Tags: []string{"tag-1"},
734-
Acceptable: false,
735-
},
736-
err: nil,
737-
},
738-
},
739-
}
740-
741-
for _, tc := range cases {
742-
t.Run(tc.description, func(t *testing.T) {
743-
ctx := context.Background()
744-
745-
assert.NoError(t, srv.Apply(tc.fixtures...))
746-
t.Cleanup(func() {
747-
assert.NoError(t, srv.Reset())
748-
})
749-
750-
dev, err := s.DeviceLookup(ctx, tc.namespace, tc.hostname)
751-
assert.Equal(t, tc.expected, Expected{dev: dev, err: err})
752-
})
753-
}
754-
}
755-
756661
func TestDeviceCreate(t *testing.T) {
757662
cases := []struct {
758663
description string

0 commit comments

Comments
 (0)