This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new d065f788d feat: add onboard keyvalue api (#7189)
d065f788d is described below
commit d065f788dcecac4440515e4ebe36a203a21a89ab
Author: abeizn <[email protected]>
AuthorDate: Tue Mar 19 18:44:17 2024 +0800
feat: add onboard keyvalue api (#7189)
* feat: add onboard keyvalue api
* fix: optimize interface
* fix: revert poetry lock
* fix: get json result
* fix: rename onboard storeKey
* fix: word
* fix: some details
---
.../migrationscripts/20240318_add_devlake_store.go | 54 +++++++++++++++
backend/core/models/migrationscripts/register.go | 1 +
backend/core/models/project.go | 14 ++++
backend/server/api/router.go | 4 ++
backend/server/api/store/store.go | 78 ++++++++++++++++++++++
backend/server/services/store.go | 57 ++++++++++++++++
6 files changed, 208 insertions(+)
diff --git a/backend/core/models/migrationscripts/20240318_add_devlake_store.go
b/backend/core/models/migrationscripts/20240318_add_devlake_store.go
new file mode 100644
index 000000000..e338fd896
--- /dev/null
+++ b/backend/core/models/migrationscripts/20240318_add_devlake_store.go
@@ -0,0 +1,54 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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 migrationscripts
+
+import (
+ "encoding/json"
+ "time"
+
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/plugin"
+)
+
+var _ plugin.MigrationScript = (*addStore)(nil)
+
+type store20240318 struct {
+ StoreKey string `gorm:"primaryKey;type:varchar(255)"`
+ StoreValue json.RawMessage `gorm:"type:json;serializer:json"`
+ CreatedAt time.Time `json:"createdAt" mapstructure:"createdAt"`
+ UpdatedAt time.Time `json:"updatedAt" mapstructure:"updatedAt"`
+}
+
+func (store20240318) TableName() string {
+ return "_devlake_store"
+}
+
+type addStore struct{}
+
+func (*addStore) Up(basicRes context.BasicRes) errors.Error {
+ return basicRes.GetDal().AutoMigrate(store20240318{})
+}
+
+func (*addStore) Version() uint64 {
+ return 20240318111247
+}
+
+func (*addStore) Name() string {
+ return "add _devlake_store table"
+}
diff --git a/backend/core/models/migrationscripts/register.go
b/backend/core/models/migrationscripts/register.go
index 03319bf92..26b3ec9bb 100644
--- a/backend/core/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/register.go
@@ -109,5 +109,6 @@ func All() []plugin.MigrationScript {
new(modifyRefsIdLength),
new(addOriginalEnvironmentToCicdDeploymentsAndCicdDeploymentCommits),
new(addSubtabknameToDeployment),
+ new(addStore),
}
}
diff --git a/backend/core/models/project.go b/backend/core/models/project.go
index 6a935e97e..4da6afc67 100644
--- a/backend/core/models/project.go
+++ b/backend/core/models/project.go
@@ -18,6 +18,9 @@ limitations under the License.
package models
import (
+ "encoding/json"
+ "time"
+
"github.com/apache/incubator-devlake/core/models/common"
)
@@ -67,3 +70,14 @@ type ApiOutputProject struct {
Blueprint *Blueprint `json:"blueprint" mapstructure:"blueprint"`
LastPipeline *Pipeline `json:"lastPipeline,omitempty"
mapstructure:"lastPipeline"`
}
+
+type Store struct {
+ StoreKey string `gorm:"primaryKey;type:varchar(255)"`
+ StoreValue json.RawMessage `gorm:"type:json;serializer:json"`
+ CreatedAt time.Time `json:"createdAt" mapstructure:"createdAt"`
+ UpdatedAt time.Time `json:"updatedAt" mapstructure:"updatedAt"`
+}
+
+func (Store) TableName() string {
+ return "_devlake_store"
+}
diff --git a/backend/server/api/router.go b/backend/server/api/router.go
index 6957044de..188c29e4c 100644
--- a/backend/server/api/router.go
+++ b/backend/server/api/router.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/impls/logruslog"
"github.com/apache/incubator-devlake/server/api/apikeys"
+ "github.com/apache/incubator-devlake/server/api/store"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/server/api/blueprints"
@@ -73,6 +74,9 @@ func RegisterRouter(r *gin.Engine, basicRes context.BasicRes)
{
r.DELETE("/projects/*projectName", project.DeleteProject)
r.POST("/projects", project.PostProject)
r.GET("/projects", project.GetProjects)
+ // on board api
+ r.GET("/store/:storeKey", store.GetStore)
+ r.PUT("/store/:storeKey", store.PutStore)
// api keys api
r.GET("/api-keys", apikeys.GetApiKeys)
diff --git a/backend/server/api/store/store.go
b/backend/server/api/store/store.go
new file mode 100644
index 000000000..0c7ab3778
--- /dev/null
+++ b/backend/server/api/store/store.go
@@ -0,0 +1,78 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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 store
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/models"
+ "github.com/apache/incubator-devlake/server/api/shared"
+ "github.com/apache/incubator-devlake/server/services"
+
+ "github.com/gin-gonic/gin"
+)
+
+// @Summary Get the value by given key
+// @Description Get the value by given key
+// @Tags framework/projects
+// @Param storeKey path string true "storeKey"
+// @Success 200 {object} json.RawMessage
+// @Failure 400 {string} errcode.Error "Bad Request"
+// @Failure 500 {string} errcode.Error "Internal Error"
+// @Router /store/{storeKey} [get]
+func GetStore(c *gin.Context) {
+ storeKey := c.Param("storeKey")
+ result, err := services.GetStore(storeKey)
+ if err != nil {
+ c.JSON(http.StatusInternalServerError, gin.H{"error":
fmt.Sprintf("Error fetching %s data", storeKey)})
+ return
+ }
+
+ shared.ApiOutputSuccess(c, result.StoreValue, http.StatusOK)
+}
+
+// @Summary Put the value by given key
+// @Description Put the value by given key
+// @Tags framework/projects
+// @Accept application/json
+// @Param storeKey path string true "storeKey"
+// @Param project body json.RawMessage false "json"
+// @Success 200 {object} json.RawMessage
+// @Failure 400 {string} errcode.Error "Bad Request"
+// @Failure 500 {string} errcode.Error "Internal Error"
+// @Router /store/{storeKey} [PUT]
+func PutStore(c *gin.Context) {
+ storeKey := c.Param("storeKey")
+ var body models.Store
+ err := c.ShouldBind(&body.StoreValue)
+ if err != nil {
+ shared.ApiOutputError(c, errors.BadInput.Wrap(err,
shared.BadRequestBody))
+ return
+ }
+ body.StoreKey = storeKey
+
+ result, err := services.PutStore(storeKey, &body)
+ if err != nil {
+ shared.ApiOutputError(c, errors.Default.Wrap(err,
fmt.Sprintf("PutStore: failed to put %s", storeKey)))
+ return
+ }
+
+ shared.ApiOutputSuccess(c, result.StoreValue, http.StatusCreated)
+}
diff --git a/backend/server/services/store.go b/backend/server/services/store.go
new file mode 100644
index 000000000..1eb4b717c
--- /dev/null
+++ b/backend/server/services/store.go
@@ -0,0 +1,57 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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 services
+
+import (
+ "fmt"
+
+ "github.com/apache/incubator-devlake/core/dal"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/models"
+)
+
+// GetProjects returns a paginated list of Projects based on `query`
+func GetStore(storeKey string) (*models.Store, errors.Error) {
+ clauses := []dal.Clause{
+ dal.From(&models.Store{}),
+ dal.Where("store_key = ?", storeKey),
+ }
+
+ kvstore := &models.Store{}
+ err := db.All(&kvstore, clauses...)
+ if err != nil {
+ return nil, errors.Default.Wrap(err, fmt.Sprintf("error finding
%s on _devlake_store table", storeKey))
+ }
+
+ return kvstore, nil
+}
+
+// PutOnboard accepts a project instance and insert it to database
+func PutStore(storeKey string, storeValue *models.Store) (*models.Store,
errors.Error) {
+ // verify input
+ if err := VerifyStruct(storeValue); err != nil {
+ return nil, err
+ }
+
+ err := db.CreateOrUpdate(storeValue, dal.Where("store_key = ?",
storeKey))
+ if err != nil {
+ return nil, err
+ }
+
+ return storeValue, nil
+}