Implement ModelInfoRepository 16/13516/3
authorsubhash kumar singh <subh.singh@samsung.com>
Mon, 7 Oct 2024 10:47:17 +0000 (10:47 +0000)
committersubhash kumar singh <subh.singh@samsung.com>
Mon, 7 Oct 2024 18:57:36 +0000 (18:57 +0000)
Implemented ModelInfoRepository with implementation.

Change-Id: If70abc07f440d12a42cee1581212a8d567828f0d
Signed-off-by: subhash kumar singh <subh.singh@samsung.com>
Dockerfile
apis/mmes_apis.go
apis_test/mmes_apis_test.go
db/iDB.go
db/modelInfoRepository.go
go.mod
go.sum
main.go
models/modelInfo.go
routers/router.go

index 9a0d75f..0660c72 100644 (file)
@@ -16,7 +16,7 @@
 #
 # ==================================================================================
 #Base Image
-FROM golang:1.21-alpine AS builder
+FROM golang:1.23.1 AS builder
 
 # location in the container
 ENV MME_DIR /home/app/
@@ -30,16 +30,16 @@ RUN go mod tidy
 RUN LOG_FILE_NAME=testing.log go test ./...
 
 #Build all packages from current dir into bin 
-RUN go build -o mme_bin .
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o mme_bin .
 
-FROM alpine:3.20
+FROM alpine:3.20.3
 
 RUN apk update && apk add bash
 RUN apk add --no-cache bash
 
 WORKDIR /app
 
-COPY --from=builder /home/app/mme_bin .
+COPY --from=builder /home/app/mme_bin mme_bin
 
 #Start the app
 ENTRYPOINT ["/app/mme_bin"]
