blob: e6bebb788bb9e9a289bfb8b270e2952235297ded [file] [log] [blame]
Mohamed Abukar34e43832019-11-13 17:57:15 +02001/*
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 restful
21
22import (
wahidwd8726302020-12-13 17:34:29 +000023 "encoding/json"
24 "errors"
25 "fmt"
Mohamed Abukar34e43832019-11-13 17:57:15 +020026 "log"
wahidwd8726302020-12-13 17:34:29 +000027 "net/http"
Mohamed Abukar34e43832019-11-13 17:57:15 +020028 "os"
wahidwd8726302020-12-13 17:34:29 +000029 "strconv"
30 "strings"
Mohamed Abukar34e43832019-11-13 17:57:15 +020031 "time"
32
Abukar Mohamedf8b99662020-03-02 14:44:30 +000033 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/models"
34 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi"
35 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations"
36 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations/health"
37 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/restapi/operations/xapp"
Mohamed Abukar34e43832019-11-13 17:57:15 +020038 "github.com/go-openapi/loads"
39 "github.com/go-openapi/runtime/middleware"
wahidwd8726302020-12-13 17:34:29 +000040 "github.com/valyala/fastjson"
Mohamed Abukar34e43832019-11-13 17:57:15 +020041
Abukar Mohamedf8b99662020-03-02 14:44:30 +000042 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
Abukar Mohamedf8b99662020-03-02 14:44:30 +000043 "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/resthooks"
Mohamed Abukar34e43832019-11-13 17:57:15 +020044)
45
wahidwd8726302020-12-13 17:34:29 +000046type XappData struct {
wahidw382755b2021-01-18 13:00:57 +000047 httpendpoint string
48 rmrendpoint string
49 rmrserviceep string
50 status string
51 xappname string
52 xappinstname string
53 xappversion string
54 xappconfigpath string
55 xappdynamiconfig bool
56 xappInstance *models.XappInstance
wahidwd8726302020-12-13 17:34:29 +000057}
58
59var xappmap = map[string]map[string]*XappData{}
60
Mohamed Abukar34e43832019-11-13 17:57:15 +020061func NewRestful() *Restful {
62 r := &Restful{
Mohamed Abukard9769772019-11-20 20:39:06 +020063 rh: resthooks.NewResthook(true),
Mohamed Abukar34e43832019-11-13 17:57:15 +020064 ready: false,
65 }
66 r.api = r.SetupHandler()
67 return r
68}
69
70func (r *Restful) Run() {
71 server := restapi.NewServer(r.api)
72 defer server.Shutdown()
Mohamed Abukard9769772019-11-20 20:39:06 +020073 server.Port = 8080
74 server.Host = "0.0.0.0"
Mohamed Abukar34e43832019-11-13 17:57:15 +020075
76 appmgr.Logger.Info("Xapp manager started ... serving on %s:%d\n", server.Host, server.Port)
77
Abukar Mohamed21fd77f2021-03-11 12:59:02 +000078 go r.symptomdataServer()
wahidwd8726302020-12-13 17:34:29 +000079 go r.RetrieveApps()
Mohamed Abukar34e43832019-11-13 17:57:15 +020080 if err := server.Serve(); err != nil {
81 log.Fatal(err.Error())
82 }
wahidwd8726302020-12-13 17:34:29 +000083
84}
85
86func (r *Restful) RetrieveApps() {
87 time.Sleep(5 * time.Second)
88 var xlist models.RegisterRequest
89 applist := r.rh.GetAppsInSDL()
90 if applist != nil {
91 appmgr.Logger.Info("List obtained from GetAppsInSDL is %s", *applist)
92 newstring := strings.Split(*applist, " ")
93 for i, _ := range newstring {
94 appmgr.Logger.Debug("Checking for xapp %s", newstring[i])
95 if newstring[i] != "" {
96 err := json.Unmarshal([]byte(newstring[i]), &xlist)
97 if err != nil {
98 appmgr.Logger.Error("Error while unmarshalling")
99 continue
100 }
101 } else {
102 continue //SDL may have empty item,so need to skip
103 }
104
105 xmodel, _ := r.PrepareConfig(xlist, false)
106 if xmodel == nil {
107 appmgr.Logger.Error("Xapp not found, deleting it from DB")
108 r.rh.UpdateAppData(xlist, true)
109 }
110 }
111 }
112
Mohamed Abukar34e43832019-11-13 17:57:15 +0200113}
114
115func (r *Restful) SetupHandler() *operations.AppManagerAPI {
116 swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
117 if err != nil {
118 appmgr.Logger.Error(err.Error())
119 os.Exit(1)
120 }
121 api := operations.NewAppManagerAPI(swaggerSpec)
122
123 // URL: /ric/v1/health
124 api.HealthGetHealthAliveHandler = health.GetHealthAliveHandlerFunc(
125 func(params health.GetHealthAliveParams) middleware.Responder {
126 return health.NewGetHealthAliveOK()
127 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200128
wahidwd8726302020-12-13 17:34:29 +0000129 api.HealthGetHealthReadyHandler = health.GetHealthReadyHandlerFunc(
Mohamed Abukar34e43832019-11-13 17:57:15 +0200130 func(params health.GetHealthReadyParams) middleware.Responder {
131 return health.NewGetHealthReadyOK()
132 })
133
134 // URL: /ric/v1/subscriptions
135 api.GetSubscriptionsHandler = operations.GetSubscriptionsHandlerFunc(
136 func(params operations.GetSubscriptionsParams) middleware.Responder {
137 return operations.NewGetSubscriptionsOK().WithPayload(r.rh.GetAllSubscriptions())
138 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200139
Mohamed Abukar34e43832019-11-13 17:57:15 +0200140 api.GetSubscriptionByIDHandler = operations.GetSubscriptionByIDHandlerFunc(
141 func(params operations.GetSubscriptionByIDParams) middleware.Responder {
142 if result, found := r.rh.GetSubscriptionById(params.SubscriptionID); found {
143 return operations.NewGetSubscriptionByIDOK().WithPayload(&result)
144 }
145 return operations.NewGetSubscriptionByIDNotFound()
146 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200147
Mohamed Abukar34e43832019-11-13 17:57:15 +0200148 api.AddSubscriptionHandler = operations.AddSubscriptionHandlerFunc(
149 func(params operations.AddSubscriptionParams) middleware.Responder {
150 return operations.NewAddSubscriptionCreated().WithPayload(r.rh.AddSubscription(*params.SubscriptionRequest))
151 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200152
Mohamed Abukar34e43832019-11-13 17:57:15 +0200153 api.ModifySubscriptionHandler = operations.ModifySubscriptionHandlerFunc(
154 func(params operations.ModifySubscriptionParams) middleware.Responder {
155 if _, ok := r.rh.ModifySubscription(params.SubscriptionID, *params.SubscriptionRequest); ok {
156 return operations.NewModifySubscriptionOK()
157 }
158 return operations.NewModifySubscriptionBadRequest()
159 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200160
Mohamed Abukar34e43832019-11-13 17:57:15 +0200161 api.DeleteSubscriptionHandler = operations.DeleteSubscriptionHandlerFunc(
162 func(params operations.DeleteSubscriptionParams) middleware.Responder {
163 if _, ok := r.rh.DeleteSubscription(params.SubscriptionID); ok {
164 return operations.NewDeleteSubscriptionNoContent()
165 }
166 return operations.NewDeleteSubscriptionBadRequest()
167 })
168
169 // URL: /ric/v1/xapp
170 api.XappGetAllXappsHandler = xapp.GetAllXappsHandlerFunc(
171 func(params xapp.GetAllXappsParams) middleware.Responder {
wahidwd8726302020-12-13 17:34:29 +0000172 if result, err := r.GetApps(); err == nil {
Mohamed Abukar34e43832019-11-13 17:57:15 +0200173 return xapp.NewGetAllXappsOK().WithPayload(result)
174 }
175 return xapp.NewGetAllXappsInternalServerError()
176 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200177
wahidw78c892e2021-01-09 06:02:22 +0000178 // URL: /ric/v1/config
179 api.XappGetAllXappConfigHandler = xapp.GetAllXappConfigHandlerFunc(
180 func(params xapp.GetAllXappConfigParams) middleware.Responder {
181 return xapp.NewGetAllXappConfigOK().WithPayload(r.getAppConfig())
182 })
183
wahidwd8726302020-12-13 17:34:29 +0000184 api.RegisterXappHandler = operations.RegisterXappHandlerFunc(
185 func(params operations.RegisterXappParams) middleware.Responder {
186 appmgr.Logger.Info("appname is %s", (*params.RegisterRequest.AppName))
187 appmgr.Logger.Info("endpoint is %s", (*params.RegisterRequest.HTTPEndpoint))
188 appmgr.Logger.Info("rmrendpoint is %s", (*params.RegisterRequest.RmrEndpoint))
189 if result, err := r.RegisterXapp(*params.RegisterRequest); err == nil {
190 go r.rh.PublishSubscription(*result, models.EventTypeDeployed)
191 return operations.NewRegisterXappCreated()
Mohamed Abukar34e43832019-11-13 17:57:15 +0200192 }
wahidwd8726302020-12-13 17:34:29 +0000193 return operations.NewRegisterXappBadRequest()
Mohamed Abukar34e43832019-11-13 17:57:15 +0200194 })
Mohamed Abukaraca8f3c2020-01-14 11:10:16 +0200195
wahidwd8726302020-12-13 17:34:29 +0000196 api.DeregisterXappHandler = operations.DeregisterXappHandlerFunc(
197 func(params operations.DeregisterXappParams) middleware.Responder {
198 appmgr.Logger.Info("appname is %s", (*params.DeregisterRequest.AppName))
199 if result, err := r.DeregisterXapp(*params.DeregisterRequest); err == nil {
200 go r.rh.PublishSubscription(*result, models.EventTypeUndeployed)
201 return operations.NewDeregisterXappNoContent()
Mohamed Abukar34e43832019-11-13 17:57:15 +0200202 }
wahidwd8726302020-12-13 17:34:29 +0000203 return operations.NewDeregisterXappBadRequest()
Mohamed Abukar34e43832019-11-13 17:57:15 +0200204 })
Mohamed Abukar34e43832019-11-13 17:57:15 +0200205
206 return api
207}
208
wahidw78c892e2021-01-09 06:02:22 +0000209func httpGetXAppsconfig(url string) *string {
wahidwd8726302020-12-13 17:34:29 +0000210 appmgr.Logger.Info("Invoked httprestful.httpGetXApps: " + url)
211 resp, err := http.Get(url)
212 if err != nil {
wahidw03122b82021-06-02 14:30:35 +0000213 appmgr.Logger.Error("Error while querying config to Xapp: ", err.Error())
wahidw78c892e2021-01-09 06:02:22 +0000214 return nil
Mohamed Abukar34e43832019-11-13 17:57:15 +0200215 }
wahidwd8726302020-12-13 17:34:29 +0000216 defer resp.Body.Close()
Mohamed Abukar34e43832019-11-13 17:57:15 +0200217
wahidwd8726302020-12-13 17:34:29 +0000218 if resp.StatusCode == http.StatusOK {
219 var data XappConfigList
220 appmgr.Logger.Info("http client raw response: %v", resp)
221 if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
222 appmgr.Logger.Error("Json decode failed: " + err.Error())
wahidw78c892e2021-01-09 06:02:22 +0000223 return nil
Mohamed Abukar34e43832019-11-13 17:57:15 +0200224 }
wahidwd8726302020-12-13 17:34:29 +0000225 //data[0] assuming only for one app
226 str := fmt.Sprintf("%v", data[0].Config)
227 appmgr.Logger.Info("HTTP BODY: %v", str)
228
229 resp.Body.Close()
wahidw78c892e2021-01-09 06:02:22 +0000230 return &str
231 } else {
232 appmgr.Logger.Info("httprestful got an unexpected http status code: %v", resp.StatusCode)
233 return nil
234 }
235}
wahidwd8726302020-12-13 17:34:29 +0000236
wahidw78c892e2021-01-09 06:02:22 +0000237func parseConfig(config *string) *appmgr.RtmData {
238 var p fastjson.Parser
239 var msgs appmgr.RtmData
wahidwd8726302020-12-13 17:34:29 +0000240
wahidw78c892e2021-01-09 06:02:22 +0000241 v, err := p.Parse(*config)
242 if err != nil {
243 appmgr.Logger.Info("fastjson.Parser for failed: %v", err)
244 return nil
245 }
246
247 if v.Exists("rmr") {
248 for _, m := range v.GetArray("rmr", "txMessages") {
249 msgs.TxMessages = append(msgs.TxMessages, strings.Trim(m.String(), `"`))
wahidwd8726302020-12-13 17:34:29 +0000250 }
251
wahidw78c892e2021-01-09 06:02:22 +0000252 for _, m := range v.GetArray("rmr", "rxMessages") {
253 msgs.RxMessages = append(msgs.RxMessages, strings.Trim(m.String(), `"`))
254 }
255
256 for _, m := range v.GetArray("rmr", "policies") {
257 if val, err := strconv.Atoi(strings.Trim(m.String(), `"`)); err == nil {
258 msgs.Policies = append(msgs.Policies, int64(val))
259 }
260 }
261 } else {
262 for _, p := range v.GetArray("messaging", "ports") {
263 appmgr.Logger.Info("txMessages=%v, rxMessages=%v", p.GetArray("txMessages"), p.GetArray("rxMessages"))
264 for _, m := range p.GetArray("txMessages") {
wahidwd8726302020-12-13 17:34:29 +0000265 msgs.TxMessages = append(msgs.TxMessages, strings.Trim(m.String(), `"`))
266 }
267
wahidw78c892e2021-01-09 06:02:22 +0000268 for _, m := range p.GetArray("rxMessages") {
wahidwd8726302020-12-13 17:34:29 +0000269 msgs.RxMessages = append(msgs.RxMessages, strings.Trim(m.String(), `"`))
270 }
271
wahidw78c892e2021-01-09 06:02:22 +0000272 for _, m := range p.GetArray("policies") {
wahidwd8726302020-12-13 17:34:29 +0000273 if val, err := strconv.Atoi(strings.Trim(m.String(), `"`)); err == nil {
274 msgs.Policies = append(msgs.Policies, int64(val))
275 }
276 }
wahidwd8726302020-12-13 17:34:29 +0000277 }
wahidwd8726302020-12-13 17:34:29 +0000278 }
wahidw78c892e2021-01-09 06:02:22 +0000279 return &msgs
wahidwd8726302020-12-13 17:34:29 +0000280}
281
282func (r *Restful) RegisterXapp(params models.RegisterRequest) (xapp *models.Xapp, err error) {
283 return r.PrepareConfig(params, true)
284}
285
286func (r *Restful) DeregisterXapp(params models.DeregisterRequest) (xapp *models.Xapp, err error) {
287 var registeredlist models.RegisterRequest
288 registeredlist.AppName = params.AppName
289 registeredlist.AppInstanceName = params.AppInstanceName
290 if _, found := xappmap[*params.AppName]; found {
291 var x models.Xapp
292 x.Instances = append(x.Instances, xappmap[*params.AppName][*params.AppInstanceName].xappInstance)
293 registeredlist.HTTPEndpoint = &xappmap[*params.AppName][*params.AppInstanceName].httpendpoint
294 delete(xappmap[*params.AppName], *params.AppInstanceName)
295 if len(xappmap[*params.AppName]) == 0 {
296 delete(xappmap, *params.AppName)
297 }
298 r.rh.UpdateAppData(registeredlist, true)
299 return &x, nil
300 } else {
301 appmgr.Logger.Error("XApp Instance %v Not Found", *params.AppName)
302 return nil, errors.New("XApp Instance Not Found")
Mohamed Abukar34e43832019-11-13 17:57:15 +0200303 }
304}
305
wahidwd8726302020-12-13 17:34:29 +0000306func (r *Restful) PrepareConfig(params models.RegisterRequest, updateflag bool) (xapp *models.Xapp, err error) {
307 maxRetries := 5
wahidw382755b2021-01-18 13:00:57 +0000308 configPresent := false
309 var xappconfig *string
wahidwd8726302020-12-13 17:34:29 +0000310 appmgr.Logger.Info("http endpoint is %s", *params.HTTPEndpoint)
311 for i := 1; i <= maxRetries; i++ {
wahidw382755b2021-01-18 13:00:57 +0000312 if params.Config != "" {
313 appmgr.Logger.Info("Getting config during xapp register: %v", params.Config)
314 xappconfig = &params.Config
315 configPresent = true
316 } else {
317 appmgr.Logger.Info("Getting config from xapp:")
318 xappconfig = httpGetXAppsconfig(fmt.Sprintf("http://%s%s", *params.HTTPEndpoint, params.ConfigPath))
319 }
wahidwd8726302020-12-13 17:34:29 +0000320
wahidw78c892e2021-01-09 06:02:22 +0000321 if xappconfig != nil {
322 data := parseConfig(xappconfig)
323 if data != nil {
wahidw78c892e2021-01-09 06:02:22 +0000324 var xapp models.Xapp
wahidwd8726302020-12-13 17:34:29 +0000325
wahidw78c892e2021-01-09 06:02:22 +0000326 xapp.Name = params.AppName
327 xapp.Version = params.AppVersion
328 //xapp.Status = params.Status
wahidwd8726302020-12-13 17:34:29 +0000329
wahidw78c892e2021-01-09 06:02:22 +0000330 r.rh.UpdateAppData(params, updateflag)
wahidw382755b2021-01-18 13:00:57 +0000331 return r.FillInstanceData(params, &xapp, *data, configPresent)
wahidw78c892e2021-01-09 06:02:22 +0000332 break
333 } else {
wahidw382755b2021-01-18 13:00:57 +0000334 appmgr.Logger.Error("No Data from xapp")
335 }
336 if configPresent == true {
337 break
wahidw78c892e2021-01-09 06:02:22 +0000338 }
wahidwd8726302020-12-13 17:34:29 +0000339 }
wahidw03122b82021-06-02 14:30:35 +0000340 appmgr.Logger.Info("Retrying query configuration from xapp, try no : %d", i)
341 time.Sleep(4 * time.Second)
wahidwd8726302020-12-13 17:34:29 +0000342 }
wahidwd8726302020-12-13 17:34:29 +0000343 return nil, errors.New("Unable to get configmap after 5 retries")
344}
345
wahidw382755b2021-01-18 13:00:57 +0000346func (r *Restful) FillInstanceData(params models.RegisterRequest, xapp *models.Xapp, rtData appmgr.RtmData, configFlag bool) (xapps *models.Xapp, err error) {
wahidwd8726302020-12-13 17:34:29 +0000347
wahidwd8726302020-12-13 17:34:29 +0000348 endPointStr := strings.Split(*params.RmrEndpoint, ":")
349 var x models.XappInstance
350 x.Name = params.AppInstanceName
351 //x.Status = strings.ToLower(params.Status)
352 x.Status = "deployed"
wahidw78c892e2021-01-09 06:02:22 +0000353 //x.IP = endPointStr[0]
354 x.IP = fmt.Sprintf("service-ricxapp-%s-rmr.ricxapp", *params.AppInstanceName)
wahidwd8726302020-12-13 17:34:29 +0000355 x.Port, _ = strconv.ParseInt(endPointStr[1], 10, 64)
356 x.TxMessages = rtData.TxMessages
357 x.RxMessages = rtData.RxMessages
358 x.Policies = rtData.Policies
359 xapp.Instances = append(xapp.Instances, &x)
wahidw78c892e2021-01-09 06:02:22 +0000360 rmrsrvname := fmt.Sprintf("service-ricxapp-%s-rmr.ricxapp:%s", *params.AppInstanceName, x.Port)
wahidwd8726302020-12-13 17:34:29 +0000361
wahidw78c892e2021-01-09 06:02:22 +0000362 a := &XappData{httpendpoint: *params.HTTPEndpoint,
wahidw382755b2021-01-18 13:00:57 +0000363 rmrendpoint: *params.RmrEndpoint,
364 rmrserviceep: rmrsrvname,
365 status: "deployed",
366 xappname: *params.AppName,
367 xappversion: params.AppVersion,
368 xappinstname: *params.AppInstanceName,
369 xappconfigpath: params.ConfigPath,
370 xappdynamiconfig: configFlag,
371 xappInstance: &x}
wahidwd8726302020-12-13 17:34:29 +0000372
373 if _, ok := xappmap[*params.AppName]; ok {
374 xappmap[*params.AppName][*params.AppInstanceName] = a
375 appmgr.Logger.Info("appname already present, %v", xappmap[*params.AppName])
376 } else {
377 xappmap[*params.AppName] = make(map[string]*XappData)
378 xappmap[*params.AppName][*params.AppInstanceName] = a
379 appmgr.Logger.Info("Creating app instance, %v", xappmap[*params.AppName])
380 }
381
382 return xapp, nil
383
384}
385
386func (r *Restful) GetApps() (xapps models.AllDeployedXapps, err error) {
387 xapps = models.AllDeployedXapps{}
388 for _, v := range xappmap {
389 var x models.Xapp
390 for i, j := range v {
391 x.Status = j.status
392 x.Name = &j.xappname
393 x.Version = j.xappversion
394 appmgr.Logger.Info("Xapps details currently in map Appname = %v,rmrendpoint = %v,Status = %v", i, j.rmrendpoint, j.status)
395 x.Instances = append(x.Instances, j.xappInstance)
396 }
397 xapps = append(xapps, &x)
398 }
399
400 return xapps, nil
401
Mohamed Abukar34e43832019-11-13 17:57:15 +0200402}
wahidw78c892e2021-01-09 06:02:22 +0000403
404func (r *Restful) getAppConfig() (configList models.AllXappConfig) {
405 for _, v := range xappmap {
wahidw382755b2021-01-18 13:00:57 +0000406 namespace := "ricxapp" //Namespace hardcoded, to be removed later
wahidw78c892e2021-01-09 06:02:22 +0000407 for _, j := range v {
408 var activeConfig interface{}
wahidw382755b2021-01-18 13:00:57 +0000409 if j.xappdynamiconfig {
410 continue
411 }
wahidw78c892e2021-01-09 06:02:22 +0000412 xappconfig := httpGetXAppsconfig(fmt.Sprintf("http://%s%s", j.httpendpoint, j.xappconfigpath))
413
414 if xappconfig == nil {
415 appmgr.Logger.Info("config not found for %s", &j.xappname)
416 continue
417 }
418 json.Unmarshal([]byte(*xappconfig), &activeConfig)
419
420 c := models.XAppConfig{
421 Metadata: &models.ConfigMetadata{XappName: &j.xappname, Namespace: &namespace},
422 Config: activeConfig,
423 }
424 configList = append(configList, &c)
425
426 }
427
428 }
429 return
430}
Abukar Mohamed21fd77f2021-03-11 12:59:02 +0000431
432func (r *Restful) symptomdataServer() {
433 http.HandleFunc("/ric/v1/symptomdata", func(w http.ResponseWriter, req *http.Request) {
434 d, _ := r.GetApps()
435 xappData := struct {
wahidw03122b82021-06-02 14:30:35 +0000436 XappList models.AllDeployedXapps `json:"xappList"`
437 ConfigList models.AllXappConfig `json:"configList"`
438 SubscriptionList models.AllSubscriptions `json:"subscriptionList"`
Abukar Mohamed21fd77f2021-03-11 12:59:02 +0000439 }{
440 d,
441 r.getAppConfig(),
442 r.rh.GetAllSubscriptions(),
443 }
444
445 w.Header().Set("Content-Type", "application/json")
446 w.Header().Set("Content-Disposition", "attachment; filename=platform/apps_info.json")
447 w.WriteHeader(http.StatusOK)
448 resp, _ := json.MarshalIndent(xappData, "", " ")
449 w.Write(resp)
450 })
451
452 http.ListenAndServe(":8081", nil)
453}