/* * Copyright 2020 Intel Corporation, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governinog permissions and * limitations under the License. */ package module import ( "encoding/json" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db" pkgerrors "github.com/pkg/errors" ) // App contains metadata for Apps type App struct { Metadata AppMetaData `json:"metadata"` } //AppMetaData contains the parameters needed for Apps type AppMetaData struct { Name string `json:"name"` Description string `json:"description"` UserData1 string `json:"userData1"` UserData2 string `json:"userData2"` } //AppContent contains fileContent type AppContent struct { FileContent string } // AppKey is the key structure that is used in the database type AppKey struct { App string `json:"app"` Project string `json:"project"` CompositeApp string `json:"compositeapp"` CompositeAppVersion string `json:"compositeappversion"` } // We will use json marshalling to convert to string to // preserve the underlying structure. func (aK AppKey) String() string { out, err := json.Marshal(aK) if err != nil { return "" } return string(out) } // AppManager is an interface exposes the App functionality type AppManager interface { CreateApp(a App, ac AppContent, p string, cN string, cV string) (App, error) GetApp(name string, p string, cN string, cV string) (App, error) GetAppContent(name string, p string, cN string, cV string) (AppContent, error) GetApps(p string, cN string, cV string) ([]App, error) DeleteApp(name string, p string, cN string, cV string) error } // AppClient implements the AppManager // It will also be used to maintain some localized state type AppClient struct { storeName string tagMeta, tagContent string } // NewAppClient returns an instance of the AppClient // which implements the AppManager func NewAppClient() *AppClient { return &AppClient{ storeName: "orchestrator", tagMeta: "appmetadata", tagContent: "appcontent", } } // CreateApp creates a new collection based on the App func (v *AppClient) CreateApp(a App, ac AppContent, p string, cN string, cV string) (App, error) { //Construct the composite key to select the entry key := AppKey{ App: a.Metadata.Name, Project: p, CompositeApp: cN, CompositeAppVersion: cV, } //Check if this App already exists _, err := v.GetApp(a.Metadata.Name, p, cN, cV) if err == nil { return App{}, pkgerrors.New("App already exists") } //Check if Project exists _, err = NewProjectClient().GetProject(p) if err != nil { return App{}, pkgerrors.New("Unable to find the project") } //check if CompositeApp with version exists _, err = NewCompositeAppClient().GetCompositeApp(cN, cV, p) if err != nil { return App{}, pkgerrors.New("Unable to find the composite app with version") } err = db.DBconn.Insert(v.storeName, key, nil, v.tagMeta, a) if err != nil { return App{}, pkgerrors.Wrap(err, "Creating DB Entry") } err = db.DBconn.Insert(v.storeName, key, nil, v.tagContent, ac) if err != nil { return App{}, pkgerrors.Wrap(err, "Creating DB Entry") } return a, nil } // GetApp returns the App for corresponding name func (v *AppClient) GetApp(name string, p string, cN string, cV string) (App, error) { //Construct the composite key to select the entry key := AppKey{ App: name, Project: p, CompositeApp: cN, CompositeAppVersion: cV, } value, err := db.DBconn.Find(v.storeName, key, v.tagMeta) if err != nil { return App{}, pkgerrors.Wrap(err, "Get app") } //value is a byte array if value != nil { app := App{} err = db.DBconn.Unmarshal(value[0], &app) if err != nil { return App{}, pkgerrors.Wrap(err, "Unmarshaling Value") } return app, nil } return App{}, pkgerrors.New("Error getting app") } // GetAppContent returns content for corresponding app func (v *AppClient) GetAppContent(name string, p string, cN string, cV string) (AppContent, error) { //Construct the composite key to select the entry key := AppKey{ App: name, Project: p, CompositeApp: cN, CompositeAppVersion: cV, } value, err := db.DBconn.Find(v.storeName, key, v.tagContent) if err != nil { return AppContent{}, pkgerrors.Wrap(err, "Get app content") } //value is a byte array if value != nil { ac := AppContent{} err = db.DBconn.Unmarshal(value[0], &ac) if err != nil { return AppContent{}, pkgerrors.Wrap(err, "Unmarshaling Value") } return ac, nil } return AppContent{}, pkgerrors.New("Error getting app content") } // GetApps returns all Apps for given composite App func (v *AppClient) GetApps(project, compositeApp, compositeAppVersion string) ([]App, error) { key := AppKey{ App: "", Project: project, CompositeApp: compositeApp, CompositeAppVersion: compositeAppVersion, } var resp []App values, err := db.DBconn.Find(v.storeName, key, v.tagMeta) if err != nil { return []App{}, pkgerrors.Wrap(err, "Get Apps") } for _, value := range values { a := App{} err = db.DBconn.Unmarshal(value, &a) if err != nil { return []App{}, pkgerrors.Wrap(err, "Unmarshaling Value") } resp = append(resp, a) } return resp, nil } // DeleteApp deletes the App from database func (v *AppClient) DeleteApp(name string, p string, cN string, cV string) error { //Construct the composite key to select the entry key := AppKey{ App: name, Project: p, CompositeApp: cN, CompositeAppVersion: cV, } err := db.DBconn.Remove(v.storeName, key) if err != nil { return pkgerrors.Wrap(err, "Delete App Entry;") } return nil }