blob: d030e72889874ce51f8b84375eaae59af84201af [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
khenaidood948f772021-08-11 17:49:24 -040025 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
26 "github.com/opencord/voltha-lib-go/v7/pkg/log"
khenaidoo9beaaf12021-10-19 17:32:01 -040027 "github.com/opencord/voltha-protos/v5/go/adapter_service"
khenaidoo25057da2021-12-08 14:40:45 -050028 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo9beaaf12021-10-19 17:32:01 -040029 "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
khenaidoo25057da2021-12-08 14:40:45 -050043 coreEndpoint string
Kent Hagerman2b216042020-04-03 18:28:56 -040044}
45
khenaidoo25057da2021-12-08 14:40:45 -050046func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn, clientConn *common.Connection) interface{} {
khenaidoo9beaaf12021-10-19 17:32:01 -040047 svc := adapter_service.NewAdapterServiceClient(conn)
khenaidoo25057da2021-12-08 14:40:45 -050048 if h, err := svc.GetHealthStatus(ctx, clientConn); err != nil || h.State != health.HealthStatus_HEALTHY {
49 logger.Debugw(ctx, "remote-connection-not-ready", log.Fields{"error": err, "health": h, "requester": clientConn, "target": conn.Target()})
khenaidood948f772021-08-11 17:49:24 -040050 return nil
51 }
52 return svc
53}
54
khenaidoo25057da2021-12-08 14:40:45 -050055func newAdapterAgent(coreEndpoint string, adapter *voltha.Adapter, onAdapterRestart vgrpc.RestartedHandler, liveProbeInterval time.Duration) *agent {
Kent Hagerman2b216042020-04-03 18:28:56 -040056 return &agent{
khenaidood948f772021-08-11 17:49:24 -040057 adapter: adapter,
58 onAdapterRestart: onAdapterRestart,
59 adapterAPIEndPoint: adapter.Endpoint,
60 liveProbeInterval: liveProbeInterval,
khenaidoo25057da2021-12-08 14:40:45 -050061 coreEndpoint: coreEndpoint,
khenaidood948f772021-08-11 17:49:24 -040062 }
63}
64
65func (aa *agent) start(ctx context.Context) error {
66 // Establish grpc connection to Core
67 var err error
khenaidoo25057da2021-12-08 14:40:45 -050068 if aa.vClient, err = vgrpc.NewClient(
69 aa.coreEndpoint,
70 aa.adapterAPIEndPoint,
71 aa.onAdapterRestart); err != nil {
khenaidood948f772021-08-11 17:49:24 -040072 return err
73 }
74
75 // Add a liveness communication update
76 aa.vClient.SubscribeForLiveness(aa.updateCommunicationTime)
77
78 go aa.vClient.Start(ctx, setAndTestAdapterServiceHandler)
79 return nil
80}
81
82func (aa *agent) stop(ctx context.Context) {
83 // Close the client
84 if aa.vClient != nil {
85 aa.vClient.Stop(ctx)
Kent Hagerman2b216042020-04-03 18:28:56 -040086 }
87}
88
Rohan Agrawal31f21802020-06-12 05:38:46 +000089func (aa *agent) getAdapter(ctx context.Context) *voltha.Adapter {
khenaidood948f772021-08-11 17:49:24 -040090 aa.adapterLock.RLock()
91 defer aa.adapterLock.RUnlock()
Kent Hagerman2b216042020-04-03 18:28:56 -040092 return aa.adapter
93}
94
khenaidoo9beaaf12021-10-19 17:32:01 -040095func (aa *agent) getClient() (adapter_service.AdapterServiceClient, error) {
khenaidood948f772021-08-11 17:49:24 -040096 client, err := aa.vClient.GetClient()
97 if err != nil {
98 return nil, err
99 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400100 c, ok := client.(adapter_service.AdapterServiceClient)
khenaidood948f772021-08-11 17:49:24 -0400101 if ok {
102 return c, nil
103 }
104 return nil, errors.New("invalid client returned")
105}
106
107func (aa *agent) resetConnection(ctx context.Context) {
108 if aa.vClient != nil {
109 aa.vClient.Reset(ctx)
110 }
111}
112
Kent Hagerman2b216042020-04-03 18:28:56 -0400113// updateCommunicationTime updates the message to the specified time.
114// No attempt is made to save the time to the db, so only recent times are guaranteed to be accurate.
115func (aa *agent) updateCommunicationTime(new time.Time) {
116 // 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 +0000117 aa.lock.Lock()
118 defer aa.lock.Unlock()
khenaidood948f772021-08-11 17:49:24 -0400119 timestamp := time.Unix(aa.adapter.LastCommunication, 0)
120 if !new.After(time.Now()) && new.After(timestamp) {
121 timestamp = new
122 aa.adapter.LastCommunication = timestamp.Unix()
Kent Hagerman2b216042020-04-03 18:28:56 -0400123 }
124}
khenaidood948f772021-08-11 17:49:24 -0400125
126func (aa *agent) IsConnectionUp() bool {
127 _, err := aa.getClient()
128 return err == nil
129}