/
grpc.go
101 lines (91 loc) · 3.64 KB
/
grpc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright © 2019 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 applicationserver
import (
"context"
"github.com/gogo/protobuf/types"
"go.thethings.network/lorawan-stack/pkg/auth/rights"
"go.thethings.network/lorawan-stack/pkg/errors"
"go.thethings.network/lorawan-stack/pkg/log"
"go.thethings.network/lorawan-stack/pkg/ttnpb"
)
// GetLink implements ttnpb.AsServer.
func (as *ApplicationServer) GetLink(ctx context.Context, req *ttnpb.GetApplicationLinkRequest) (*ttnpb.ApplicationLink, error) {
if err := rights.RequireApplication(ctx, req.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_LINK); err != nil {
return nil, err
}
return as.linkRegistry.Get(ctx, req.ApplicationIdentifiers, req.FieldMask.Paths)
}
// SetLink implements ttnpb.AsServer.
func (as *ApplicationServer) SetLink(ctx context.Context, req *ttnpb.SetApplicationLinkRequest) (*ttnpb.ApplicationLink, error) {
if err := rights.RequireApplication(ctx, req.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_LINK); err != nil {
return nil, err
}
// Get all the fields here for starting the link task.
link, err := as.linkRegistry.Set(ctx, req.ApplicationIdentifiers, ttnpb.ApplicationLinkFieldPathsTopLevel,
func(link *ttnpb.ApplicationLink) (*ttnpb.ApplicationLink, []string, error) {
return &req.ApplicationLink, req.FieldMask.Paths, nil
},
)
if err != nil {
return nil, err
}
if err := as.cancelLink(ctx, req.ApplicationIdentifiers); err != nil && !errors.IsNotFound(err) {
log.FromContext(ctx).WithError(err).Warn("Failed to cancel link")
}
as.startLinkTask(as.Context(), req.ApplicationIdentifiers)
res := &ttnpb.ApplicationLink{}
if err := res.SetFields(link, req.FieldMask.Paths...); err != nil {
return nil, err
}
return res, nil
}
// DeleteLink implements ttnpb.AsServer.
func (as *ApplicationServer) DeleteLink(ctx context.Context, ids *ttnpb.ApplicationIdentifiers) (*types.Empty, error) {
if err := rights.RequireApplication(ctx, *ids, ttnpb.RIGHT_APPLICATION_LINK); err != nil {
return nil, err
}
if err := as.cancelLink(ctx, *ids); err != nil && !errors.IsNotFound(err) {
log.FromContext(ctx).WithError(err).Warn("Failed to cancel link")
}
_, err := as.linkRegistry.Set(ctx, *ids, nil, func(link *ttnpb.ApplicationLink) (*ttnpb.ApplicationLink, []string, error) { return nil, nil, nil })
if err != nil {
return nil, err
}
return ttnpb.Empty, nil
}
// GetLinkStats implements ttnpb.AsServer.
func (as *ApplicationServer) GetLinkStats(ctx context.Context, ids *ttnpb.ApplicationIdentifiers) (*ttnpb.ApplicationLinkStats, error) {
if err := rights.RequireApplication(ctx, *ids, ttnpb.RIGHT_APPLICATION_LINK); err != nil {
return nil, err
}
link, err := as.getLink(ctx, *ids)
if err != nil {
return nil, err
}
<-link.connReady
stats := &ttnpb.ApplicationLinkStats{}
lt := link.GetLinkTime()
stats.LinkedAt = <
stats.NetworkServerAddress = link.NetworkServerAddress
if n, t, ok := link.GetUpStats(); ok {
stats.UpCount = n
stats.LastUpReceivedAt = &t
}
if n, t, ok := link.GetDownlinkStats(); ok {
stats.DownlinkCount = n
stats.LastDownlinkForwardedAt = &t
}
return stats, nil
}