Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prioritize gateway's field contacts over Contact Info list #6430

Merged
merged 8 commits into from
Sep 6, 2023
2 changes: 2 additions & 0 deletions pkg/gatewayserver/gatewayserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ func (gs *GatewayServer) Connect(
gtw, err := gs.entityRegistry.Get(ctx, &ttnpb.GetGatewayRequest{
GatewayIds: ids,
FieldMask: ttnpb.FieldMask(
"administrative_contact",
"antennas",
"attributes",
"disable_packet_broker_forwarding",
Expand All @@ -486,6 +487,7 @@ func (gs *GatewayServer) Connect(
"schedule_anytime_delay",
"schedule_downlink_late",
"status_public",
"technical_contact",
"update_location_from_status",
),
})
Expand Down
28 changes: 13 additions & 15 deletions pkg/gatewayserver/upstream/packetbroker/packetbroker.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ func (h *Handler) ConnectGateway(ctx context.Context, ids *ttnpb.GatewayIdentifi

gtw := conn.Gateway()
antennas := make([]*ttnpb.GatewayAntenna, len(gtw.Antennas))
for i, ant := range gtw.Antennas {
antennas[i] = ant
}
copy(antennas, gtw.Antennas)

pbIDs := &ttnpb.PacketBrokerGateway_GatewayIdentifiers{
GatewayId: ids.GatewayId,
Expand All @@ -118,26 +116,26 @@ func (h *Handler) ConnectGateway(ctx context.Context, ids *ttnpb.GatewayIdentifi

req := &ttnpb.UpdatePacketBrokerGatewayRequest{
Gateway: &ttnpb.PacketBrokerGateway{
Ids: pbIDs,
Antennas: antennas,
FrequencyPlanIds: gtw.FrequencyPlanIds,
StatusPublic: gtw.StatusPublic,
LocationPublic: gtw.LocationPublic,
Online: true,
RxRate: &wrapperspb.FloatValue{
Value: 0,
},
TxRate: &wrapperspb.FloatValue{
Value: 0,
},
Ids: pbIDs,
Antennas: antennas,
FrequencyPlanIds: gtw.FrequencyPlanIds,
StatusPublic: gtw.StatusPublic,
LocationPublic: gtw.LocationPublic,
AdministrativeContact: gtw.AdministrativeContact,
adriansmares marked this conversation as resolved.
Show resolved Hide resolved
TechnicalContact: gtw.TechnicalContact,
Online: true,
RxRate: &wrapperspb.FloatValue{Value: 0},
TxRate: &wrapperspb.FloatValue{Value: 0},
},
FieldMask: ttnpb.FieldMask(
"administrative_contact",
"antennas",
"frequency_plan_ids",
"location_public",
"online",
"rx_rate",
"status_public",
"technical_contact",
"tx_rate",
),
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/identityserver/mock/application_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ type mockISApplicationRegistry struct {
mu sync.Mutex
}

func newApplicationRegistry() *mockISApplicationRegistry {
return &mockISApplicationRegistry{
applications: make(map[string]*ttnpb.Application),
applicationAuths: make(map[string][]string),
applicationRights: make(map[string]authKeyToRights),
}
}

func (is *mockISApplicationRegistry) Add(
ctx context.Context,
ids *ttnpb.ApplicationIdentifiers,
Expand Down
8 changes: 8 additions & 0 deletions pkg/identityserver/mock/device_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type mockISEndDeviceRegistry struct {
endDevices sync.Map
}

func newEndDeviceRegitry() *mockISEndDeviceRegistry {
return &mockISEndDeviceRegistry{}
}

func (m *mockISEndDeviceRegistry) Add(ctx context.Context, dev *ttnpb.EndDevice) {
m.endDevices.Store(unique.ID(ctx, dev.Ids), dev)
}
Expand Down Expand Up @@ -70,6 +74,10 @@ type isEndDeviceBatchRegistry struct {
reg *mockISEndDeviceRegistry
}

func newEndDeviceBatchRegitry(devReg *mockISEndDeviceRegistry) *isEndDeviceBatchRegistry {
return &isEndDeviceBatchRegistry{reg: devReg}
}

// Get implements ttnpb.EndDeviceBatchRegistryServer.
func (m *isEndDeviceBatchRegistry) Get(
ctx context.Context,
Expand Down
4 changes: 4 additions & 0 deletions pkg/identityserver/mock/entity_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ type mockEntityAccess struct {
err error
}

func newEntityAccess() *mockEntityAccess {
return &mockEntityAccess{}
}

func (ea *mockEntityAccess) AuthInfo(context.Context, *emptypb.Empty) (*ttnpb.AuthInfoResponse, error) {
if ea.err != nil {
return &ttnpb.AuthInfoResponse{}, ea.err
Expand Down
8 changes: 8 additions & 0 deletions pkg/identityserver/mock/gateway_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ type mockISGatewayRegistry struct {
mu sync.Mutex
}

func newGatewayRegistry() *mockISGatewayRegistry {
return &mockISGatewayRegistry{
gateways: make(map[string]*ttnpb.Gateway),
gatewayAuths: make(map[string][]string),
gatewayRights: make(map[string]authKeyToRights),
}
}

func (is *mockISGatewayRegistry) SetRegisteredGateway(gtwIDs *ttnpb.GatewayIdentifiers) {
is.mu.Lock()
defer is.mu.Unlock()
Expand Down
71 changes: 41 additions & 30 deletions pkg/identityserver/mock/mock.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.

Check warning on line 1 in pkg/identityserver/mock/mock.go

View workflow job for this annotation

GitHub Actions / Check Mergeability

pkg/identityserver/mock/mock.go has a conflict when merging TheThingsIndustries/lorawan-stack:v3.27.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,83 +29,94 @@
type authKeyToRights map[string][]ttnpb.Right

// MockDefinition contains the structure that is returned by the New(ctx) method of the package, might be used to
// specify IS mock in test cases definitons.
// specify IS mock in test cases definitions.
type MockDefinition struct {
applicationRegistry *mockISApplicationRegistry
gatewayRegistry *mockISGatewayRegistry
endDeviceRegistry *mockISEndDeviceRegistry
endDeviceBatchRegistry *isEndDeviceBatchRegistry
entityAccess *mockEntityAccess
gatewayRegistry *mockISGatewayRegistry
organizationRegistry *mockISOrganizationRegistry
userRegistry *mockISUserRegistry
}

type closeMock func()

// New returns a identityserver mock along side its address and closing function.
func New(ctx context.Context) (*MockDefinition, string, closeMock) {
endDeviceRegistry := &mockISEndDeviceRegistry{}
// New returns an Identity Server mock along side its address and closing function.
func New(ctx context.Context) (*MockDefinition, string, closeMock) { // nolint:revive
endDeviceRegistry := newEndDeviceRegitry()

is := &MockDefinition{
applicationRegistry: &mockISApplicationRegistry{
applications: make(map[string]*ttnpb.Application),
applicationAuths: make(map[string][]string),
applicationRights: make(map[string]authKeyToRights),
},
gatewayRegistry: &mockISGatewayRegistry{
gateways: make(map[string]*ttnpb.Gateway),
gatewayAuths: make(map[string][]string),
gatewayRights: make(map[string]authKeyToRights),
},
endDeviceRegistry: endDeviceRegistry,
endDeviceBatchRegistry: &isEndDeviceBatchRegistry{
reg: endDeviceRegistry,
},
entityAccess: &mockEntityAccess{},
applicationRegistry: newApplicationRegistry(),
endDeviceRegistry: endDeviceRegistry,
endDeviceBatchRegistry: newEndDeviceBatchRegitry(endDeviceRegistry),
entityAccess: newEntityAccess(),
gatewayRegistry: newGatewayRegistry(),
organizationRegistry: newOrganizationRegistry(),
userRegistry: newUserRegistry(),
}

srv := rpcserver.New(ctx)

ttnpb.RegisterApplicationRegistryServer(srv.Server, is.applicationRegistry)
ttnpb.RegisterApplicationAccessServer(srv.Server, is.applicationRegistry)

ttnpb.RegisterGatewayRegistryServer(srv.Server, is.gatewayRegistry)
ttnpb.RegisterGatewayAccessServer(srv.Server, is.gatewayRegistry)

ttnpb.RegisterEndDeviceRegistryServer(srv.Server, is.endDeviceRegistry)

ttnpb.RegisterEntityAccessServer(srv.Server, is.entityAccess)

ttnpb.RegisterGatewayRegistryServer(srv.Server, is.gatewayRegistry)
ttnpb.RegisterGatewayAccessServer(srv.Server, is.gatewayRegistry)
ttnpb.RegisterEndDeviceBatchRegistryServer(srv.Server, is.endDeviceBatchRegistry)

ttnpb.RegisterEntityAccessServer(srv.Server, is.entityAccess)
ttnpb.RegisterOrganizationRegistryServer(srv.Server, is.organizationRegistry)
ttnpb.RegisterOrganizationAccessServer(srv.Server, is.organizationRegistry)

ttnpb.RegisterUserRegistryServer(srv.Server, is.userRegistry)
ttnpb.RegisterUserAccessServer(srv.Server, is.userRegistry)

lis, err := net.Listen("tcp", "")
if err != nil {
panic(err)
}
go srv.Serve(lis) //nolint:errcheck
go srv.Serve(lis) // nolint:errcheck
return is, lis.Addr().String(), func() {
lis.Close()
srv.GracefulStop()
}
}

// EndDeviceRegistry returns the methods related to the device registry.
func (m *MockDefinition) EndDeviceRegistry() *mockISEndDeviceRegistry {
func (m *MockDefinition) EndDeviceRegistry() *mockISEndDeviceRegistry { // nolint:revive
return m.endDeviceRegistry
}

// ApplicationRegistry returns the methods related to the application registry.
func (m *MockDefinition) ApplicationRegistry() *mockISApplicationRegistry {
func (m *MockDefinition) ApplicationRegistry() *mockISApplicationRegistry { // nolint:revive
return m.applicationRegistry
}

// GatewayRegistry returns the methods related to the gateway registry.
func (m *MockDefinition) GatewayRegistry() *mockISGatewayRegistry {
func (m *MockDefinition) GatewayRegistry() *mockISGatewayRegistry { // nolint:revive
return m.gatewayRegistry
}

// EntityAccess returns the methods related to the access entity.
func (m *MockDefinition) EntityAccess() *mockEntityAccess {
func (m *MockDefinition) EntityAccess() *mockEntityAccess { // nolint:revive
return m.entityAccess
}

func (m *MockDefinition) EndDeviceBatchRegistry() *isEndDeviceBatchRegistry { //nolint:revive
// EndDeviceBatchRegistry returns the methods related to the end device batch registry.
func (m *MockDefinition) EndDeviceBatchRegistry() *isEndDeviceBatchRegistry { // nolint:revive
return m.endDeviceBatchRegistry
}

// OrganizationRegistry returns the methods related to the organization registry.
func (m *MockDefinition) OrganizationRegistry() *mockISOrganizationRegistry { // nolint:revive
return m.organizationRegistry
}

// UserRegistry returns the methods related to the user registry.
func (m *MockDefinition) UserRegistry() *mockISUserRegistry { // nolint:revive
return m.userRegistry
}
56 changes: 56 additions & 0 deletions pkg/identityserver/mock/organization_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// 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 mockis

import (
"context"
"sync"

"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
)

type mockISOrganizationRegistry struct {
ttnpb.UnimplementedOrganizationRegistryServer
ttnpb.UnimplementedOrganizationAccessServer

orgs sync.Map
}

func newOrganizationRegistry() *mockISOrganizationRegistry {
return &mockISOrganizationRegistry{}
}

func (m *mockISOrganizationRegistry) Create(
ctx context.Context, req *ttnpb.CreateOrganizationRequest,
) (*ttnpb.Organization, error) {
m.orgs.Store(unique.ID(ctx, req.Organization.Ids), req.Organization)
return req.Organization, nil
}

func (m *mockISOrganizationRegistry) Get(
ctx context.Context, req *ttnpb.GetOrganizationRequest,
) (*ttnpb.Organization, error) {
loadedOrganization, ok := m.orgs.Load(unique.ID(ctx, req.OrganizationIds))
if !ok {
return nil, errNotFound
}
org, ok := loadedOrganization.(*ttnpb.Organization)
if !ok {
panic("stored value is not of type *ttnpb.Organization")
}

return org, nil
}
52 changes: 52 additions & 0 deletions pkg/identityserver/mock/user_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// 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 mockis

import (
"context"
"sync"

"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
)

type mockISUserRegistry struct {
ttnpb.UnimplementedUserRegistryServer
ttnpb.UnimplementedUserAccessServer

users sync.Map
}

func newUserRegistry() *mockISUserRegistry {
return &mockISUserRegistry{}
}

func (m *mockISUserRegistry) Create(ctx context.Context, req *ttnpb.CreateUserRequest) (*ttnpb.User, error) {
m.users.Store(unique.ID(ctx, req.User.Ids), req.User)
return req.User, nil
}

func (m *mockISUserRegistry) Get(ctx context.Context, req *ttnpb.GetUserRequest) (*ttnpb.User, error) {
loadedUser, ok := m.users.Load(unique.ID(ctx, req.UserIds))
if !ok {
return nil, errNotFound
}
usr, ok := loadedUser.(*ttnpb.User)
if !ok {
panic("stored value is not of type *ttnpb.User")
}

return usr, nil
}
3 changes: 3 additions & 0 deletions pkg/packetbrokeragent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package packetbrokeragent contains the implementation of the Packet Broker Agent component.
package packetbrokeragent

import (
Expand Down Expand Up @@ -326,6 +327,7 @@ func New(c *component.Component, conf *Config, opts ...Option) (*Agent, error) {
if err != nil {
return nil, err
}

a.grpc.gsPba = &gsPbaServer{
netID: a.netID,
clusterID: a.clusterID,
Expand All @@ -336,6 +338,7 @@ func New(c *component.Component, conf *Config, opts ...Option) (*Agent, error) {
frequencyPlansStore: getFrequencyPlanStore,
upstreamCh: a.upstreamCh,
mapperConn: mapperConn,
entityRegistry: newIS(c),
}
} else {
a.grpc.gsPba = &disabledServer{}
Expand Down
Loading
Loading