Enhance config handling
[ric-plt/appmgr.git] / pkg / restful / restful.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 package restful
21
22 import (
23         "log"
24         "os"
25         "time"
26
27         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/models"
28         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/restapi"
29         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/restapi/operations"
30         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/restapi/operations/health"
31         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/restapi/operations/xapp"
32         "github.com/go-openapi/loads"
33         "github.com/go-openapi/runtime/middleware"
34
35         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/appmgr"
36         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/cm"
37         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/helm"
38         "gerrit.oran-osc.org/r/ric-plt/appmgr/pkg/resthooks"
39 )
40
41 func NewRestful() *Restful {
42         r := &Restful{
43                 helm:  helm.NewHelm(),
44                 cm:    cm.NewCM(),
45                 rh:    resthooks.NewResthook(true),
46                 ready: false,
47         }
48         r.api = r.SetupHandler()
49         return r
50 }
51
52 func (r *Restful) Run() {
53         server := restapi.NewServer(r.api)
54         defer server.Shutdown()
55         server.Port = 8080
56         server.Host = "0.0.0.0"
57
58         appmgr.Logger.Info("Xapp manager started ... serving on %s:%d\n", server.Host, server.Port)
59
60         go r.NotifyClients()
61         if err := server.Serve(); err != nil {
62                 log.Fatal(err.Error())
63         }
64 }
65
66 func (r *Restful) SetupHandler() *operations.AppManagerAPI {
67         swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
68         if err != nil {
69                 appmgr.Logger.Error(err.Error())
70                 os.Exit(1)
71         }
72         api := operations.NewAppManagerAPI(swaggerSpec)
73
74         // URL: /ric/v1/health
75         api.HealthGetHealthAliveHandler = health.GetHealthAliveHandlerFunc(
76                 func(params health.GetHealthAliveParams) middleware.Responder {
77                         return health.NewGetHealthAliveOK()
78                 })
79
80                 api.HealthGetHealthReadyHandler = health.GetHealthReadyHandlerFunc(
81                 func(params health.GetHealthReadyParams) middleware.Responder {
82                         return health.NewGetHealthReadyOK()
83                 })
84
85         // URL: /ric/v1/subscriptions
86         api.GetSubscriptionsHandler = operations.GetSubscriptionsHandlerFunc(
87                 func(params operations.GetSubscriptionsParams) middleware.Responder {
88                         return operations.NewGetSubscriptionsOK().WithPayload(r.rh.GetAllSubscriptions())
89                 })
90
91         api.GetSubscriptionByIDHandler = operations.GetSubscriptionByIDHandlerFunc(
92                 func(params operations.GetSubscriptionByIDParams) middleware.Responder {
93                         if result, found := r.rh.GetSubscriptionById(params.SubscriptionID); found {
94                                 return operations.NewGetSubscriptionByIDOK().WithPayload(&result)
95                         }
96                         return operations.NewGetSubscriptionByIDNotFound()
97                 })
98
99         api.AddSubscriptionHandler = operations.AddSubscriptionHandlerFunc(
100                 func(params operations.AddSubscriptionParams) middleware.Responder {
101                         return operations.NewAddSubscriptionCreated().WithPayload(r.rh.AddSubscription(*params.SubscriptionRequest))
102                 })
103
104         api.ModifySubscriptionHandler = operations.ModifySubscriptionHandlerFunc(
105                 func(params operations.ModifySubscriptionParams) middleware.Responder {
106                         if _, ok := r.rh.ModifySubscription(params.SubscriptionID, *params.SubscriptionRequest); ok {
107                                 return operations.NewModifySubscriptionOK()
108                         }
109                         return operations.NewModifySubscriptionBadRequest()
110                 })
111
112         api.DeleteSubscriptionHandler = operations.DeleteSubscriptionHandlerFunc(
113                 func(params operations.DeleteSubscriptionParams) middleware.Responder {
114                         if _, ok := r.rh.DeleteSubscription(params.SubscriptionID); ok {
115                                 return operations.NewDeleteSubscriptionNoContent()
116                         }
117                         return operations.NewDeleteSubscriptionBadRequest()
118                 })
119
120         // URL: /ric/v1/xapp
121         api.XappGetAllXappsHandler = xapp.GetAllXappsHandlerFunc(
122                 func(params xapp.GetAllXappsParams) middleware.Responder {
123                         if result, err := r.helm.StatusAll(); err == nil {
124                                 return xapp.NewGetAllXappsOK().WithPayload(result)
125                         }
126                         return xapp.NewGetAllXappsInternalServerError()
127                 })
128
129         api.XappListAllXappsHandler = xapp.ListAllXappsHandlerFunc(
130                 func(params xapp.ListAllXappsParams) middleware.Responder {
131                         if result := r.helm.SearchAll(); err == nil {
132                                 return xapp.NewListAllXappsOK().WithPayload(result)
133                         }
134                         return xapp.NewListAllXappsInternalServerError()
135                 })
136
137         api.XappGetXappByNameHandler = xapp.GetXappByNameHandlerFunc(
138                 func(params xapp.GetXappByNameParams) middleware.Responder {
139                         if result, err := r.helm.Status(params.XAppName); err == nil {
140                                 return xapp.NewGetXappByNameOK().WithPayload(&result)
141                         }
142                         return xapp.NewGetXappByNameNotFound()
143                 })
144
145         api.XappGetXappInstanceByNameHandler = xapp.GetXappInstanceByNameHandlerFunc(
146                 func(params xapp.GetXappInstanceByNameParams) middleware.Responder {
147                         if result, err := r.helm.Status(params.XAppName); err == nil {
148                                 for _, v := range result.Instances {
149                                         if *v.Name == params.XAppInstanceName {
150                                                 return xapp.NewGetXappInstanceByNameOK().WithPayload(v)
151                                         }
152                                 }
153                         }
154                         return xapp.NewGetXappInstanceByNameNotFound()
155                 })
156
157         api.XappDeployXappHandler = xapp.DeployXappHandlerFunc(
158                 func(params xapp.DeployXappParams) middleware.Responder {
159                         if result, err := r.helm.Install(*params.XappDescriptor); err == nil {
160                                 go r.PublishXappCreateEvent(params)
161                                 return xapp.NewDeployXappCreated().WithPayload(&result)
162                         }
163                         return xapp.NewUndeployXappInternalServerError()
164                 })
165
166         api.XappUndeployXappHandler = xapp.UndeployXappHandlerFunc(
167                 func(params xapp.UndeployXappParams) middleware.Responder {
168                         if result, err := r.helm.Delete(params.XAppName); err == nil {
169                                 go r.PublishXappDeleteEvent(result)
170                                 return xapp.NewUndeployXappNoContent()
171                         }
172                         return xapp.NewUndeployXappInternalServerError()
173                 })
174
175         // URL: /ric/v1/config
176         api.XappGetAllXappConfigHandler = xapp.GetAllXappConfigHandlerFunc(
177                 func(params xapp.GetAllXappConfigParams) middleware.Responder {
178                         return xapp.NewGetAllXappConfigOK().WithPayload(r.cm.UploadConfigAll())
179                 })
180
181         api.XappGetConfigElementHandler = xapp.GetConfigElementHandlerFunc(
182                 func(params xapp.GetConfigElementParams) middleware.Responder {
183                         return xapp.NewGetConfigElementOK().WithPayload(r.cm.UploadConfigElement(params.Element))
184                 })
185
186         api.XappModifyXappConfigHandler = xapp.ModifyXappConfigHandlerFunc(
187                 func(params xapp.ModifyXappConfigParams) middleware.Responder {
188                         result, err := r.cm.UpdateConfigMap(*params.XAppConfig)
189                         if err != nil {
190                                 if err.Error() != "Validation failed!" {
191                                         return xapp.NewModifyXappConfigInternalServerError()
192                                 } else {
193                                         return xapp.NewModifyXappConfigUnprocessableEntity()
194                                 }
195                         }
196                         r.rh.PublishSubscription(models.Xapp{}, models.EventTypeModified)
197                         return xapp.NewModifyXappConfigOK().WithPayload(result)
198                 })
199
200         return api
201 }
202
203 func (r *Restful) NotifyClients() {
204         r.helm.Initialize()
205         if xapps, err := r.helm.StatusAll(); err == nil {
206                 r.rh.NotifyClients(xapps, models.EventTypeRestarted)
207                 r.ready = true
208         }
209 }
210
211 func (r *Restful) PublishXappCreateEvent(params xapp.DeployXappParams) {
212         name := *params.XappDescriptor.XappName
213         if params.XappDescriptor.ReleaseName != "" {
214                 name = params.XappDescriptor.ReleaseName
215         }
216
217         for i := 0; i < 5; i++ {
218                 time.Sleep(time.Duration(5) * time.Second)
219                 if result, _ := r.helm.Status(name); result.Instances != nil {
220                         r.rh.PublishSubscription(result, models.EventTypeDeployed)
221                         break
222                 }
223         }
224 }
225
226 func (r *Restful) PublishXappDeleteEvent(xapp models.Xapp) {
227         r.rh.PublishSubscription(xapp, models.EventTypeUndeployed)
228 }