import (
"encoding/json"
+ "errors"
"github.com/gorilla/mux"
"github.com/spf13/viper"
"log"
"net/http"
+ "time"
)
// API functions
-func (m *XappManager) Initialize(h Helmer) {
- /*
- m.sd = SubscriptionDispatcher{}
- m.sd.Initialize()
- m.helm = h
- m.helm.Initialize()
- */
+func (m *XappManager) Initialize(h Helmer, cm ConfigMapper) {
+ m.cm = cm
+ m.helm = h
+ m.helm.SetCM(cm)
+
m.router = mux.NewRouter().StrictSlash(true)
resources := []Resource{
{"GET", "/ric/v1/health/ready", m.getHealthStatus},
{"GET", "/ric/v1/xapps", m.getAllXapps},
+ {"GET", "/ric/v1/xapps/search", m.searchAllXapps},
{"GET", "/ric/v1/xapps/{name}", m.getXappByName},
{"GET", "/ric/v1/xapps/{name}/instances/{id}", m.getXappInstanceByName},
{"POST", "/ric/v1/xapps", m.deployXapp},
{"GET", "/ric/v1/subscriptions/{id}", m.getSubscription},
{"DELETE", "/ric/v1/subscriptions/{id}", m.deleteSubscription},
{"PUT", "/ric/v1/subscriptions/{id}", m.updateSubscription},
+
+ {"GET", "/ric/v1/config", m.getConfig},
+ {"POST", "/ric/v1/config", m.createConfig},
+ {"PUT", "/ric/v1/config", m.updateConfig},
+ {"DELETE", "/ric/v1/config", m.deleteConfig},
+ {"DELETE", "/ric/v1/config/{name}", m.deleteSingleConfig},
}
for _, resource := range resources {
- handler := Logger(resource.HandlerFunc)
+ handler := LogRestRequests(resource.HandlerFunc)
//handler = m.serviceChecker(handler)
m.router.Methods(resource.Method).Path(resource.Url).Handler(handler)
}
m.sd = SubscriptionDispatcher{}
m.sd.Initialize()
- m.helm = h
m.helm.Initialize()
m.notifyClients()
return
}
}
- mdclog(MdclogErr, "Xapp instance not found - url="+r.URL.RequestURI())
+ Logger.Error("Xapp instance not found - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusNotFound, "Xapp instance not found")
}
respondWithJSON(w, http.StatusOK, xapps)
}
+func (m *XappManager) searchAllXapps(w http.ResponseWriter, r *http.Request) {
+ respondWithJSON(w, http.StatusOK, m.helm.SearchAll())
+}
+
func (m *XappManager) deployXapp(w http.ResponseWriter, r *http.Request) {
if r.Body == nil {
- mdclog(MdclogErr, "No xapp data found in request body - url="+r.URL.RequestURI())
+ Logger.Error("No xapp data found in request body - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusMethodNotAllowed, "No xapp data!")
return
}
- var xapp Xapp
- if err := json.NewDecoder(r.Body).Decode(&xapp); err != nil {
- mdclog(MdclogErr, "Invalid xapp data in request body - url="+r.URL.RequestURI())
+ var cm XappDeploy
+ if err := json.NewDecoder(r.Body).Decode(&cm); err != nil {
+ Logger.Error("Invalid xapp data in request body - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusMethodNotAllowed, "Invalid xapp data!")
return
}
defer r.Body.Close()
- xapp, err := m.helm.Install(xapp.Name)
+ xapp, err := m.helm.Install(cm)
if err != nil {
respondWithError(w, http.StatusInternalServerError, err.Error())
return
}
+ for i := 0; i < 3; i++ {
+ if xapp, err = m.helm.Status(xapp.Name); xapp.Instances != nil {
+ break
+ }
+ time.Sleep(time.Duration(5) * time.Second)
+ }
+
respondWithJSON(w, http.StatusCreated, xapp)
m.sd.Publish(xapp, EventType("created"))
if s, ok := m.sd.Get(id); ok {
respondWithJSON(w, http.StatusOK, s)
} else {
- mdclog(MdclogErr, "Subscription not found - url="+r.URL.RequestURI())
+ Logger.Error("Subscription not found - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusNotFound, "Subscription not found")
}
}
if _, ok := m.sd.Delete(id); ok {
respondWithJSON(w, http.StatusNoContent, nil)
} else {
- mdclog(MdclogErr, "Subscription not found - url="+r.URL.RequestURI())
+ Logger.Error("Subscription not found - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusNotFound, "Subscription not found")
}
}
func (m *XappManager) addSubscription(w http.ResponseWriter, r *http.Request) {
var req SubscriptionReq
if r.Body == nil || json.NewDecoder(r.Body).Decode(&req) != nil {
- mdclog(MdclogErr, "Invalid request payload - url="+r.URL.RequestURI())
+ Logger.Error("Invalid request payload - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusMethodNotAllowed, "Invalid request payload")
return
}
if id, ok := getResourceId(r, w, "id"); ok == true {
var req SubscriptionReq
if r.Body == nil || json.NewDecoder(r.Body).Decode(&req) != nil {
- mdclog(MdclogErr, "Invalid request payload - url="+r.URL.RequestURI())
+ Logger.Error("Invalid request payload - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusMethodNotAllowed, "Invalid request payload")
return
}
if s, ok := m.sd.Update(id, req); ok {
respondWithJSON(w, http.StatusOK, s)
} else {
- mdclog(MdclogErr, "Subscription not found - url="+r.URL.RequestURI())
+ Logger.Error("Subscription not found - url=%s", r.URL.RequestURI())
respondWithError(w, http.StatusNotFound, "Subscription not found")
}
}
func (m *XappManager) notifyClients() {
xapps, err := m.helm.StatusAll()
if err != nil {
- mdclog(MdclogInfo, "Couldn't fetch xapps status information"+err.Error())
+ Logger.Info("Couldn't fetch xapps status information: %v", err.Error())
return
}
m.sd.notifyClients(xapps, "updated")
}
+func (m *XappManager) getConfig(w http.ResponseWriter, r *http.Request) {
+ cfg := m.cm.UploadConfig()
+ respondWithJSON(w, http.StatusOK, cfg)
+}
+
+func (m *XappManager) createConfig(w http.ResponseWriter, r *http.Request) {
+ var c XAppConfig
+ if parseConfig(w, r, &c) != nil {
+ return
+ }
+
+ if errList, err := m.cm.CreateConfigMap(c); err != nil {
+ if err.Error() != "Validation failed!" {
+ respondWithError(w, http.StatusInternalServerError, err.Error())
+ } else {
+ respondWithJSON(w, http.StatusUnprocessableEntity, errList)
+ }
+ return
+ }
+ respondWithJSON(w, http.StatusCreated, c.Metadata)
+}
+
+func (m *XappManager) updateConfig(w http.ResponseWriter, r *http.Request) {
+ var c XAppConfig
+ if parseConfig(w, r, &c) != nil {
+ return
+ }
+
+ if errList, err := m.cm.UpdateConfigMap(c); err != nil {
+ if err.Error() != "Validation failed!" {
+ respondWithError(w, http.StatusInternalServerError, err.Error())
+ } else {
+ respondWithJSON(w, http.StatusInternalServerError, errList)
+ }
+ return
+ }
+ respondWithJSON(w, http.StatusOK, c.Metadata)
+}
+
+func (m *XappManager) deleteSingleConfig(w http.ResponseWriter, r *http.Request) {
+ xappName, ok := getResourceId(r, w, "name")
+ if ok != true {
+ return
+ }
+
+ md := ConfigMetadata{Name: xappName, Namespace: m.cm.GetNamespace(""), ConfigName: xappName + "-appconfig"}
+ m.delConfig(w, XAppConfig{Metadata: md})
+}
+
+func (m *XappManager) deleteConfig(w http.ResponseWriter, r *http.Request) {
+ var c XAppConfig
+ if parseConfig(w, r, &c) != nil {
+ return
+ }
+
+ m.delConfig(w, c)
+}
+
+func (m *XappManager) delConfig(w http.ResponseWriter, c XAppConfig) {
+ if _, err := m.cm.DeleteConfigMap(c); err != nil {
+ respondWithError(w, http.StatusInternalServerError, err.Error())
+ return
+ }
+ respondWithJSON(w, http.StatusNoContent, nil)
+}
+
// Helper functions
func respondWithError(w http.ResponseWriter, code int, message string) {
respondWithJSON(w, code, map[string]string{"error": message})
func getResourceId(r *http.Request, w http.ResponseWriter, pattern string) (id string, ok bool) {
if id, ok = mux.Vars(r)[pattern]; ok != true {
- mdclog(MdclogErr, "Couldn't resolve name/id from the request URL")
+ Logger.Error("Couldn't resolve name/id from the request URL")
respondWithError(w, http.StatusMethodNotAllowed, "Couldn't resolve name/id from the request URL")
return
}
return
}
+
+func parseConfig(w http.ResponseWriter, r *http.Request, req *XAppConfig) error {
+ if r.Body == nil || json.NewDecoder(r.Body).Decode(&req) != nil {
+ Logger.Error("Invalid request payload - url=%s", r.URL.RequestURI())
+ respondWithError(w, http.StatusMethodNotAllowed, "Invalid request payload")
+ return errors.New("Invalid payload")
+ }
+ defer r.Body.Close()
+
+ return nil
+}