blob: c2d45deedf74849f00b0ca48a5e319082610a0ff [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"
28 "github.com/opencord/voltha-protos/v5/go/adapter_services"
29 "github.com/opencord/voltha-protos/v5/go/voltha"
30 "google.golang.org/grpc"
Kent Hagerman2b216042020-04-03 18:28:56 -040031)
32
33// agent represents adapter agent
34type agent struct {
khenaidood948f772021-08-11 17:49:24 -040035 adapter *voltha.Adapter
36 lock sync.RWMutex
37 adapterAPIEndPoint string
38 vClient *vgrpc.Client
39 adapterLock sync.RWMutex
40 onAdapterRestart vgrpc.RestartedHandler
41 liveProbeInterval time.Duration
Kent Hagerman2b216042020-04-03 18:28:56 -040042}
43
khenaidood948f772021-08-11 17:49:24 -040044func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
45 svc := adapter_services.NewAdapterServiceClient(conn)
46 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != voltha.HealthStatus_HEALTHY {
47 logger.Debugw(ctx, "connection-not-ready", log.Fields{"error": err, "health": h})
48 return nil
49 }
50 return svc
51}
52
53func newAdapterAgent(adapter *voltha.Adapter, onAdapterRestart vgrpc.RestartedHandler, liveProbeInterval time.Duration) *agent {
Kent Hagerman2b216042020-04-03 18:28:56 -040054 return &agent{
khenaidood948f772021-08-11 17:49:24 -040055 adapter: adapter,
56 onAdapterRestart: onAdapterRestart,
57 adapterAPIEndPoint: adapter.Endpoint,
58 liveProbeInterval: liveProbeInterval,
59 }
60}
61
62func (aa *agent) start(ctx context.Context) error {
63 // Establish grpc connection to Core
64 var err error
65 if aa.vClient, err = vgrpc.NewClient(aa.adapterAPIEndPoint,
66 aa.onAdapterRestart,
67 vgrpc.ActivityCheck(true)); err != nil {
68 return err
69 }
70
71 // Add a liveness communication update
72 aa.vClient.SubscribeForLiveness(aa.updateCommunicationTime)
73
74 go aa.vClient.Start(ctx, setAndTestAdapterServiceHandler)
75 return nil
76}
77
78func (aa *agent) stop(ctx context.Context) {
79 // Close the client
80 if aa.vClient != nil {
81 aa.vClient.Stop(ctx)
Kent Hagerman2b216042020-04-03 18:28:56 -040082 }
83}
84
Rohan Agrawal31f21802020-06-12 05:38:46 +000085func (aa *agent) getAdapter(ctx context.Context) *voltha.Adapter {
khenaidood948f772021-08-11 17:49:24 -040086 aa.adapterLock.RLock()
87 defer aa.adapterLock.RUnlock()
Kent Hagerman2b216042020-04-03 18:28:56 -040088 return aa.adapter
89}
90
khenaidood948f772021-08-11 17:49:24 -040091func (aa *agent) getClient() (adapter_services.AdapterServiceClient, error) {
92 client, err := aa.vClient.GetClient()
93 if err != nil {
94 return nil, err
95 }
96 c, ok := client.(adapter_services.AdapterServiceClient)
97 if ok {
98 return c, nil
99 }
100 return nil, errors.New("invalid client returned")
101}
102
103func (aa *agent) resetConnection(ctx context.Context) {
104 if aa.vClient != nil {
105 aa.vClient.Reset(ctx)
106 }
107}
108
Kent Hagerman2b216042020-04-03 18:28:56 -0400109// updateCommunicationTime updates the message to the specified time.
110// No attempt is made to save the time to the db, so only recent times are guaranteed to be accurate.
111func (aa *agent) updateCommunicationTime(new time.Time) {
112 // 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 +0000113 aa.lock.Lock()
114 defer aa.lock.Unlock()
khenaidood948f772021-08-11 17:49:24 -0400115 timestamp := time.Unix(aa.adapter.LastCommunication, 0)
116 if !new.After(time.Now()) && new.After(timestamp) {
117 timestamp = new
118 aa.adapter.LastCommunication = timestamp.Unix()
Kent Hagerman2b216042020-04-03 18:28:56 -0400119 }
120}
khenaidood948f772021-08-11 17:49:24 -0400121
122func (aa *agent) IsConnectionUp() bool {
123 _, err := aa.getClient()
124 return err == nil
125}