2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
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
10 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
26 "github.com/spf13/viper"
37 type ReadyCB func(interface{})
38 type ShutdownCB func()
41 // XApp is an application instance
49 Subscription *Subscriber
52 readyCbParams interface{}
59 return Rmr != nil && Rmr.IsReady() && Sdl != nil && Sdl.IsReady()
62 func SetReadyCB(cb ReadyCB, params interface{}) {
64 readyCbParams = params
67 func XappReadyCb(params interface{}) {
68 Alarm = NewAlarmClient(viper.GetString("moId"), viper.GetString("name"))
70 readyCb(readyCbParams)
74 func xappShutdownCb() {
76 Logger.Info("Wait for xapp to get unregistered")
77 time.Sleep(10 * time.Second)
85 name, _ := os.Hostname()
86 httpservicename := "SERVICE_RICXAPP_" + strings.ToUpper(name) + "_HTTP_PORT"
87 httpendpoint := os.Getenv(strings.Replace(httpservicename, "-", "_", -1))
88 urlString := strings.Split(httpendpoint, "//")
89 // Added this check to make UT pass
90 if urlString[0] == "" {
93 resp, err := http.Get(fmt.Sprintf("http://%s/ric/v1/health/ready", urlString[1]))
95 time.Sleep(5 * time.Second)
97 Logger.Error("Error in health check: %v", err)
101 Logger.Info("Health Probe Success with resp.StatusCode is %v", resp.StatusCode)
102 if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
106 Logger.Info("Health Probe failed, retrying...")
111 func SendRegistermsg() {
112 name, _ := os.Hostname()
113 xappname := viper.GetString("name")
114 xappversion := viper.GetString("version")
115 appnamespace := os.Getenv("APP_NAMESPACE")
116 if appnamespace == "" {
117 appnamespace = "ricxapp"
119 httpservicename := "SERVICE_" + strings.ToUpper(appnamespace) + "_" + strings.ToUpper(name) + "_HTTP_PORT"
120 rmrservicename := "SERVICE_" + strings.ToUpper(appnamespace) + "_" + strings.ToUpper(name) + "_RMR_PORT"
121 httpendpointstr := os.Getenv(strings.Replace(httpservicename, "-", "_", -1))
122 rmrendpointstr := os.Getenv(strings.Replace(rmrservicename, "-", "_", -1))
123 httpendpoint := strings.Split(httpendpointstr, "//")
124 rmrendpoint := strings.Split(rmrendpointstr, "//")
125 if httpendpoint[0] == "" || rmrendpoint[0] == "" {
129 pltnamespace := os.Getenv("PLT_NAMESPACE")
130 if pltnamespace == "" {
131 pltnamespace = "ricplt"
134 configpath := "/ric/v1/config"
136 requestBody, err := json.Marshal(map[string]string{
138 "httpEndpoint": httpendpoint[1],
139 "rmrEndpoint": rmrendpoint[1],
140 "appInstanceName": xappname,
141 "appVersion": xappversion,
142 "configPath": configpath,
146 Logger.Info("Error while compiling request to appmgr: %v", err)
148 url := fmt.Sprintf("http://service-%v-appmgr-http.%v:8080/ric/v1/register", pltnamespace, pltnamespace)
149 resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
150 Logger.Info(" Resp is %v", resp)
152 Logger.Info("Error compiling request to appmgr: %v", err)
154 Logger.Info("Registering request sent. Response received is :%v", resp)
157 body, err := ioutil.ReadAll(resp.Body)
158 Logger.Info("Post body is %v", resp.Body)
160 Logger.Info("rsp: Error compiling request to appmgr: %v", string(body))
162 defer resp.Body.Close()
167 func SendDeregistermsg() {
169 name, _ := os.Hostname()
170 xappname := viper.GetString("name")
172 appnamespace := os.Getenv("APP_NAMESPACE")
173 if appnamespace == "" {
174 appnamespace = "ricxapp"
176 pltnamespace := os.Getenv("PLT_NAMESPACE")
177 if pltnamespace == "" {
178 pltnamespace = "ricplt"
181 requestBody, err := json.Marshal(map[string]string{
183 "appInstanceName": xappname,
187 Logger.Info("Error while compiling request to appmgr: %v", err)
189 url := fmt.Sprintf("http://service-%v-appmgr-http.%v:8080/ric/v1/deregister", pltnamespace, pltnamespace)
190 resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
191 Logger.Info(" Resp is %v", resp)
193 Logger.Info("Error compiling request to appmgr: %v", err)
195 Logger.Info("Deregistering request sent. Response received is :%v", resp)
198 body, err := ioutil.ReadAll(resp.Body)
199 Logger.Info("Post body is %v", resp.Body)
201 Logger.Info("rsp: Error compiling request to appmgr: %v", string(body))
203 defer resp.Body.Close()
208 func SetShutdownCB(cb ShutdownCB) {
212 func InstallSignalHandler() {
214 // Signal handlers to really exit program.
215 // shutdownCb can hang until application has
216 // made all needed gracefull shutdown actions
217 // hardcoded limit for shutdown is 20 seconds
219 interrupt := make(chan os.Signal, 1)
220 signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
221 //signal handler function
223 for range interrupt {
224 if atomic.CompareAndSwapInt32(&shutdownFlag, 0, 1) {
228 sentry := make(chan struct{})
233 if shutdownCb != nil {
239 case <-time.After(time.Duration(timeout) * time.Second):
240 Logger.Info("xapp-frame shutdown callback took more than %d seconds", timeout)
242 Logger.Info("xapp-frame shutdown callback handled within %d seconds", timeout)
247 newCnt := atomic.AddInt32(&shutdownCnt, 1)
248 Logger.Info("xapp-frame shutdown already ongoing. Forced exit counter %d/%d ", newCnt, 5)
250 Logger.Info("xapp-frame shutdown forced exit")
261 // Load xapp configuration
262 Logger = LoadConfig()
264 if viper.IsSet("controls.logger.level") {
265 Logger.SetLevel(viper.GetInt("controls.logger.level"))
267 Logger.SetLevel(viper.GetInt("logger.level"))
271 Resource = NewRouter()
272 Config = Configurator{}
273 Metric = NewMetrics(viper.GetString("metrics.url"), viper.GetString("metrics.namespace"), Resource.router)
274 Subscription = NewSubscriber(viper.GetString("subscription.host"), viper.GetInt("subscription.timeout"))
275 Sdl = NewSDLClient(viper.GetString("controls.db.namespace"))
276 Rnib = NewRNIBClient()
278 InstallSignalHandler()
281 func RunWithParams(c MessageConsumer, sdlcheck bool) {
283 Rmr.SetReadyCB(XappReadyCb, nil)
284 SetShutdownCB(xappShutdownCb)
285 host := fmt.Sprintf(":%d", GetPortData("http").Port)
286 go http.ListenAndServe(host, Resource.router)
287 Logger.Info(fmt.Sprintf("Xapp started, listening on: %s", host))
295 func Run(c MessageConsumer) {
296 RunWithParams(c, true)