index 44b7397..ce04b71 100644 (file)
@@ -18,7 +18,6 @@ limitations under the License.
 package apis
 
 import (
-       "encoding/json"
        "io"
        "net/http"
        "os"
@@ -28,7 +27,6 @@ import (
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/logging"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/models"
        "github.com/gin-gonic/gin"
-       "github.com/google/uuid"
 )
 
 type MmeApiHandler struct {
@@ -46,36 +44,56 @@ func NewMmeApiHandler(dbMgr core.DBMgr, iDB db.IDB) *MmeApiHandler {
 
 func (m *MmeApiHandler) RegisterModel(cont *gin.Context) {
 
-       logging.INFO("Creating model...")
-       bodyBytes, _ := io.ReadAll(cont.Request.Body)
-
        var modelInfo models.ModelInfo
-       //Need to unmarshal JSON to Struct, to access request
-       //data such as model name, rapp id etc
-       err := json.Unmarshal(bodyBytes, &modelInfo)
-       if err != nil || modelInfo.ModelId.ModelName == "" {
-               logging.ERROR("Error in unmarshalling")
+
+       if err := cont.ShouldBindJSON(&modelInfo); err != nil {
                cont.JSON(http.StatusBadRequest, gin.H{
-                       "code":    http.StatusBadRequest,
-                       "message": string("Can not parse input data, provide mandatory details"),
-               })
-       } else {
-               id := uuid.New()
-               modelInfo.Id = id.String()
-               modelInfoBytes, _ := json.Marshal(modelInfo)
-               err := m.dbmgr.CreateBucket(modelInfo.ModelId.ModelName)
-               if err == nil {
-                       m.dbmgr.UploadFile(modelInfoBytes, modelInfo.ModelId.ModelName+os.Getenv("INFO_FILE_POSTFIX"), modelInfo.ModelId.ModelName)
-               } else {
-                       cont.JSON(http.StatusInternalServerError, gin.H{
-                               "code":    http.StatusInternalServerError,
-                               "message": err.Error(),
-                       })
-               }
-               cont.JSON(http.StatusCreated, gin.H{
-                       "modelinfo": modelInfoBytes,
+                       "error": err.Error(),
                })
+               return
        }
+
+       // TODO: validate the object
+
+       if err := m.iDB.Create(modelInfo); err != nil {
+               logging.ERROR("error", err)
+               return
+       }
+
+       logging.INFO("model is saved.")
+
+       cont.JSON(http.StatusCreated, gin.H{})
+
+       // logging.INFO("Creating model...")
+       // bodyBytes, _ := io.ReadAll(cont.Request.Body)
+
+       // var modelInfo models.ModelInfo
+       // //Need to unmarshal JSON to Struct, to access request
+       // //data such as model name, rapp id etc
+       // err := json.Unmarshal(bodyBytes, &modelInfo)
+       // if err != nil || modelInfo.ModelId.ModelName == "" {
+       //      logging.ERROR("Error in unmarshalling")
+       //      cont.JSON(http.StatusBadRequest, gin.H{
+       //              "code":    http.StatusBadRequest,
+       //              "message": string("Can not parse input data, provide mandatory details"),
+       //      })
+       // } else {
+       //      id := uuid.New()
+       //      modelInfo.Id = id.String()
+       //      modelInfoBytes, _ := json.Marshal(modelInfo)
+       //      err := m.dbmgr.CreateBucket(modelInfo.ModelId.ModelName)
+       //      if err == nil {
+       //              m.dbmgr.UploadFile(modelInfoBytes, modelInfo.ModelId.ModelName+os.Getenv("INFO_FILE_POSTFIX"), modelInfo.ModelId.ModelName)
+       //      } else {
+       //              cont.JSON(http.StatusInternalServerError, gin.H{
+       //                      "code":    http.StatusInternalServerError,
+       //                      "message": err.Error(),
+       //              })
+       //      }
+       //      cont.JSON(http.StatusCreated, gin.H{
+       //              "modelinfo": modelInfoBytes,
+       //      })
+       // }
 }
 
 /*
@@ -83,29 +101,41 @@ This API retrieves model info list managed in modelmgmtservice
 */
 func (m *MmeApiHandler) GetModelInfo(cont *gin.Context) {
        logging.INFO("List all model API")
-       bucketList, err := m.dbmgr.ListBucket(os.Getenv("INFO_FILE_POSTFIX"))
+
+       models, err := m.iDB.GetAll()
        if err != nil {
-               statusCode := http.StatusInternalServerError
-               logging.ERROR("Error occurred, send status code: ", statusCode)
-               cont.JSON(statusCode, gin.H{
-                       "code":    statusCode,
-                       "message": "Unexpected Error in server, you can't get model information list",
+               logging.ERROR("error:", err)
+               cont.JSON(http.StatusInternalServerError, gin.H{
+                       "code":    http.StatusInternalServerError,
+                       "message": err.Error(),
                })
                return
        }
 
-       modelInfoListResp := []models.ModelInfoResponse{}
-       for _, bucket := range bucketList {
-               modelInfoListResp = append(modelInfoListResp, models.ModelInfoResponse{
-                       Name: bucket.Name,
-                       Data: string(bucket.Object),
-               })
-       }
-
-       cont.JSON(http.StatusOK, gin.H{
-               "code":    http.StatusOK,
-               "message": modelInfoListResp,
-       })
+       cont.JSON(http.StatusOK, models)
+       // bucketList, err := m.dbmgr.ListBucket(os.Getenv("INFO_FILE_POSTFIX"))
+       // if err != nil {
+       //      statusCode := http.StatusInternalServerError
+       //      logging.ERROR("Error occurred, send status code: ", statusCode)
+       //      cont.JSON(statusCode, gin.H{
+       //              "code":    statusCode,
+       //              "message": "Unexpected Error in server, you can't get model information list",
+       //      })
+       //      return
+       // }
+
+       // modelInfoListResp := []models.ModelInfoResponse{}
+       // for _, bucket := range bucketList {
+       //      modelInfoListResp = append(modelInfoListResp, models.ModelInfoResponse{
+       //              Name: bucket.Name,
+       //              Data: string(bucket.Object),
+       //      })
+       // }
+
+       // cont.JSON(http.StatusOK, gin.H{
+       //      "code":    http.StatusOK,
+       //      "message": modelInfoListResp,
+       // })
 }
 
 /*
@@ -170,10 +200,42 @@ func (m *MmeApiHandler) GetModel(cont *gin.Context) {
        cont.IndentedJSON(http.StatusOK, " ")
 }
 
-func (m *MmeApiHandler) UpdateModel() {
+func (m *MmeApiHandler) UpdateModel(c *gin.Context) {
        logging.INFO("Updating model...")
+       id := c.Param("id")
+       var modelInfo models.ModelInfo
+
+       if err := c.ShouldBindJSON(&modelInfo); err != nil {
+               c.JSON(http.StatusBadRequest, gin.H{
+                       "error": err.Error(),
+               })
+               return
+       }
+
+       if id != modelInfo.Id {
+               c.JSON(http.StatusBadRequest, gin.H{
+                       "error": "ID in path and body does not match",
+               })
+               return
+       }
+
+       if err := m.iDB.Update(modelInfo); err != nil {
+               logging.ERROR(err)
+               return
+       }
+
+       logging.INFO("model updated")
+       c.JSON(http.StatusOK, gin.H{})
 }
 
-func (m *MmeApiHandler) DeleteModel() {
+func (m *MmeApiHandler) DeleteModel(c *gin.Context) {
        logging.INFO("Deleting model...")
+       id := c.Param("id")
+       if err := m.iDB.Delete(id); err != nil {
+               c.JSON(http.StatusInternalServerError, gin.H{
+                       "error": err.Error(),
+               })
+               return
+       }
+       c.JSON(http.StatusOK, gin.H{"message": "modelInfo deleted"})
 }
index d9772b9..deb5a9e 100644 (file)
@@ -19,7 +19,7 @@ package apis_test
 
 import (
        "encoding/json"
-       "errors"
+       "fmt"
        "io"
        "net/http"
        "net/http/httptest"
@@ -29,6 +29,8 @@ import (
 
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/apis"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/core"
+       "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/db"
+       "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/logging"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/models"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/routers"
        "github.com/stretchr/testify/assert"
@@ -67,11 +69,39 @@ func (d *dbMgrMock) ListBucket(bucketObjPostfix string) ([]core.Bucket, error) {
        return args.Get(0).([]core.Bucket), args.Error(1)
 }
 
+type iDBMock struct {
+       mock.Mock
+       db.IDB
+}
+
+func (i *iDBMock) Create(modelInfo models.ModelInfo) error {
+       args := i.Called(modelInfo)
+       return args.Error(0)
+}
+func (i *iDBMock) GetByID(id string) (*models.ModelInfo, error) {
+       return nil, nil
+}
+func (i *iDBMock) GetAll() ([]models.ModelInfo, error) {
+       args := i.Called()
+       if _, ok := args.Get(1).(error); !ok {
+               return args.Get(0).([]models.ModelInfo), nil
+       } else {
+               var emptyModelInfo []models.ModelInfo
+               return emptyModelInfo, args.Error(1)
+       }
+}
+func (i *iDBMock) Update(modelInfo models.ModelInfo) error {
+       return nil
+}
+func (i *iDBMock) Delete(id string) error {
+       return nil
+}
+
 func TestRegisterModel(t *testing.T) {
        os.Setenv("LOG_FILE_NAME", "testing")
-       dbMgrMockInst := new(dbMgrMock)
-       dbMgrMockInst.On("CreateBucket", "test-model").Return(nil)
-       handler := apis.NewMmeApiHandler(dbMgrMockInst, nil)
+       iDBMockInst := new(iDBMock)
+       iDBMockInst.On("Create", mock.Anything).Return(nil)
+       handler := apis.NewMmeApiHandler(nil, iDBMockInst)
        router := routers.InitRouter(handler)
        w := httptest.NewRecorder()
        req, _ := http.NewRequest("POST", "/registerModel", strings.NewReader(registerModelBody))
@@ -84,15 +114,24 @@ func TestWhenSuccessGetModelInfoList(t *testing.T) {
        os.Setenv("LOG_FILE_NAME", "testing")
 
        // Setting Mock
-       dbMgrMockInst := new(dbMgrMock)
-       dbMgrMockInst.On("ListBucket").Return([]core.Bucket{
+       iDBmockInst := new(iDBMock)
+       iDBmockInst.On("GetAll").Return([]models.ModelInfo{
                {
-                       Name:   "qoe",
-                       Object: []byte(registerModelBody),
+                       Id: "1234",
+                       ModelId: models.ModelID{
+                               ModelName:    "test",
+                               ModelVersion: "v1.0",
+                       },
+                       Description: "this is test modelINfo",
+                       ModelSpec: models.ModelSpec{
+                               Metadata: models.Metadata{
+                                       Author: "testing",
+                               },
+                       },
                },
        }, nil)
 
-       handler := apis.NewMmeApiHandler(dbMgrMockInst, nil)
+       handler := apis.NewMmeApiHandler(nil, iDBmockInst)
        router := routers.InitRouter(handler)
        responseRecorder := httptest.NewRecorder()
 
@@ -102,15 +141,12 @@ func TestWhenSuccessGetModelInfoList(t *testing.T) {
        response := responseRecorder.Result()
        body, _ := io.ReadAll(response.Body)
 
-       var modelInfoListResp struct {
-               Code    int                        `json:"code"`
-               Message []models.ModelInfoResponse `json:"message"`
-       }
-       json.Unmarshal(body, &modelInfoListResp)
+       var modelInfos []models.ModelInfo
+       logging.INFO(modelInfos)
+       json.Unmarshal(body, &modelInfos)
 
        assert.Equal(t, 200, responseRecorder.Code)
-       assert.Equal(t, 200, modelInfoListResp.Code)
-       assert.Equal(t, registerModelBody, modelInfoListResp.Message[0].Data)
+       assert.Equal(t, 1, len(modelInfos))
 }
 
 func TestWhenFailGetModelInfoList(t *testing.T) {
@@ -118,10 +154,10 @@ func TestWhenFailGetModelInfoList(t *testing.T) {
        os.Setenv("LOG_FILE_NAME", "testing")
 
        // Setting Mock
-       dbMgrMockInst := new(dbMgrMock)
-       dbMgrMockInst.On("ListBucket").Return([]core.Bucket{}, errors.New("Test: Fail GetModelInfoList"))
+       iDBmockInst2 := new(iDBMock)
+       iDBmockInst2.On("GetAll").Return([]models.ModelInfo{}, fmt.Errorf("db not available"))
 
-       handler := apis.NewMmeApiHandler(dbMgrMockInst, nil)
+       handler := apis.NewMmeApiHandler(nil, iDBmockInst2)
        router := routers.InitRouter(handler)
        responseRecorder := httptest.NewRecorder()
 
@@ -131,13 +167,8 @@ func TestWhenFailGetModelInfoList(t *testing.T) {
        response := responseRecorder.Result()
        body, _ := io.ReadAll(response.Body)
 
-       var modelInfoListResp struct {
-               Code    int                        `json:"code"`
-               Message []models.ModelInfoResponse `json:"message"`
-       }
+       var modelInfoListResp []models.ModelInfo
        json.Unmarshal(body, &modelInfoListResp)
 
        assert.Equal(t, 500, responseRecorder.Code)
-       assert.Equal(t, 500, modelInfoListResp.Code)
-       assert.Equal(t, 0, len(modelInfoListResp.Message))
 }
index 233ffa8..a237a69 100644 (file)
--- a/db/iDB.go
+++ b/db/iDB.go
@@ -24,7 +24,7 @@ import (
 type IDB interface {
        Create(modelInfo models.ModelInfo) error
        GetByID(id string) (*models.ModelInfo, error)
-       GetAll() []models.ModelInfo
+       GetAll() ([]models.ModelInfo, error)
        Update(modelInfo models.ModelInfo) error
        Delete(id string) error
 }
index 6e8b128..5ac9fdd 100644 (file)
@@ -18,6 +18,7 @@ limitations under the License.
 package db
 
 import (
+       "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/logging"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/models"
        "gorm.io/gorm"
 )
@@ -33,6 +34,7 @@ func NewModelInfoRepository(db *gorm.DB) *ModelInfoRepository {
 }
 
 func (repo *ModelInfoRepository) Create(modelInfo models.ModelInfo) error {
+       repo.db.Create(modelInfo)
        return nil
 }
 
@@ -40,14 +42,26 @@ func (repo *ModelInfoRepository) GetByID(id string) (*models.ModelInfo, error) {
        return nil, nil
 }
 
-func (repo *ModelInfoRepository) GetAll() []models.ModelInfo {
-       return nil
+func (repo *ModelInfoRepository) GetAll() ([]models.ModelInfo, error) {
+       var modelInfos []models.ModelInfo
+       result := repo.db.Find(&modelInfos)
+       if result.Error != nil {
+               return nil, result.Error
+       }
+       return modelInfos, nil
 }
 
 func (repo *ModelInfoRepository) Update(modelInfo models.ModelInfo) error {
+       if err := repo.db.Save(modelInfo).Error; err != nil {
+               return err
+       }
        return nil
 }
 
 func (repo *ModelInfoRepository) Delete(id string) error {
+       logging.INFO("id is:", id)
+       if err := repo.db.Delete(&models.ModelInfo{}, "id=?", id).Error; err != nil {
+               return err
+       }
        return nil
 }
diff --git a/go.mod b/go.mod
index 72f7c83..fa25acc 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -1,12 +1,15 @@
 module gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice
 
-go 1.21.3
+go 1.22
+
+toolchain go1.23.2
 
 require (
        github.com/aws/aws-sdk-go v1.47.3
        github.com/gin-gonic/gin v1.9.1
-       github.com/google/uuid v1.6.0
        github.com/stretchr/testify v1.8.3
+       gorm.io/driver/postgres v1.5.9
+       gorm.io/gorm v1.25.12
 )
 
 require (
@@ -19,28 +22,32 @@ require (
        github.com/go-playground/universal-translator v0.18.1 // indirect
        github.com/go-playground/validator/v10 v10.14.0 // indirect
        github.com/goccy/go-json v0.10.2 // indirect
+       github.com/jackc/pgpassfile v1.0.0 // indirect
+       github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+       github.com/jackc/pgx/v5 v5.5.5 // indirect
+       github.com/jackc/puddle/v2 v2.2.1 // indirect
        github.com/jinzhu/inflection v1.0.0 // indirect
        github.com/jinzhu/now v1.1.5 // indirect
        github.com/jmespath/go-jmespath v0.4.0 // indirect
        github.com/json-iterator/go v1.1.12 // indirect
        github.com/klauspost/cpuid/v2 v2.2.4 // indirect
+       github.com/kr/text v0.2.0 // indirect
        github.com/leodido/go-urn v1.2.4 // indirect
        github.com/mattn/go-isatty v0.0.19 // indirect
-       github.com/mattn/go-sqlite3 v1.14.22 // indirect
        github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
        github.com/modern-go/reflect2 v1.0.2 // indirect
        github.com/pelletier/go-toml/v2 v2.0.8 // indirect
        github.com/pmezard/go-difflib v1.0.0 // indirect
+       github.com/rogpeppe/go-internal v1.13.1 // indirect
        github.com/stretchr/objx v0.5.0 // indirect
        github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
        github.com/ugorji/go/codec v1.2.11 // indirect
        golang.org/x/arch v0.3.0 // indirect
-       golang.org/x/crypto v0.14.0 // indirect
+       golang.org/x/crypto v0.17.0 // indirect
        golang.org/x/net v0.17.0 // indirect
-       golang.org/x/sys v0.13.0 // indirect
+       golang.org/x/sync v0.1.0 // indirect
+       golang.org/x/sys v0.21.0 // indirect
        golang.org/x/text v0.14.0 // indirect
        google.golang.org/protobuf v1.30.0 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
-       gorm.io/driver/sqlite v1.5.6 // indirect
-       gorm.io/gorm v1.25.12 // indirect
 )
diff --git a/go.sum b/go.sum
index d3925ff..6ce65e0 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,7 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
 github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -29,8 +30,14 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
+github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
 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.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
@@ -44,12 +51,14 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
 github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
 github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
-github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -59,6 +68,8 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
@@ -78,16 +89,16 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
 golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
 golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@@ -95,15 +106,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
-gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
+gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
+gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
 gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/main.go b/main.go
index 548897c..1bb51c3 100644 (file)
--- a/main.go
+++ b/main.go
@@ -18,6 +18,7 @@ limitations under the License.
 package main
 
 import (
+       "fmt"
        "net/http"
        "os"
        "time"
@@ -28,14 +29,31 @@ import (
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/logging"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/models"
        "gerrit.o-ran-sc.org/r/aiml-fw/awmf/modelmgmtservice/routers"
-       "gorm.io/driver/sqlite"
+       "gorm.io/driver/postgres"
        "gorm.io/gorm"
 )
 
 func main() {
 
        // setup the database connection
-       db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
+
+       // connection string
+       DSN := fmt.Sprintf(
+               "host=%s user=%s password=%s dbname=%s port=%s sslmode=disable ",
+               os.Getenv("PG_HOST"),
+               os.Getenv("PG_USER"),
+               os.Getenv("PG_PASSWORD"),
+               os.Getenv("PG_DBNAME"),
+               os.Getenv("PG_PORT"),
+       )
+
+       logging.INFO("Connection string for DB", DSN)
+       db, err := gorm.Open(postgres.New(postgres.Config{
+               DSN:                  DSN,
+               PreferSimpleProtocol: true, // disables implicit prepared statement usage
+       }), &gorm.Config{})
+
+       // db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
        if err != nil {
                logging.ERROR("database not available")
                os.Exit(-1)
@@ -57,5 +75,8 @@ func main() {
                WriteTimeout: 10 * time.Second,
        }
        logging.INFO("Starting api..")
-       server.ListenAndServe()
+       err = server.ListenAndServe()
+       if err != nil {
+               logging.ERROR("error", err)
+       }
 }
index 7ea86ba..2d1c702 100644 (file)
@@ -23,7 +23,7 @@ type Metadata struct {
 }
 
 type ModelSpec struct {
-       Metadata Metadata `json:"metadata"`
+       Metadata Metadata `json:"metadata" gorm:"embedded"`
 }
 type ModelID struct {
        ModelName    string `json:"modelName"`
@@ -31,10 +31,10 @@ type ModelID struct {
 }
 
 type ModelInfo struct {
-       Id          string    `json:"id"`
-       ModelId     ModelID   `json:"modelId,omitempty"`
+       Id          string    `json:"id" gorm:"primaryKey"`
+       ModelId     ModelID   `json:"model-id,omitempty" gorm:"embedded"`
        Description string    `json:"description"`
-       ModelSpec   ModelSpec `json:"metaInfo"`
+       ModelSpec   ModelSpec `json:"meta-info" gorm:"embedded"`
 }
 
 type ModelInfoResponse struct {
index 12a4918..365268b 100644 (file)
@@ -29,6 +29,8 @@ func InitRouter(handler *apis.MmeApiHandler) *gin.Engine {
 
        r.POST("/registerModel", handler.RegisterModel)
        r.GET("/getModelInfo", handler.GetModelInfo)
+       r.PUT("/modelInfo/:id", handler.UpdateModel)
+       r.DELETE("/modelInfo/:id", handler.DeleteModel)
        r.GET("/getModelInfo/:modelName", handler.GetModelInfoByName)
        r.POST("/uploadModel/:modelName", handler.UploadModel)
        r.GET("/downloadModel/:modelName/model.zip", handler.DownloadModel)