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