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 ==================================================================================
34 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/models"
35 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi"
36 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations"
37 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations/health"
38 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations/xapp"
39 "github.com/go-openapi/loads"
40 "github.com/go-openapi/runtime/middleware"
41 "github.com/valyala/fastjson"
43 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
44 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/resthooks"
47 type XappData struct {
55 xappInstance *models.XappInstance
58 var xappmap = map[string]map[string]*XappData{}
60 func NewRestful() *Restful {
62 rh: resthooks.NewResthook(true),
65 r.api = r.SetupHandler()
69 func (r *Restful) Run() {
70 server := restapi.NewServer(r.api)
71 defer server.Shutdown()
73 server.Host = "0.0.0.0"
75 appmgr.Logger.Info("Xapp manager started ... serving on %s:%d\n", server.Host, server.Port)
78 if err := server.Serve(); err != nil {
79 log.Fatal(err.Error())
84 func (r *Restful) RetrieveApps() {
85 time.Sleep(5 * time.Second)
86 var xlist models.RegisterRequest
87 applist := r.rh.GetAppsInSDL()
89 appmgr.Logger.Info("List obtained from GetAppsInSDL is %s", *applist)
90 newstring := strings.Split(*applist, " ")
91 for i, _ := range newstring {
92 appmgr.Logger.Debug("Checking for xapp %s", newstring[i])
93 if newstring[i] != "" {
94 err := json.Unmarshal([]byte(newstring[i]), &xlist)
96 appmgr.Logger.Error("Error while unmarshalling")
100 continue //SDL may have empty item,so need to skip
103 xmodel, _ := r.PrepareConfig(xlist, false)
105 appmgr.Logger.Error("Xapp not found, deleting it from DB")
106 r.rh.UpdateAppData(xlist, true)
113 func (r *Restful) SetupHandler() *operations.AppManagerAPI {
114 swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
116 appmgr.Logger.Error(err.Error())
119 api := operations.NewAppManagerAPI(swaggerSpec)
121 // URL: /ric/v1/health
122 api.HealthGetHealthAliveHandler = health.GetHealthAliveHandlerFunc(
123 func(params health.GetHealthAliveParams) middleware.Responder {
124 return health.NewGetHealthAliveOK()
127 api.HealthGetHealthReadyHandler = health.GetHealthReadyHandlerFunc(
128 func(params health.GetHealthReadyParams) middleware.Responder {
129 return health.NewGetHealthReadyOK()
132 // URL: /ric/v1/subscriptions
133 api.GetSubscriptionsHandler = operations.GetSubscriptionsHandlerFunc(
134 func(params operations.GetSubscriptionsParams) middleware.Responder {
135 return operations.NewGetSubscriptionsOK().WithPayload(r.rh.GetAllSubscriptions())
138 api.GetSubscriptionByIDHandler = operations.GetSubscriptionByIDHandlerFunc(
139 func(params operations.GetSubscriptionByIDParams) middleware.Responder {
140 if result, found := r.rh.GetSubscriptionById(params.SubscriptionID); found {
141 return operations.NewGetSubscriptionByIDOK().WithPayload(&result)
143 return operations.NewGetSubscriptionByIDNotFound()
146 api.AddSubscriptionHandler = operations.AddSubscriptionHandlerFunc(
147 func(params operations.AddSubscriptionParams) middleware.Responder {
148 return operations.NewAddSubscriptionCreated().WithPayload(r.rh.AddSubscription(*params.SubscriptionRequest))
151 api.ModifySubscriptionHandler = operations.ModifySubscriptionHandlerFunc(
152 func(params operations.ModifySubscriptionParams) middleware.Responder {
153 if _, ok := r.rh.ModifySubscription(params.SubscriptionID, *params.SubscriptionRequest); ok {
154 return operations.NewModifySubscriptionOK()
156 return operations.NewModifySubscriptionBadRequest()
159 api.DeleteSubscriptionHandler = operations.DeleteSubscriptionHandlerFunc(
160 func(params operations.DeleteSubscriptionParams) middleware.Responder {
161 if _, ok := r.rh.DeleteSubscription(params.SubscriptionID); ok {
162 return operations.NewDeleteSubscriptionNoContent()
164 return operations.NewDeleteSubscriptionBadRequest()
168 api.XappGetAllXappsHandler = xapp.GetAllXappsHandlerFunc(
169 func(params xapp.GetAllXappsParams) middleware.Responder {
170 if result, err := r.GetApps(); err == nil {
171 return xapp.NewGetAllXappsOK().WithPayload(result)
173 return xapp.NewGetAllXappsInternalServerError()
176 api.RegisterXappHandler = operations.RegisterXappHandlerFunc(
177 func(params operations.RegisterXappParams) middleware.Responder {
178 appmgr.Logger.Info("appname is %s", (*params.RegisterRequest.AppName))
179 appmgr.Logger.Info("endpoint is %s", (*params.RegisterRequest.HTTPEndpoint))
180 appmgr.Logger.Info("rmrendpoint is %s", (*params.RegisterRequest.RmrEndpoint))
181 if result, err := r.RegisterXapp(*params.RegisterRequest); err == nil {
182 go r.rh.PublishSubscription(*result, models.EventTypeDeployed)
183 return operations.NewRegisterXappCreated()
185 return operations.NewRegisterXappBadRequest()
188 api.DeregisterXappHandler = operations.DeregisterXappHandlerFunc(
189 func(params operations.DeregisterXappParams) middleware.Responder {
190 appmgr.Logger.Info("appname is %s", (*params.DeregisterRequest.AppName))
191 if result, err := r.DeregisterXapp(*params.DeregisterRequest); err == nil {
192 go r.rh.PublishSubscription(*result, models.EventTypeUndeployed)
193 return operations.NewDeregisterXappNoContent()
195 return operations.NewDeregisterXappBadRequest()
201 func httpGetXAppsconfig(url string) (*appmgr.RtmData, error) {
202 appmgr.Logger.Info("Invoked httprestful.httpGetXApps: " + url)
203 resp, err := http.Get(url)
207 defer resp.Body.Close()
209 if resp.StatusCode == http.StatusOK {
210 var data XappConfigList
211 appmgr.Logger.Info("http client raw response: %v", resp)
212 if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
213 appmgr.Logger.Error("Json decode failed: " + err.Error())
216 //data[0] assuming only for one app
217 str := fmt.Sprintf("%v", data[0].Config)
218 appmgr.Logger.Info("HTTP BODY: %v", str)
222 var p fastjson.Parser
223 var msgs appmgr.RtmData
225 v, err := p.Parse(str)
227 appmgr.Logger.Info("fastjson.Parser for failed: %v", err)
232 for _, m := range v.GetArray("rmr", "txMessages") {
233 msgs.TxMessages = append(msgs.TxMessages, strings.Trim(m.String(), `"`))
236 for _, m := range v.GetArray("rmr", "rxMessages") {
237 msgs.RxMessages = append(msgs.RxMessages, strings.Trim(m.String(), `"`))
240 for _, m := range v.GetArray("rmr", "policies") {
241 if val, err := strconv.Atoi(strings.Trim(m.String(), `"`)); err == nil {
242 msgs.Policies = append(msgs.Policies, int64(val))
246 for _, p := range v.GetArray("messaging", "ports") {
247 appmgr.Logger.Info("txMessages=%v, rxMessages=%v", p.GetArray("txMessages"), p.GetArray("rxMessages"))
248 for _, m := range p.GetArray("txMessages") {
249 msgs.TxMessages = append(msgs.TxMessages, strings.Trim(m.String(), `"`))
252 for _, m := range p.GetArray("rxMessages") {
253 msgs.RxMessages = append(msgs.RxMessages, strings.Trim(m.String(), `"`))
256 for _, m := range p.GetArray("policies") {
257 if val, err := strconv.Atoi(strings.Trim(m.String(), `"`)); err == nil {
258 msgs.Policies = append(msgs.Policies, int64(val))
265 appmgr.Logger.Info("httprestful got an unexpected http status code: %v", resp.StatusCode)
269 func (r *Restful) RegisterXapp(params models.RegisterRequest) (xapp *models.Xapp, err error) {
270 return r.PrepareConfig(params, true)
273 func (r *Restful) DeregisterXapp(params models.DeregisterRequest) (xapp *models.Xapp, err error) {
274 var registeredlist models.RegisterRequest
275 registeredlist.AppName = params.AppName
276 registeredlist.AppInstanceName = params.AppInstanceName
277 if _, found := xappmap[*params.AppName]; found {
279 x.Instances = append(x.Instances, xappmap[*params.AppName][*params.AppInstanceName].xappInstance)
280 registeredlist.HTTPEndpoint = &xappmap[*params.AppName][*params.AppInstanceName].httpendpoint
281 delete(xappmap[*params.AppName], *params.AppInstanceName)
282 if len(xappmap[*params.AppName]) == 0 {
283 delete(xappmap, *params.AppName)
285 r.rh.UpdateAppData(registeredlist, true)
288 appmgr.Logger.Error("XApp Instance %v Not Found", *params.AppName)
289 return nil, errors.New("XApp Instance Not Found")
293 func (r *Restful) PrepareConfig(params models.RegisterRequest, updateflag bool) (xapp *models.Xapp, err error) {
295 //tmpString := strings.Split(*params.HTTPEndpoint, "//")
296 appmgr.Logger.Info("http endpoint is %s", *params.HTTPEndpoint)
297 for i := 1; i <= maxRetries; i++ {
298 data, err := httpGetXAppsconfig(fmt.Sprintf("http://%s%s", *params.HTTPEndpoint, params.ConfigPath))
300 if data != nil && err == nil {
301 appmgr.Logger.Info("iRetry Count = %v", i)
304 xapp.Name = params.AppName
305 xapp.Version = params.AppVersion
306 //xapp.Status = params.Status
308 r.rh.UpdateAppData(params, updateflag)
309 return r.FillInstanceData(params, &xapp, *data)
311 } else if err == nil {
312 appmgr.Logger.Error("Unexpected HTTP status code/JSON Parsing error")
314 appmgr.Logger.Error("Couldn't get data due to" + err.Error())
316 time.Sleep(2 * time.Second)
319 return nil, errors.New("Unable to get configmap after 5 retries")
322 func (r *Restful) FillInstanceData(params models.RegisterRequest, xapp *models.Xapp, rtData appmgr.RtmData) (xapps *models.Xapp, err error) {
324 //tmpString := strings.Split(*params.RmrEndpoint, "//")
325 endPointStr := strings.Split(*params.RmrEndpoint, ":")
326 var x models.XappInstance
327 x.Name = params.AppInstanceName
328 //x.Status = strings.ToLower(params.Status)
329 x.Status = "deployed"
330 x.IP = endPointStr[0]
331 x.Port, _ = strconv.ParseInt(endPointStr[1], 10, 64)
332 x.TxMessages = rtData.TxMessages
333 x.RxMessages = rtData.RxMessages
334 x.Policies = rtData.Policies
335 xapp.Instances = append(xapp.Instances, &x)
337 a := &XappData{httpendpoint: *params.HTTPEndpoint, rmrendpoint: *params.RmrEndpoint, status: "deployed", xappname: *params.AppName, xappversion: params.AppVersion, xappinstname: *params.AppInstanceName, xappconfigpath: params.ConfigPath, xappInstance: &x}
339 if _, ok := xappmap[*params.AppName]; ok {
340 xappmap[*params.AppName][*params.AppInstanceName] = a
341 appmgr.Logger.Info("appname already present, %v", xappmap[*params.AppName])
343 xappmap[*params.AppName] = make(map[string]*XappData)
344 xappmap[*params.AppName][*params.AppInstanceName] = a
345 appmgr.Logger.Info("Creating app instance, %v", xappmap[*params.AppName])
352 func (r *Restful) GetApps() (xapps models.AllDeployedXapps, err error) {
353 xapps = models.AllDeployedXapps{}
354 for _, v := range xappmap {
356 for i, j := range v {
359 x.Version = j.xappversion
360 appmgr.Logger.Info("Xapps details currently in map Appname = %v,rmrendpoint = %v,Status = %v", i, j.rmrendpoint, j.status)
361 x.Instances = append(x.Instances, j.xappInstance)
363 xapps = append(xapps, &x)