blob: e335c0835960153398b7cf063c91e323cb97a783 [file] [log] [blame]
Mohamed Abukar2e78e422019-06-02 11:45:52 +03001/*
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
20package xapp
21
22import (
23 "encoding/json"
24 "github.com/gorilla/mux"
wahidw413abf52020-12-15 12:17:09 +000025 "github.com/spf13/viper"
Mohamed Abukarf4668932020-09-15 09:40:07 +030026 "io/ioutil"
Mohamed Abukar2e78e422019-06-02 11:45:52 +030027 "net/http"
wahidw413abf52020-12-15 12:17:09 +000028 "os"
29
30 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
Mohamed Abukar2e78e422019-06-02 11:45:52 +030031)
32
33const (
wahidw413abf52020-12-15 12:17:09 +000034 ReadyURL = "/ric/v1/health/ready"
35 AliveURL = "/ric/v1/health/alive"
36 ConfigURL = "/ric/v1/cm/{name}"
37 AppConfigURL = "/ric/v1/config"
Mohamed Abukar2e78e422019-06-02 11:45:52 +030038)
39
Mohamed Abukar256c3042020-12-30 17:48:12 +020040var (
41 healthReady bool
42)
43
Mohamed Abukar2e78e422019-06-02 11:45:52 +030044type StatusCb func() bool
45
46type Router struct {
47 router *mux.Router
48 cbMap []StatusCb
49}
50
51func NewRouter() *Router {
52 r := &Router{
53 router: mux.NewRouter().StrictSlash(true),
54 cbMap: make([]StatusCb, 0),
55 }
56
57 // Inject default routes for health probes
58 r.InjectRoute(ReadyURL, readyHandler, "GET")
59 r.InjectRoute(AliveURL, aliveHandler, "GET")
Mohamed Abukarf4668932020-09-15 09:40:07 +030060 r.InjectRoute(ConfigURL, configHandler, "POST")
wahidw413abf52020-12-15 12:17:09 +000061 r.InjectRoute(AppConfigURL, appconfigHandler, "GET")
Mohamed Abukar2e78e422019-06-02 11:45:52 +030062
63 return r
64}
65
66func (r *Router) serviceChecker(inner http.HandlerFunc) http.HandlerFunc {
67 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
68 Logger.Info("restapi: method=%s url=%s", req.Method, req.URL.RequestURI())
Mohamed Abukar9cfde092020-04-28 17:11:33 +030069 if req.URL.RequestURI() == AliveURL || r.CheckStatus() {
Mohamed Abukar2e78e422019-06-02 11:45:52 +030070 inner.ServeHTTP(w, req)
71 } else {
72 respondWithJSON(w, http.StatusServiceUnavailable, nil)
73 }
74 })
75}
76
77func (r *Router) InjectRoute(url string, handler http.HandlerFunc, method string) *mux.Route {
Juha Hyttinen5bd72732020-08-14 11:38:06 +030078 return r.router.Path(url).HandlerFunc(r.serviceChecker(handler)).Methods(method)
Mohamed Abukar2e78e422019-06-02 11:45:52 +030079}
80
81func (r *Router) InjectQueryRoute(url string, h http.HandlerFunc, m string, q ...string) *mux.Route {
Juha Hyttinen5bd72732020-08-14 11:38:06 +030082 return r.router.Path(url).HandlerFunc(r.serviceChecker(h)).Methods(m).Queries(q...)
83}
84
85func (r *Router) InjectRoutePrefix(prefix string, handler http.HandlerFunc) *mux.Route {
86 return r.router.PathPrefix(prefix).HandlerFunc(r.serviceChecker(handler))
Mohamed Abukar2e78e422019-06-02 11:45:52 +030087}
88
89func (r *Router) InjectStatusCb(f StatusCb) {
90 r.cbMap = append(r.cbMap, f)
91}
92
93func (r *Router) CheckStatus() (status bool) {
94 if len(r.cbMap) == 0 {
95 return true
96 }
97
98 for _, f := range r.cbMap {
99 status = f()
100 }
101 return
102}
103
Mohamed Abukar256c3042020-12-30 17:48:12 +0200104func IsHealthProbeReady() bool {
105 return healthReady
106}
107
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300108func readyHandler(w http.ResponseWriter, r *http.Request) {
Mohamed Abukar256c3042020-12-30 17:48:12 +0200109 healthReady = true
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300110 respondWithJSON(w, http.StatusOK, nil)
111}
112
113func aliveHandler(w http.ResponseWriter, r *http.Request) {
114 respondWithJSON(w, http.StatusOK, nil)
115}
116
Mohamed Abukarf4668932020-09-15 09:40:07 +0300117func configHandler(w http.ResponseWriter, r *http.Request) {
118 xappName := mux.Vars(r)["name"]
119 if xappName == "" || r.Body == nil {
120 respondWithJSON(w, http.StatusBadRequest, nil)
121 return
122 }
123 defer r.Body.Close()
124
125 body, err := ioutil.ReadAll(r.Body)
126 if err != nil {
127 Logger.Error("ioutil.ReadAll failed: %v", err)
128 respondWithJSON(w, http.StatusInternalServerError, nil)
129 return
130 }
131
132 if err := PublishConfigChange(xappName, string(body)); err != nil {
133 respondWithJSON(w, http.StatusInternalServerError, nil)
134 return
135 }
136
137 respondWithJSON(w, http.StatusOK, nil)
138}
139
Mohamed Abukar2e78e422019-06-02 11:45:52 +0300140func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
141 w.Header().Set("Content-Type", "application/json")
142 w.WriteHeader(code)
143 if payload != nil {
144 response, _ := json.Marshal(payload)
145 w.Write(response)
146 }
147}
wahidw413abf52020-12-15 12:17:09 +0000148
149func appconfigHandler(w http.ResponseWriter, r *http.Request) {
150
151 Logger.Info("Inside appconfigHandler")
152
153 var appconfig models.XappConfigList
154 var metadata models.ConfigMetadata
155 var xappconfig models.XAppConfig
156 name := viper.GetString("name")
157 configtype := "json"
158 metadata.XappName = &name
159 metadata.ConfigType = &configtype
160
161 configFile, err := os.Open("/opt/ric/config/config-file.json")
162 if err != nil {
163 Logger.Error("Cannot open config file: %v", err)
164 respondWithJSON(w, http.StatusInternalServerError, nil)
165 // return nil,errors.New("Could Not parse the config file")
166 }
167
168 body, err := ioutil.ReadAll(configFile)
169
170 defer configFile.Close()
171
172 xappconfig.Metadata = &metadata
173 xappconfig.Config = string(body)
174
175 appconfig = append(appconfig, &xappconfig)
176
177 respondWithJSON(w, http.StatusOK, appconfig)
178
179 //return appconfig,nil
180}