Release of Routing Manager v0.3.0
[ric-plt/rtmgr.git] / cmd / rtmgr.go
1 /*
2 ==================================================================================
3    Copyright (c) 2019 AT&T Intellectual Property.
4    Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19 /*
20         Mnemonic:       rtmgr.go
21         Abstract:       Routing Manager Main file. Implemets the following functions:
22                         - parseArgs: reading command line arguments
23                         - init:Rtmgr initializing the service modules
24                         - serve: running the loop
25         Date:           12 March 2019
26 */
27 package main
28
29 import (
30         "flag"
31         "os"
32         "os/signal"
33         "routing-manager/pkg/nbi"
34         "routing-manager/pkg/rpe"
35         "routing-manager/pkg/rtmgr"
36         "routing-manager/pkg/sbi"
37         "routing-manager/pkg/sdl"
38         "syscall"
39         "time"
40 )
41
42 const SERVICENAME = "rtmgr"
43 const INTERVAL time.Duration = 2
44
45 var (
46         args map[string]*string
47 )
48
49 func parseArgs() {
50         // TODO: arguments should be validated (filename; xm-url; sbi-if; rest-url; rest-port)
51         args = make(map[string]*string)
52         args["configfile"] = flag.String("configfile", "/etc/rtmgrcfg.json", "Routing manager's configuration file path")
53         args["nbi"] = flag.String("nbi", "httpGetter", "Northbound interface module to be used. Valid values are: 'httpGetter | httpRESTful'")
54         args["sbi"] = flag.String("sbi", "nngpush", "Southbound interface module to be used. Valid values are: 'nngpush | nngpub'")
55         args["rpe"] = flag.String("rpe", "rmrpush", "Route Policy Engine to be used. Valid values are: 'rmrpush | rmrpub'")
56         args["sdl"] = flag.String("sdl", "file", "Datastore enginge to be used. Valid values are: 'file'")
57         args["xm-url"] = flag.String("xm-url", "http://localhost:3000/xapps", "HTTP URL where xApp Manager exposes the entire xApp List")
58         args["nbi-if"] = flag.String("nbi-if", "http://localhost:8888", "Base HTTP URL where routing manager will be listening on")
59         args["sbi-if"] = flag.String("sbi-if", "0.0.0.0", "IPv4 address of interface where Southbound socket to be opened")
60         args["filename"] = flag.String("filename", "/db/rt.json", "Absolute path of file where the route information to be stored")
61         args["loglevel"] = flag.String("loglevel", "INFO", "INFO | WARN | ERROR | DEBUG")
62         flag.Parse()
63 }
64
65 func initRtmgr() (nbi.NbiEngine, sbi.SbiEngine, sdl.SdlEngine, rpe.RpeEngine, error) {
66         var err error
67         var nbii nbi.NbiEngine
68         var sbii sbi.SbiEngine
69         var sdli sdl.SdlEngine
70         var rpei rpe.RpeEngine
71         if nbii, err = nbi.GetNbi(*args["nbi"]); err == nil && nbii != nil {
72                 if sbii, err = sbi.GetSbi(*args["sbi"]); err == nil && sbii != nil {
73                         if sdli, err = sdl.GetSdl(*args["sdl"]); err == nil && sdli != nil {
74                                 if rpei, err = rpe.GetRpe(*args["rpe"]); err == nil && rpei != nil {
75                                         return nbii, sbii, sdli, rpei, nil
76                                 }
77                         }
78                 }
79         }
80         return nil, nil, nil, nil, err
81 }
82
83 func serveSBI(triggerSBI <-chan bool, sbiEngine sbi.SbiEngine, sdlEngine sdl.SdlEngine, rpeEngine rpe.RpeEngine) {
84         for {
85                 if <-triggerSBI {
86                         data, err := sdlEngine.ReadAll(*args["filename"])
87                         if err != nil || data == nil {
88                                 rtmgr.Logger.Error("cannot get data from sdl interface due to: " + err.Error())
89                                 continue
90                         }
91                         sbiEngine.UpdateEndpoints(data)
92                         policies := rpeEngine.GeneratePolicies(rtmgr.Eps)
93                         err = sbiEngine.DistributeAll(policies)
94                         if err != nil {
95                                 rtmgr.Logger.Error("routing rable cannot be published due to: " + err.Error())
96                         }
97                 }
98         }
99 }
100
101 func serve(nbiEngine nbi.NbiEngine, sbiEngine sbi.SbiEngine, sdlEngine sdl.SdlEngine, rpeEngine rpe.RpeEngine) {
102
103         triggerSBI := make(chan bool)
104
105         nbiErr := nbiEngine.Initialize(*args["xm-url"], *args["nbi-if"], *args["filename"], *args["configfile"],
106                                         sdlEngine, rpeEngine, triggerSBI)
107         if nbiErr != nil {
108                 rtmgr.Logger.Error("fail to initialize nbi due to: " + nbiErr.Error())
109                 return
110         }
111
112         err := sbiEngine.Initialize(*args["sbi-if"])
113         if err != nil {
114                 rtmgr.Logger.Info("fail to open pub socket due to: " + err.Error())
115                 return
116         }
117         defer nbiEngine.Terminate()
118         defer sbiEngine.Terminate()
119
120         // This SBI Go routine is trtiggered by periodic main loop and when data is recieved on REST interface.
121         go serveSBI(triggerSBI, sbiEngine, sdlEngine, rpeEngine)
122
123         for {
124                 time.Sleep(INTERVAL * time.Second)
125                 if *args["nbi"] == "httpGetter" {
126                         data, err := nbiEngine.(*nbi.HttpGetter).FetchAllXapps(*args["xm-url"])
127                         if err != nil {
128                                 rtmgr.Logger.Error("cannot fetch xapp data dute to: " + err.Error())
129                         } else if data != nil {
130                                 sdlEngine.WriteXapps(*args["filename"], data)
131                         }
132                 }
133
134                 triggerSBI <- true
135         }
136 }
137
138 func SetupCloseHandler() {
139         c := make(chan os.Signal, 2)
140         signal.Notify(c, os.Interrupt, syscall.SIGTERM)
141         go func() {
142                 <-c
143                 rtmgr.Logger.Info("\r- Ctrl+C pressed in Terminal")
144                 os.Exit(0)
145         }()
146 }
147
148 func main() {
149         parseArgs()
150         rtmgr.SetLogLevel(*args["loglevel"])
151         nbiEngine, sbiEngine, sdlEngine, rpeEngine, err := initRtmgr()
152         if err != nil {
153                 rtmgr.Logger.Error(err.Error())
154                 os.Exit(1)
155         }
156         SetupCloseHandler()
157         rtmgr.Logger.Info("Start " + SERVICENAME + " service")
158         rtmgr.Eps = make(rtmgr.Endpoints)
159         serve(nbiEngine, sbiEngine, sdlEngine, rpeEngine)
160         os.Exit(0)
161 }