blob: d68287ed0def76a2a51589590f66e277d13c4a6b [file] [log] [blame]
Elia Battistonc8d0d462022-02-22 16:30:51 +01001/*
2* Copyright 2022-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 main
18
19import (
20 "context"
21 "fmt"
22 "os"
23 "os/signal"
Elia Battistonbe9edc12022-03-09 11:35:58 +010024 "sync"
Elia Battistonc8d0d462022-02-22 16:30:51 +010025 "syscall"
26 "time"
27
Elia Battistonbe9edc12022-03-09 11:35:58 +010028 "github.com/golang/protobuf/ptypes/empty"
Elia Battistonc8d0d462022-02-22 16:30:51 +010029 "github.com/opencord/voltha-lib-go/v7/pkg/log"
30 "github.com/opencord/voltha-lib-go/v7/pkg/probe"
31 "github.com/opencord/voltha-lib-go/v7/pkg/version"
Elia Battistonbe9edc12022-03-09 11:35:58 +010032 clients "github.com/opencord/voltha-northbound-bbf-adapter/internal/clients"
Elia Battistonc8d0d462022-02-22 16:30:51 +010033 "github.com/opencord/voltha-northbound-bbf-adapter/internal/config"
34)
35
Elia Battistonbe9edc12022-03-09 11:35:58 +010036//String for readiness probe services
Elia Battistonc8d0d462022-02-22 16:30:51 +010037const (
38 bbfAdapterService = "bbf-adapter-service"
39)
40
Elia Battistonbe9edc12022-03-09 11:35:58 +010041type bbfAdapter struct {
42 conf *config.BBFAdapterConfig
43 volthaNbiClient *clients.VolthaNbiClient
44 oltAppClient *clients.OltAppClient
45}
46
47func newBbfAdapter(conf *config.BBFAdapterConfig) *bbfAdapter {
48 return &bbfAdapter{
49 conf: conf,
50 }
51}
52
53func (a *bbfAdapter) start(ctx context.Context, wg *sync.WaitGroup) {
54 var err error
55
56 //Connect to the voltha northbound api
57 a.volthaNbiClient = clients.NewVolthaNbiClient(a.conf.VolthaNbiEndpoint)
58 if err = a.volthaNbiClient.Connect(ctx, a.conf.TlsEnabled, a.conf.TlsVerify); err != nil {
59 logger.Fatalw(ctx, "failed-to-open-voltha-nbi-grpc-connection", log.Fields{"err": err})
60 } else {
61 probe.UpdateStatusFromContext(ctx, a.conf.VolthaNbiEndpoint, probe.ServiceStatusRunning)
62 }
63
64 //Check if the REST APIs of the olt app are reachable
65 a.oltAppClient = clients.NewOltAppClient(a.conf.OnosRestEndpoint, a.conf.OnosUser, a.conf.OnosPassword)
66 if err := a.oltAppClient.CheckConnection(ctx); err != nil {
67 logger.Fatalw(ctx, "failed-to-connect-to-onos-olt-app-api", log.Fields{"err": err})
68 } else {
69 probe.UpdateStatusFromContext(ctx, a.conf.OnosRestEndpoint, probe.ServiceStatusRunning)
70 }
71
72 //Run the main logic of the BBF adapter
73
74 //Set the service as running, making the adapter finally ready
75 probe.UpdateStatusFromContext(ctx, bbfAdapterService, probe.ServiceStatusRunning)
76 logger.Info(ctx, "bbf-adapter-ready")
77
78loop:
79 for {
80 select {
81 case <-ctx.Done():
82 logger.Info(ctx, "stop-for-context-done")
83 break loop
84 case <-time.After(15 * time.Second):
85 //TODO: this is just to test functionality
86
87 //Make a request to voltha
88 devices, err := a.volthaNbiClient.Service.ListDevices(ctx, &empty.Empty{})
89 if err != nil {
90 logger.Errorw(ctx, "failed-to-list-devices", log.Fields{"err": err})
91 continue
92 }
93 logger.Debugw(ctx, "Got devices from VOLTHA", log.Fields{"devNum": len(devices.Items)})
94
95 //Make a request to Olt app
96 response, err := a.oltAppClient.GetStatus()
97 if err != nil {
98 logger.Errorw(ctx, "failed-to-get-status", log.Fields{
99 "err": err,
100 "reponse": response,
101 })
102 continue
103 } else {
104 logger.Debugw(ctx, "Got status from OltApp", log.Fields{"response": response})
105 }
106
107 logger.Warn(ctx, "BBF Adapter currently has no implemented logic.")
108 }
109 }
110
111 probe.UpdateStatusFromContext(ctx, bbfAdapterService, probe.ServiceStatusStopped)
112 wg.Done()
113}
114
115//Close all connections of the adapter
116func (a *bbfAdapter) cleanup() {
117 a.volthaNbiClient.Close()
118}
119
Elia Battistonc8d0d462022-02-22 16:30:51 +0100120func printBanner() {
121 fmt.Println(" ____ ____ ______ _ _ ")
122 fmt.Println(" | _ \\| _ \\| ____| /\\ | | | | ")
123 fmt.Println(" | |_) | |_) | |__ / \\ __| | __ _ _ __ | |_ ___ _ __ ")
124 fmt.Println(" | _ <| _ <| __| / /\\ \\ / _` |/ _` | '_ \\| __/ _ \\ '__|")
125 fmt.Println(" | |_) | |_) | | / ____ \\ (_| | (_| | |_) | || __/ | ")
126 fmt.Println(" |____/|____/|_| /_/ \\_\\__,_|\\__,_| .__/ \\__\\___|_| ")
127 fmt.Println(" | | ")
128 fmt.Println(" |_| ")
129}
130
131func printVersion() {
132 fmt.Println("VOLTHA Northbound BBF Adapter")
133 fmt.Println(version.VersionInfo.String(" "))
134}
135
136func waitForExit(ctx context.Context) int {
137 signalChannel := make(chan os.Signal, 1)
138 signal.Notify(signalChannel,
139 syscall.SIGHUP,
140 syscall.SIGINT,
141 syscall.SIGTERM,
142 syscall.SIGQUIT)
143
144 exitChannel := make(chan int)
145
146 go func() {
147 s := <-signalChannel
148 switch s {
149 case syscall.SIGHUP,
150 syscall.SIGINT,
151 syscall.SIGTERM,
152 syscall.SIGQUIT:
153 logger.Infow(ctx, "closing-signal-received", log.Fields{"signal": s})
154 exitChannel <- 0
155 default:
156 logger.Infow(ctx, "unexpected-signal-received", log.Fields{"signal": s})
157 exitChannel <- 1
158 }
159 }()
160
161 code := <-exitChannel
162 return code
163}
164
165func main() {
Elia Battistonbe9edc12022-03-09 11:35:58 +0100166 ctx, cancelCtx := context.WithCancel(context.Background())
167
Elia Battistonc8d0d462022-02-22 16:30:51 +0100168 start := time.Now()
169
170 conf := config.LoadConfig(ctx)
171
172 //Logging
173 logLevel, err := log.StringToLogLevel(conf.LogLevel)
174 if err != nil {
175 logger.Fatalf(ctx, "Cannot setup logging, %s", err)
176 }
177
178 // Setup default logger - applies for packages that do not have specific logger set
179 if _, err := log.SetDefaultLogger(log.JSON, logLevel, log.Fields{}); err != nil {
180 logger.With(log.Fields{"error": err}).Fatal(ctx, "Cannot setup logging")
181 }
182
183 // Update all loggers (provisionned via init) with a common field
184 if err := log.UpdateAllLoggers(log.Fields{}); err != nil {
185 logger.With(log.Fields{"error": err}).Fatal(ctx, "Cannot setup logging")
186 }
187
188 log.SetAllLogLevel(logLevel)
189
190 defer func() {
191 err := log.CleanUp()
192 if err != nil {
193 logger.Errorw(context.Background(), "unable-to-flush-any-buffered-log-entries", log.Fields{"error": err})
194 }
195 }()
196
197 // Print version and exit
198 if conf.PrintVersion {
199 printVersion()
200 return
201 }
202
203 // Print banner if specified
204 if conf.PrintBanner {
205 printBanner()
206 }
207
208 logger.Infow(ctx, "config", log.Fields{"config": *conf})
209
210 p := &probe.Probe{}
211 go p.ListenAndServe(ctx, conf.ProbeAddress)
212
Elia Battistonbe9edc12022-03-09 11:35:58 +0100213 //Register all services that will need to be initialized before considering the adapter ready
Elia Battistonc8d0d462022-02-22 16:30:51 +0100214 probeCtx := context.WithValue(ctx, probe.ProbeContextKey, p)
Elia Battistonbe9edc12022-03-09 11:35:58 +0100215 p.RegisterService(
216 ctx,
217 bbfAdapterService,
218 conf.VolthaNbiEndpoint,
219 conf.OnosRestEndpoint,
220 )
221
Elia Battistonc8d0d462022-02-22 16:30:51 +0100222 closer, err := log.GetGlobalLFM().InitTracingAndLogCorrelation(conf.TraceEnabled, conf.TraceAgentAddress, conf.LogCorrelationEnabled)
223 if err != nil {
224 logger.Warnw(ctx, "unable-to-initialize-tracing-and-log-correlation-module", log.Fields{"error": err})
225 } else {
226 defer log.TerminateTracing(closer)
227 }
228
Elia Battistonbe9edc12022-03-09 11:35:58 +0100229 adapter := newBbfAdapter(conf)
Elia Battistonc8d0d462022-02-22 16:30:51 +0100230
Elia Battistonbe9edc12022-03-09 11:35:58 +0100231 //Run the adapter
232 wg := &sync.WaitGroup{}
233 wg.Add(1)
234 go adapter.start(probeCtx, wg)
235 defer adapter.cleanup()
Elia Battistonc8d0d462022-02-22 16:30:51 +0100236
Elia Battistonbe9edc12022-03-09 11:35:58 +0100237 //Wait a signal to stop execution
Elia Battistonc8d0d462022-02-22 16:30:51 +0100238 code := waitForExit(ctx)
239 logger.Infow(ctx, "received-a-closing-signal", log.Fields{"code": code})
240
Elia Battistonbe9edc12022-03-09 11:35:58 +0100241 //Stop everything that waits for the context to be done
242 cancelCtx()
243 //Wait for the adapter logic to stop
244 wg.Wait()
245
Elia Battistonc8d0d462022-02-22 16:30:51 +0100246 elapsed := time.Since(start)
247 logger.Infow(ctx, "run-time", log.Fields{"time": elapsed.Seconds()})
248}