blob: c1648265045fed247fb8c7b3d8a24dbd2db0361a [file] [log] [blame]
Kent Hagerman2b216042020-04-03 18:28:56 -04001/*
2 * Copyright 2020-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package adapter
18
19import (
Rohan Agrawal31f21802020-06-12 05:38:46 +000020 "context"
khenaidood948f772021-08-11 17:49:24 -040021 "errors"
Kent Hagerman2b216042020-04-03 18:28:56 -040022 "sync"
23 "time"
khenaidood948f772021-08-11 17:49:24 -040024
25 "github.com/golang/protobuf/ptypes/empty"
26 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
27 "github.com/opencord/voltha-lib-go/v7/pkg/log"
khenaidoo9beaaf12021-10-19 17:32:01 -040028 "github.com/opencord/voltha-protos/v5/go/adapter_service"
29 "github.com/opencord/voltha-protos/v5/go/health"
khenaidood948f772021-08-11 17:49:24 -040030 "github.com/opencord/voltha-protos/v5/go/voltha"
31 "google.golang.org/grpc"
Kent Hagerman2b216042020-04-03 18:28:56 -040032)
33
34// agent represents adapter agent
35type agent struct {
khenaidood948f772021-08-11 17:49:24 -040036 adapter *voltha.Adapter
37 lock sync.RWMutex
38 adapterAPIEndPoint string
39 vClient *vgrpc.Client
40 adapterLock sync.RWMutex
41 onAdapterRestart vgrpc.RestartedHandler
42 liveProbeInterval time.Duration
Kent Hagerman2b216042020-04-03 18:28:56 -040043}
44
khenaidood948f772021-08-11 17:49:24 -040045func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
khenaidoo9beaaf12021-10-19 17:32:01 -040046 svc := adapter_service.NewAdapterServiceClient(conn)
47 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != health.HealthStatus_HEALTHY {
khenaidood948f772021-08-11 17:49:24 -040048 logger.Debugw(ctx, "connection-not-ready", log.Fields{"error": err, "health": h})
49 return nil
50 }
51 return svc
52}
53
54func newAdapterAgent(adapter *voltha.Adapter, onAdapterRestart vgrpc.RestartedHandler, liveProbeInterval time.Duration) *agent {
Kent Hagerman2b216042020-04-03 18:28:56 -040055 return &agent{
khenaidood948f772021-08-11 17:49:24 -040056 adapter: adapter,
57 onAdapterRestart: onAdapterRestart,
58 adapterAPIEndPoint: adapter.Endpoint,
59 liveProbeInterval: liveProbeInterval,
60 }
61}
62
63func (aa *agent) start(ctx context.Context) error {
64 // Establish grpc connection to Core
65 var err error
66 if aa.vClient, err = vgrpc.NewClient(aa.adapterAPIEndPoint,
67 aa.onAdapterRestart,
68 vgrpc.ActivityCheck(true)); err != nil {
69 return err
70 }
71
72 // Add a liveness communication update
73 aa.vClient.SubscribeForLiveness(aa.updateCommunicationTime)
74
75 go aa.vClient.Start(ctx, setAndTestAdapterServiceHandler)
76 return nil
77}
78
79func (aa *agent) stop(ctx context.Context) {
80 // Close the client
81 if aa.vClient != nil {
82 aa.vClient.Stop(ctx)
Kent Hagerman2b216042020-04-03 18:28:56 -040083 }
84}
85
Rohan Agrawal31f21802020-06-12 05:38:46 +000086func (aa *agent) getAdapter(ctx context.Context) *voltha.Adapter {
khenaidood948f772021-08-11 17:49:24 -040087 aa.adapterLock.RLock()
88 defer aa.adapterLock.RUnlock()
Kent Hagerman2b216042020-04-03 18:28:56 -040089 return aa.adapter
90}
91
khenaidoo9beaaf12021-10-19 17:32:01 -040092func (aa *agent) getClient() (adapter_service.AdapterServiceClient, error) {
khenaidood948f772021-08-11 17:49:24 -040093 client, err := aa.vClient.GetClient()
94 if err != nil {
95 return nil, err
96 }
khenaidoo9beaaf12021-10-19 17:32:01 -040097 c, ok := client.(adapter_service.AdapterServiceClient)
khenaidood948f772021-08-11 17:49:24 -040098 if ok {
99 return c, nil
100 }
101 return nil, errors.New("invalid client returned")
102}
103
104func (aa *agent) resetConnection(ctx context.Context) {
105 if aa.vClient != nil {
106 aa.vClient.Reset(ctx)
107 }
108}
109
Kent Hagerman2b216042020-04-03 18:28:56 -0400110// updateCommunicationTime updates the message to the specified time.
111// No attempt is made to save the time to the db, so only recent times are guaranteed to be accurate.
112func (aa *agent) updateCommunicationTime(new time.Time) {
113 // only update if new time is not in the future, and either the old time is invalid or new time > old time
David K. Bainbridge5809b5b2020-08-27 00:07:41 +0000114 aa.lock.Lock()
115 defer aa.lock.Unlock()
khenaidood948f772021-08-11 17:49:24 -0400116 timestamp := time.Unix(aa.adapter.LastCommunication, 0)
117 if !new.After(time.Now()) && new.After(timestamp) {
118 timestamp = new
119 aa.adapter.LastCommunication = timestamp.Unix()
Kent Hagerman2b216042020-04-03 18:28:56 -0400120 }
121}
khenaidood948f772021-08-11 17:49:24 -0400122
123func (aa *agent) IsConnectionUp() bool {
124 _, err := aa.getClient()
125 return err == nil
126}