From: shashikanth.vh@huawei.com Date: Tue, 12 May 2020 05:36:14 +0000 (+0530) Subject: mepm applcm initial code X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=973e68c113a84f5041406219dd87c0f7778ba0fe;p=ealt-edge.git mepm applcm initial code Change-Id: I24b751ed3a7881d3a8d234876520b04b889be483 --- diff --git a/mecm/mepm/applcm/broker/build/Dockerfile b/mecm/mepm/applcm/broker/build/Dockerfile new file mode 100644 index 0000000..8a7e2ae --- /dev/null +++ b/mecm/mepm/applcm/broker/build/Dockerfile @@ -0,0 +1,42 @@ +# Copyright 2020 Huawei Technologies Co., Ltd. +# +# 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 governing permissions and +# limitations under the License. + +FROM golang:1.13.4-alpine3.10 + +ENV GOPROXY https://goproxy.io +ENV GO111MODULE on + +RUN apk update && apk upgrade && \ + apk add --no-cache bash git openssh + +WORKDIR /go/cache + +ADD go.mod . +ADD go.sum . +RUN go mod download + +WORKDIR /go/release +RUN mkdir -p /go/release/application/packages + +ADD . . + +RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -installsuffix cgo -o app cmd/broker/main.go + +RUN cp app start.sh / + +EXPOSE 8081 + +CMD ["/start.sh"] + + diff --git a/mecm/mepm/applcm/broker/cmd/broker/main.go b/mecm/mepm/applcm/broker/cmd/broker/main.go new file mode 100644 index 0000000..6a96500 --- /dev/null +++ b/mecm/mepm/applcm/broker/cmd/broker/main.go @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package main + +import ( + "broker/pkg/handlers" + "log" + "os" +) +/* +var ( + GcukCertFile = os.Getenv("GCUK_CERT_FILE") + GcukKeyFile = os.Getenv("GCUK_KEY_FILE") + GcukServiceAddr = os.Getenv("GCUK_SERVICE_ADDR") +)*/ + +func main() { + logger := log.New(os.Stdout, "broker ", log.LstdFlags|log.Lshortfile) + + handler := &handlers.Handlers{} + handler.Initialize(logger) + //handler.Run("127.0.0.1:8081") + handler.Run("0.0.0.0:8081") +} diff --git a/mecm/mepm/applcm/broker/docker-build.sh b/mecm/mepm/applcm/broker/docker-build.sh new file mode 100755 index 0000000..6f6bf8b --- /dev/null +++ b/mecm/mepm/applcm/broker/docker-build.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Copyright 2020 Huawei Technologies Co., Ltd. +# +# 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 governing permissions and +# limitations under the License. + +MEP_VERSION=latest +docker build --no-cache -t ealtedge/applcm-broker:${MEP_VERSION} -f build/Dockerfile . diff --git a/mecm/mepm/applcm/broker/go.mod b/mecm/mepm/applcm/broker/go.mod index 235d5a0..dd82bd7 100644 --- a/mecm/mepm/applcm/broker/go.mod +++ b/mecm/mepm/applcm/broker/go.mod @@ -9,6 +9,7 @@ require ( github.com/golang/protobuf v1.4.0 github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 + github.com/jinzhu/gorm v1.9.12 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect golang.org/x/net v0.0.0-20200506145744-7e3656a0809f golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect diff --git a/mecm/mepm/applcm/broker/go.sum b/mecm/mepm/applcm/broker/go.sum index b43094c..d938512 100644 --- a/mecm/mepm/applcm/broker/go.sum +++ b/mecm/mepm/applcm/broker/go.sum @@ -5,13 +5,19 @@ github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13/go.mod h1:tgcrVJ8 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -27,13 +33,24 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q= +github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -42,6 +59,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -50,6 +68,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= @@ -58,6 +77,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/mecm/mepm/applcm/broker/pkg/handlers/adapter/dbAdapter/dbAdapter.go b/mecm/mepm/applcm/broker/pkg/handlers/adapter/dbAdapter/dbAdapter.go new file mode 100644 index 0000000..2e527ec --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/adapter/dbAdapter/dbAdapter.go @@ -0,0 +1,98 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package dbAdapter + +import ( + "broker/pkg/handlers/model" + "fmt" + "github.com/jinzhu/gorm" + "net/http" +) + +func InsertAppInstanceInfo(db *gorm.DB, n model.AppInstanceInfo) { + fmt.Printf("Insert App Instance Info (%v, %T)\n", n, n) + db.Create(&model.AppInstanceInfo{ID: n.ID, AppInstanceName: n.AppInstanceName, AppInstanceDescription: n.AppInstanceDescription, + AppDID: n.AppDID, AppProvider: n.AppProvider, AppName: n.AppName, AppSoftVersion: n.AppSoftVersion, AppDVersion: n.AppDVersion, AppPkgID: n.AppPkgID, InstantiationState: n.InstantiationState}) + + fmt.Printf("Inserting Done") +} + +func GetAppInstanceInfo(db *gorm.DB, key string) (appInstInfo model.AppInstanceInfo) { + fmt.Printf("Get App Instance Info %s", key) + var appInstanceInfo model.AppInstanceInfo + returnVal := db.First(&appInstanceInfo, "id=?", key).Error + if returnVal != nil { + return + } + + return appInstanceInfo +} + +func UpdateAppInstanceInfoInstStatusHostAndWorkloadId(db *gorm.DB, id string, instantiationState string, host string, workloadId string) { + fmt.Printf("update into DB (%v, %T)\n", id, instantiationState, host, workloadId) + + var appInstInfo model.AppInstanceInfo + db.Where("id=?", id).First(&appInstInfo).Update("instantiationState", instantiationState).Update("host", host).Update("workloadID", workloadId) + fmt.Printf("AppName: %s\nAppDID: %s\nAppInstanceDescription:%t\n\n", + appInstInfo.AppName, appInstInfo.AppDID, appInstInfo.AppInstanceDescription) + + fmt.Printf("Update Done") +} + +func UpdateAppInstanceInfoInstStatusAndWorkload(db *gorm.DB, id string, instantiationState string, workloadId string) { + fmt.Printf("update DB (%v, %T)\n", id, instantiationState) + + var appInstInfo model.AppInstanceInfo + db.Where("id=?", id).First(&appInstInfo).Update("instantiationState", instantiationState).Update("workloadID", workloadId) + fmt.Printf("AppName: %s\nAppDID: %s\nAppInstanceDescription:%t\n\n", + appInstInfo.AppName, appInstInfo.AppDID, appInstInfo.AppInstanceDescription) + fmt.Printf("Update Done") +} + +func UpdateAppInstanceInfoHost(db *gorm.DB, w http.ResponseWriter, id string, host string) { +} + +func DeleteAppInstanceInfo(db *gorm.DB, key string) { + + db.Where("id=?", key).Delete(&model.AppInstanceInfo{}) + + fmt.Println("Delete App Instance Info: $s", key) +} + +func InsertAppPackageInfo(db *gorm.DB, n model.AppPackageInfo) { + fmt.Printf("Insert App Package Info (%v, %T)\n", n, n) + db.Create(&model.AppPackageInfo{ID: n.ID, AppDID: n.AppDID, AppProvider: n.AppProvider, + AppName: n.AppName, AppSoftwareVersion: n.AppSoftwareVersion, AppDVersion: n.AppDVersion, + OnboardingState: n.OnboardingState, DeployType: n.DeployType, AppPackage: n.AppPackage}) + + fmt.Printf("Inserting done") +} + +func GetAppPackageInfo(db *gorm.DB, key string) (appPackageInfo model.AppPackageInfo) { + fmt.Printf("Get App Package Info: %s", key) + var appPkgInfo model.AppPackageInfo + err := db.First(&appPkgInfo, "id=?", key).Error + if err != nil { + return + } + return appPkgInfo +} + +func DeleteAppPackageInfo(db *gorm.DB, key string) { + fmt.Printf("Delete App Package Info: %s", key) + db.Where("id=?", key).Delete(&model.AppPackageInfo{}) + fmt.Println("Delete App Package Info: $s", key) +} diff --git a/mecm/mepm/applcm/broker/pkg/handlers/adapter/pluginAdapter/pluginAdapter.go b/mecm/mepm/applcm/broker/pkg/handlers/adapter/pluginAdapter/pluginAdapter.go new file mode 100644 index 0000000..d3707f0 --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/adapter/pluginAdapter/pluginAdapter.go @@ -0,0 +1,98 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package pluginAdapter + +import ( + "broker/pkg/plugin" + "context" + "log" + "os" + "time" +) + +func Instantiate(pluginInfo string, host string, deployArtifact string) (workloadId string, error error) { + logger := log.New(os.Stdout, "broker ", log.LstdFlags|log.Lshortfile) + clientConfig := plugin.ClientGRPCConfig{Address: pluginInfo, ChunkSize: 1024, RootCertificate: ""} + var client, err = plugin.NewClientGRPC(clientConfig) + if err != nil { + logger.Fatalf("failed to create client: %v", err) + return "", err + } + log.Printf("pluginInfo: ", pluginInfo) + log.Printf("host: ", host) + log.Printf("deployArtifact: ", deployArtifact) + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Second) + defer cancel() + + //Instantiate + workloadId, status, err := client.Instantiate(ctx, deployArtifact, host) + if err != nil { + logger.Println("server failed to respond %s", err.Error()) + } else { + logger.Println(workloadId, status) + return workloadId, nil + } + return "", err +} + +func Query(pluginInfo string, host string, workloadId string) (status string, error error) { + logger := log.New(os.Stdout, "broker ", log.LstdFlags|log.Lshortfile) + clientConfig := plugin.ClientGRPCConfig{Address: pluginInfo, ChunkSize: 1024, RootCertificate: ""} + var client, err = plugin.NewClientGRPC(clientConfig) + if err != nil { + logger.Fatalf("failed to create client: %v", err) + return "", err + } + log.Printf("pluginInfo: ", pluginInfo) + log.Printf("host: ", host) + log.Printf("workloadId: ", workloadId) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + //Query + stats := client.Query(ctx, host, workloadId) + if err != nil { + logger.Fatalf("failed to instantiate: %v", err) + return stats, err + } + logger.Println("query status: ", stats) + return stats, nil +} + +func Terminate(pluginInfo string, host string, workloadId string) (status string, error error) { + logger := log.New(os.Stdout, "broker ", log.LstdFlags|log.Lshortfile) + clientConfig := plugin.ClientGRPCConfig{Address: pluginInfo, ChunkSize: 1024, RootCertificate: ""} + var client, err = plugin.NewClientGRPC(clientConfig) + if err != nil { + logger.Fatalf("failed to create client: %v", err) + return + } + log.Printf("pluginInfo: ", pluginInfo) + log.Printf("host: ", host) + log.Printf("workloadId: ", workloadId) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + //Terminate + ts := client.Terminate(ctx, host, workloadId) + if err != nil { + logger.Fatalf("failed to instantiate: %v", err) + return ts, err + } + + logger.Println("termination status: ", ts) + return ts, nil +} diff --git a/mecm/mepm/applcm/broker/pkg/handlers/common/common.go b/mecm/mepm/applcm/broker/pkg/handlers/common/common.go new file mode 100644 index 0000000..9b384bb --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/common/common.go @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package common + +import ( + "encoding/json" + "net/http" +) + +func RespondJSON(w http.ResponseWriter, status int, payload interface{}) { + response, err := json.Marshal(payload) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + w.Write([]byte(response)) +} + +// respondError makes the error response with payload as json format +func RespondError(w http.ResponseWriter, code int, message string) { + RespondJSON(w, code, map[string]string{"error": message}) +} diff --git a/mecm/mepm/applcm/broker/pkg/handlers/handlers.go b/mecm/mepm/applcm/broker/pkg/handlers/handlers.go new file mode 100644 index 0000000..d945649 --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/handlers.go @@ -0,0 +1,144 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package handlers + +import ( + "broker/pkg/handlers/model" + "fmt" + "github.com/gorilla/mux" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" + "log" + "net/http" + "os" + "time" +) + +const CreateAppInstance = "/ealtedge/mepm/app_lcm/v1/app_instances" +const InstantiateAppInstance = "/ealtedge/mepm/app_lcm/v1/app_instances/{appInstanceId}/instantiate" +const QueryAppInstanceInfo = "/ealtedge/mepm/app_lcm/v1/app_instances/{appInstanceId}" +const QueryAppLcmOperationStatus = "/ealtedge/mepm/app_lcm/v1/app_lcm_op_occs" +const TerminateAppIns = "/ealtedge/mepm/app_lcm/v1/app_instances/{appInstanceId}/terminate" +const DeleteAppInstanceIdentifier = "/ealtedge/mepm/app_lcm/v1/app_instances/{appInstanceId}" +const OnboardPackage = "/ealtedge/mepm/app_pkgm/v1/app_packages" +const QueryOnboardPackage = "/ealtedge/mepm/app_pkgm/v1/app_packages/{appPkgId}" + +const PackageFolderPath = "/go/release/application/packages/" +const PackageArtifactPath = "/Artifacts/Deployment/" + +type Handlers struct { + Router *mux.Router + logger *log.Logger + db *gorm.DB +} + +const DB_NAME = "applcmDB" + +// Run the app on it's router +func (hdlr *Handlers) Run(host string) { + fmt.Println("Binding to port...: %d", host) + log.Fatal(http.ListenAndServe(host, hdlr.Router)) +} + +func createDatabase() *gorm.DB { + fmt.Println("creating Database...") + + usrpswd := os.Getenv("MYSQL_USER") + ":" + os.Getenv("MYSQL_PASSWORD") + host := "@tcp(" + "dbhost" + ":3306)/" + + db, err := gorm.Open("mysql", usrpswd + host) + if err != nil { + fmt.Println("Database connect error", err.Error()) + } +// db = db.Exec("DROP DATABASE IF EXISTS " + DB_NAME) +// db = db.Exec("CREATE DATABASE "+ DB_NAME) + db.Exec("CREATE DATABASE " + DB_NAME) + db.Exec("USE applcmDB") + + //db.Close() + //db, err = gorm.Open("mysql", usrpswd + host + DB_NAME + "?charset=utf8&parseTime=True") + /*if err != nil { + fmt.Println("Database connect error", err.Error()) + } else { + fmt.Println("Database connected successfully") + }*/ + gorm.DefaultCallback.Create().Remove("mysql:set_identity_insert") + + fmt.Println("Migrating models...") + db.AutoMigrate(&model.AppPackageInfo{}) + db.AutoMigrate(&model.AppInstanceInfo{}) + //db.LogMode(true) + return db +} + +// Initialize initializes the app with predefined configuration +func (hdlr *Handlers) Initialize(logger *log.Logger) { + hdlr.Router = mux.NewRouter() + + hdlr.logger = logger + hdlr.setRouters() + hdlr.db = createDatabase() +} + +func (hdlr *Handlers) Logger(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + startTime := time.Now() + defer hdlr.logger.Printf("request processed in %s\n", time.Now().Sub(startTime)) + next(w, r) + } +} + +// setRouters sets the all required routers +func (hdlr *Handlers) setRouters() { + // Routing for handling the requests + hdlr.Post(OnboardPackage, hdlr.handleRequest(UploadFileHldr)) + hdlr.Get(QueryOnboardPackage, hdlr.handleRequest(QueryAppPackageInfo)) + hdlr.Post(CreateAppInstance, hdlr.handleRequest(CreateAppInstanceHldr)) + hdlr.Delete(QueryOnboardPackage, hdlr.handleRequest(DeleteAppPackage)) + hdlr.Post(InstantiateAppInstance, hdlr.handleRequest(InstantiateAppInstanceHldr)) + hdlr.Get(QueryAppInstanceInfo, hdlr.handleRequest(QueryAppInstanceInfoHldr)) + hdlr.Get(QueryAppLcmOperationStatus, hdlr.handleRequest(QueryAppLcmOperationStatusHldr)) + hdlr.Post(TerminateAppIns, hdlr.handleRequest(TerminateAppInsHldr)) + hdlr.Delete(DeleteAppInstanceIdentifier, hdlr.handleRequest(DeleteAppInstanceIdentifierHldr)) +} + +// Get wraps the router for GET method +func (hdlr *Handlers) Get(path string, f func(w http.ResponseWriter, r *http.Request)) { + hdlr.Router.HandleFunc(path, f).Methods("GET") +} + +// Post wraps the router for POST method +func (hdlr *Handlers) Post(path string, f func(w http.ResponseWriter, r *http.Request)) { + hdlr.Router.HandleFunc(path, f).Methods("POST") +} + +// Put wraps the router for PUT method +func (hdlr *Handlers) Put(path string, f func(w http.ResponseWriter, r *http.Request)) { + hdlr.Router.HandleFunc(path, f).Methods("PUT") +} + +// Delete wraps the router for DELETE method +func (hdlr *Handlers) Delete(path string, f func(w http.ResponseWriter, r *http.Request)) { + hdlr.Router.HandleFunc(path, f).Methods("DELETE") +} + +type RequestHandlerFunction func(db *gorm.DB, w http.ResponseWriter, r *http.Request) + +func (hdlr *Handlers) handleRequest(handler RequestHandlerFunction) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + handler(hdlr.db, w, r) + } +} diff --git a/mecm/mepm/applcm/broker/pkg/handlers/handlersImpl.go b/mecm/mepm/applcm/broker/pkg/handlers/handlersImpl.go new file mode 100644 index 0000000..ec9e296 --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/handlersImpl.go @@ -0,0 +1,424 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package handlers + +import ( + "archive/zip" + "broker/pkg/handlers/adapter/dbAdapter" + "broker/pkg/handlers/adapter/pluginAdapter" + "broker/pkg/handlers/common" + "broker/pkg/handlers/model" + "bytes" + "encoding/json" + "fmt" + "github.com/buger/jsonparser" + "github.com/ghodss/yaml" + "github.com/google/uuid" + "github.com/gorilla/mux" + "github.com/jinzhu/gorm" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "path/filepath" + "strings" +) + +func UploadFileHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + + file, header, err := r.FormFile("file") + defer file.Close() + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, file); err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + var packageName = "" + f := strings.Split(header.Filename, ".") + if len(f) > 0 { + packageName = f[0] + } + fmt.Println(packageName) + + pkgPath := PackageFolderPath + header.Filename + newFile, err := os.Create(pkgPath) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + defer newFile.Close() + if _, err := newFile.Write(buf.Bytes()); err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + /* Unzip package to decode appDescriptor */ + openPackage(w, pkgPath) + + var yamlFile = PackageFolderPath + packageName + "/Definitions/" + "MainServiceTemplate.yaml" + appPkgInfo := decodeApplicationDescriptor(w, yamlFile) + appPkgInfo.AppPackage = header.Filename + appPkgInfo.OnboardingState = "ONBOARDED" + + log.Println("Application package info from package") + defer r.Body.Close() + + dbAdapter.InsertAppPackageInfo(db, appPkgInfo) + + /*http.StatusOK*/ + common.RespondJSON(w, http.StatusCreated, appPkgInfo) +} + +func openPackage(w http.ResponseWriter, packagePath string) { + zipReader, _ := zip.OpenReader(packagePath) + for _, file := range zipReader.Reader.File { + + zippedFile, err := file.Open() + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + } + defer zippedFile.Close() + + targetDir := PackageFolderPath + "/" + extractedFilePath := filepath.Join( + targetDir, + file.Name, + ) + + if file.FileInfo().IsDir() { + os.MkdirAll(extractedFilePath, file.Mode()) + } else { + outputFile, err := os.OpenFile( + extractedFilePath, + os.O_WRONLY|os.O_CREATE|os.O_TRUNC, + file.Mode(), + ) + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + } + defer outputFile.Close() + + _, err = io.Copy(outputFile, zippedFile) + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + } + } + } +} + +func decodeApplicationDescriptor(w http.ResponseWriter, serviceTemplate string) model.AppPackageInfo { + + yamlFile, err := ioutil.ReadFile(serviceTemplate) + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + } + + jsondata, err := yaml.YAMLToJSON(yamlFile) + if err != nil { + common.RespondError(w, http.StatusBadRequest, err.Error()) + } + + appDId, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appDId") + appProvider, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appProvider") + appInfoName, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appInfoName") + appSoftVersion, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appSoftVersion") + appDVersion, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "appDVersion") + deployType, _, _, _ := jsonparser.Get(jsondata, "topology_template", "node_templates", "face_recognition", "properties", "type") + + appPkgInfo := model.AppPackageInfo{ + ID: string(appDId), + AppDID: string(appDId), + AppProvider: string(appProvider), + AppName: string(appInfoName), + AppSoftwareVersion: string(appSoftVersion), + AppDVersion: string(appDVersion), + DeployType: string(deployType), + } + + //return appPackageInfo + return appPkgInfo +} + +func QueryAppPackageInfo(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + appPkgId := params["appPkgId"] + appPkgInfo := dbAdapter.GetAppPackageInfo(db, appPkgId) + if appPkgInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode(appPkgInfo)) +} + +func DeleteAppPackage(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + appPkgId := params["appPkgId"] + appPackageInfo := dbAdapter.GetAppPackageInfo(db, appPkgId) + if appPackageInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + dbAdapter.DeleteAppPackageInfo(db, appPkgId) + + deletePackage := PackageFolderPath + appPackageInfo.AppPackage + + /* Delete ZIP*/ + os.Remove(deletePackage) + f := strings.Split(appPackageInfo.AppPackage, ".") + if len(f) > 0 { + packageName := f[0] + /*Delete unzipped*/ + os.Remove(packageName) + } + common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode("")) +} + +func CreateAppInstanceHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + var req model.CreateApplicationReq + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + appPkgInfo := dbAdapter.GetAppPackageInfo(db, req.AppDID) + if appPkgInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + fmt.Println("Query appPkg Info:", appPkgInfo) + + appInstanceId, err := uuid.NewUUID() + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + } + + appInstanceInfo := model.AppInstanceInfo{ + + ID: appInstanceId.String(), + AppInstanceName: req.AppInstancename, + AppInstanceDescription: req.AppInstanceDescriptor, + AppDID: req.AppDID, + AppProvider: appPkgInfo.AppProvider, + AppName: appPkgInfo.AppName, + AppSoftVersion: appPkgInfo.AppSoftwareVersion, + AppDVersion: appPkgInfo.AppDVersion, + AppPkgID: appPkgInfo.AppDID, + InstantiationState: "NOT_INSTANTIATED", + } + dbAdapter.InsertAppInstanceInfo(db, appInstanceInfo) + fmt.Println("CreateAppInstanceHldr:", req) + /*http.StatusOK*/ + common.RespondJSON(w, http.StatusCreated, json.NewEncoder(w).Encode(appInstanceInfo)) +} + +func InstantiateAppInstanceHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + var req model.InstantiateApplicationReq + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + params := mux.Vars(r) + appInstanceId := params["appInstanceId"] + + appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId) + appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID) + if appInstanceInfo.ID == "" || appPackageInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + + if appInstanceInfo.InstantiationState == "INSTANTIATED" { + common.RespondError(w, http.StatusInternalServerError, "Application already instantiated") + return + } + + //remove extension + var packageName = "" + f := strings.Split(appPackageInfo.AppPackage, ".") + if len(f) > 0 { + packageName = f[0] + } + fmt.Println(packageName) + + var artifact string + var pluginInfo string + + switch appPackageInfo.DeployType { + case "helm": + pkgPath := PackageFolderPath + packageName + PackageArtifactPath + "Charts" + artifact = getDeploymentArtifact(pkgPath, ".tar") + if artifact == "" { + common.RespondError(w, http.StatusInternalServerError, "artifact not available in application package") + return + } + pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT") + case "kubernetes": + pkgPath := PackageFolderPath + packageName + PackageArtifactPath + "Kubernetes" + artifact = getDeploymentArtifact(pkgPath, "*.yaml") + if artifact == "" { + common.RespondError(w, http.StatusInternalServerError, "artifact not available in application package") + return + } + pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT") + default: + common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported") + return + } + fmt.Println("Artifact to deploy:", artifact) + + workloadId, err := pluginAdapter.Instantiate(pluginInfo, req.SelectedMECHostInfo.HostID, artifact) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + dbAdapter.UpdateAppInstanceInfoInstStatusHostAndWorkloadId(db, appInstanceId, "INSTANTIATED", req.SelectedMECHostInfo.HostID, workloadId) + + common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode("")) +} + +func getDeploymentArtifact(dir string, ext string) string { + d, err := os.Open(dir) + if err != nil { + fmt.Println(err) + return "" + } + defer d.Close() + + files, err := d.Readdir(-1) + if err != nil { + fmt.Println(err) + return "" + } + + fmt.Println("Directory to read " + dir) + + for _, file := range files { + if file.Mode().IsRegular() { + if filepath.Ext(file.Name()) == ext || filepath.Ext(file.Name()) == ".gz" { + fmt.Println(file.Name()) + fmt.Println(dir + "/" + file.Name()) + return dir + "/" + file.Name() + } + } + } + return "" +} + +func QueryAppInstanceInfoHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + + params := mux.Vars(r) + appInstanceId := params["appInstanceId"] + + appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId) + appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID) + if appInstanceInfo.ID == "" || appPackageInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + var instantiatedAppState string + if appInstanceInfo.InstantiationState == "INSTANTIATED" { + + var pluginInfo string + + switch appPackageInfo.DeployType { + case "helm": + pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT") + case "kubernetes": + pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT") + default: + common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported") + return + } + + state, err := pluginAdapter.Query(pluginInfo, appInstanceInfo.Host, appInstanceInfo.WorkloadID) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + instantiatedAppState = state + } + appInstanceInfo.InstantiatedAppState = instantiatedAppState + + common.RespondJSON(w, http.StatusCreated, json.NewEncoder(w).Encode(appInstanceInfo)) +} + +func QueryAppLcmOperationStatusHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + var req model.QueryApplicationLCMOperStatusReq + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + fmt.Fprintf(w, "QueryApplicationLCMOperStatus: %+v", req) +} + +func TerminateAppInsHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + log.Println("TerminateAppInsHldr...") + params := mux.Vars(r) + appInstanceId := params["appInstanceId"] + + appInstanceInfo := dbAdapter.GetAppInstanceInfo(db, appInstanceId) + appPackageInfo := dbAdapter.GetAppPackageInfo(db, appInstanceInfo.AppDID) + if appInstanceInfo.ID == "" || appPackageInfo.ID == "" { + common.RespondJSON(w, http.StatusNotFound, "ID not exist") + return + } + + if appInstanceInfo.InstantiationState == "NOT_INSTANTIATED" { + common.RespondError(w, http.StatusNotAcceptable, "instantiationState: NOT_INSTANTIATED") + return + } + + var pluginInfo string + switch appPackageInfo.DeployType { + case "helm": + pluginInfo = "helm.plugin" + ":" + os.Getenv("HELM_PLUGIN_PORT") + case "kubernetes": + pluginInfo = "kubernetes.plugin" + ":" + os.Getenv("KUBERNETES_PLUGIN_PORT") + default: + common.RespondError(w, http.StatusInternalServerError, "Deployment type not supported") + return + } + + _, err := pluginAdapter.Terminate(pluginInfo, appInstanceInfo.Host, appInstanceInfo.WorkloadID) + if err != nil { + common.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + dbAdapter.UpdateAppInstanceInfoInstStatusAndWorkload(db, appInstanceId, "NOT_INSTANTIATED", "") + + common.RespondJSON(w, http.StatusAccepted, json.NewEncoder(w).Encode("")) +} +func DeleteAppInstanceIdentifierHldr(db *gorm.DB, w http.ResponseWriter, r *http.Request) { + fmt.Println("DeleteAppInstanceIdentifierHldr:") + params := mux.Vars(r) + appInstanceId := params["appInstanceId"] + + dbAdapter.DeleteAppInstanceInfo(db, appInstanceId) + common.RespondJSON(w, http.StatusOK, json.NewEncoder(w).Encode("")) +} diff --git a/mecm/mepm/applcm/broker/pkg/handlers/model/model.go b/mecm/mepm/applcm/broker/pkg/handlers/model/model.go new file mode 100644 index 0000000..dad1358 --- /dev/null +++ b/mecm/mepm/applcm/broker/pkg/handlers/model/model.go @@ -0,0 +1,82 @@ +/* + * Copyright 2020 Huawei Technologies Co., Ltd. + * + * 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 governing permissions and + * limitations under the License. + */ +package model + +import ( + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +type CreateApplicationReq struct { + AppDID string `yaml:"appDId"` + AppInstancename string `yaml:"appInstancename"` + AppInstanceDescriptor string `yaml:"appInstanceDescriptor"` +} + +type CreateApplicationRsp struct { + AppInstanceID string `yaml:"appInstanceId"` +} + +type OnBoardPkgApplicationRsp struct { + AppPkgID string `yaml:"appPkgId"` +} + +type InstantiateApplicationReq struct { + SelectedMECHostInfo struct { + HostName string `yaml:"hostName"` + HostID string `yaml:"hostId"` + } `yaml:"selectedMECHostInfo"` +} + +type QueryApplicationInstanceInfoReq struct { + Filter string `yaml:"filter"` + AttributeSelector string `yaml:"attributeSelector"` +} + +type QueryApplicationLCMOperStatusReq struct { + LifecycleOperationOccurrenceID string `yaml:"lifecycleOperationOccurrenceId"` +} + +// User represents a user account +type AppPackageInfo struct { + //gorm.Model + ID string `gorm:"primary_key;not null;unique"` + AppDID string `yaml:"appDId"` + AppProvider string `yaml:"appProvider"` + AppName string `yaml:"appName"` + AppSoftwareVersion string `yaml:"appSoftwareVersion"` + AppDVersion string `yaml:"appDVersion"` + OnboardingState string `yaml:"onboardingState"` + DeployType string `yaml:"deployType"` + AppPackage string `yaml:"appPackage"` +} + +// Task represents a task for the user +type AppInstanceInfo struct { + //gorm.Model + ID string `gorm:"primary_key;not null;unique"` + AppInstanceName string `yaml:"appInstanceName"` + AppInstanceDescription string `yaml:"appInstanceDescription"` + AppDID string `yaml:"appDId"` + AppProvider string `yaml:"appProvider"` + AppName string `yaml:"appName"` + AppSoftVersion string `yaml:"appSoftVersion"` + AppDVersion string `yaml:"appDVersion"` + AppPkgID string `yaml:"appPkgId"` + InstantiationState string `yaml:"instantiationState"` + Host string `yaml:"host"` + WorkloadID string `yaml:"workloadId"` + InstantiatedAppState string `yaml:"instantiatedAppState"` +} diff --git a/mecm/mepm/applcm/broker/pkg/plugin/grpcclient.go b/mecm/mepm/applcm/broker/pkg/plugin/grpcclient.go index 27402ed..613af74 100644 --- a/mecm/mepm/applcm/broker/pkg/plugin/grpcclient.go +++ b/mecm/mepm/applcm/broker/pkg/plugin/grpcclient.go @@ -68,7 +68,7 @@ func NewClientGRPC(cfg ClientGRPCConfig) (c ClientGRPC, err error) { return } -func (c *ClientGRPC) Instantiate(ctx context.Context, f string, hostIP string) (workloadId string, status string) { +func (c *ClientGRPC) Instantiate(ctx context.Context, f string, hostIP string) (workloadId string, status string, error error) { var ( writing = true buf []byte @@ -142,9 +142,10 @@ func (c *ClientGRPC) Instantiate(ctx context.Context, f string, hostIP string) ( res, err := stream.CloseAndRecv() if err != nil { logger.Fatalf("failed to receive upstream status response: ", err) + return "", "", err } log.Printf("response", res) - return res.WorkloadId, res.Status + return res.WorkloadId, res.Status, err } func (c *ClientGRPC) Query(ctx context.Context, hostIP string, workloadId string) (status string) { diff --git a/mecm/mepm/applcm/broker/start.sh b/mecm/mepm/applcm/broker/start.sh new file mode 100755 index 0000000..4b909b9 --- /dev/null +++ b/mecm/mepm/applcm/broker/start.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# Copyright 2020 Huawei Technologies Co., Ltd. +# +# 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 governing permissions and +# limitations under the License. + +cd / +#set +e +#sed -i "s/^httpaddr.*=.*$/httpaddr = $(hostname)/g" conf/app.conf +#sed -i "s/^ssl_mode.*=.*$/ssl_mode = ${MEP_SSL_MODE:-0}/g" conf/app.conf +#sed -i "s/^ssl_verify_client.*=.*$/ssl_verify_client = 0/g" conf/app.conf +#set -e + +./app