You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/09/30 10:08:00 UTC

[servicecomb-kie] 01/02: SCB-1500 decouple mongodb, use mongodb storage as a plugin

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git

commit 86e7c7c1facd09f94f477d0015300b1acb060c76
Author: tian <xi...@gmail.com>
AuthorDate: Sun Sep 29 19:22:08 2019 +0800

    SCB-1500 decouple mongodb, use mongodb storage as a plugin
---
 cmd/kieserver/main.go                              |  6 +-
 server/resource/v1/history_resource.go             |  7 +-
 server/resource/v1/history_resource_test.go        | 11 +--
 server/resource/v1/kv_resource.go                  | 19 +++--
 server/resource/v1/kv_resource_test.go             |  5 +-
 server/resource/v1/v1_suite_test.go                |  2 +
 server/service/history/service.go                  | 66 ---------------
 server/service/{ => mongo}/history/dao.go          | 46 +++++++++--
 server/service/{label => mongo/history}/service.go | 30 +++----
 server/service/{ => mongo}/history/tool.go         |  0
 server/service/mongo/init.go                       | 16 ++++
 server/service/{kv/dao.go => mongo/kv/kv_dao.go}   | 65 +++++++++------
 .../{kv/service.go => mongo/kv/kv_service.go}      | 91 +++++++++-----------
 server/service/{ => mongo}/kv/kv_suite_test.go     |  2 +-
 server/service/{ => mongo}/kv/kv_test.go           | 91 +++++++++++---------
 server/service/{ => mongo}/kv/tool.go              |  6 +-
 .../{label/dao.go => mongo/label/label_dao.go}     | 96 +++++++++++-----------
 .../{db/db.go => service/mongo/session/session.go} | 17 ++--
 server/service/{kv => }/options.go                 |  2 +-
 server/service/service.go                          | 35 ++++++++
 20 files changed, 316 insertions(+), 297 deletions(-)

diff --git a/cmd/kieserver/main.go b/cmd/kieserver/main.go
index b861289..cd397f9 100644
--- a/cmd/kieserver/main.go
+++ b/cmd/kieserver/main.go
@@ -18,13 +18,13 @@
 package main
 
 import (
+	"github.com/apache/servicecomb-kie/server/service"
 	"os"
 
-	"github.com/apache/servicecomb-kie/server/db"
-
 	"github.com/apache/servicecomb-kie/server/config"
 	_ "github.com/apache/servicecomb-kie/server/handler"
 	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
+	_ "github.com/apache/servicecomb-kie/server/service/mongo"
 	"github.com/go-chassis/go-chassis"
 	"github.com/go-mesh/openlogging"
 	"github.com/urfave/cli"
@@ -80,7 +80,7 @@ func main() {
 	if err := config.Init(Configs.ConfigFile); err != nil {
 		openlogging.Fatal(err.Error())
 	}
-	if err := db.Init(); err != nil {
+	if err := service.DBInit(); err != nil {
 		openlogging.Fatal(err.Error())
 	}
 	if err := chassis.Run(); err != nil {
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 73b237a..28b8241 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -18,12 +18,11 @@
 package v1
 
 import (
+	"github.com/apache/servicecomb-kie/server/service"
 	"net/http"
 
 	"github.com/apache/servicecomb-kie/pkg/common"
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	rvsvc "github.com/apache/servicecomb-kie/server/service/history"
 	goRestful "github.com/emicklei/go-restful"
 	"github.com/go-chassis/go-chassis/server/restful"
 	"github.com/go-mesh/openlogging"
@@ -42,9 +41,9 @@ func (r *HistoryResource) GetRevisionsByLabelID(context *restful.Context) {
 		WriteErrResponse(context, http.StatusForbidden, "label_id must not be empty", common.ContentTypeText)
 		return
 	}
-	revisions, err := rvsvc.GetHistoryByLabelID(context.Ctx, labelID)
+	revisions, err := service.HistoryService.GetHistoryByLabelID(context.Ctx, labelID)
 	if err != nil {
-		if err == db.ErrRevisionNotExist {
+		if err == service.ErrRevisionNotExist {
 			WriteErrResponse(context, http.StatusNotFound, err.Error(), common.ContentTypeText)
 			return
 		}
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
index c4756aa..c431614 100644
--- a/server/resource/v1/history_resource_test.go
+++ b/server/resource/v1/history_resource_test.go
@@ -19,6 +19,7 @@ package v1_test
 import (
 	"context"
 	"encoding/json"
+	"github.com/apache/servicecomb-kie/server/service"
 	"io/ioutil"
 
 	"github.com/go-chassis/go-chassis/core/common"
@@ -29,11 +30,9 @@ import (
 	"net/http/httptest"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	kvsvc "github.com/apache/servicecomb-kie/server/service/kv"
-
 	"github.com/apache/servicecomb-kie/server/config"
 	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
+	_ "github.com/apache/servicecomb-kie/server/service/mongo"
 	"github.com/go-chassis/go-chassis/server/restful/restfultest"
 
 	. "github.com/onsi/ginkgo"
@@ -48,7 +47,7 @@ var _ = Describe("v1 history resource", func() {
 
 	Describe("get history revisions", func() {
 		config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
-		err := db.Init()
+		err := service.DBInit()
 		It("should not return err", func() {
 			Expect(err).Should(BeNil())
 		})
@@ -59,8 +58,10 @@ var _ = Describe("v1 history resource", func() {
 				Labels: map[string]string{
 					"test": "revisions",
 				},
+				Domain:  "default",
+				Project: "test",
 			}
-			kv, _ = kvsvc.CreateOrUpdate(context.Background(), "default", kv, "test")
+			kv, _ = service.KVService.CreateOrUpdate(context.Background(), kv)
 			path := fmt.Sprintf("/v1/%s/kie/revision/%s", "test", kv.LabelID)
 			r, _ := http.NewRequest("GET", path, nil)
 			revision := &v1.HistoryResource{}
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index eebd1f5..ded2dfa 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -24,8 +24,7 @@ import (
 
 	"github.com/apache/servicecomb-kie/pkg/common"
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	kvsvc "github.com/apache/servicecomb-kie/server/service/kv"
+	"github.com/apache/servicecomb-kie/server/service"
 	goRestful "github.com/emicklei/go-restful"
 	"github.com/go-chassis/go-chassis/server/restful"
 	"github.com/go-mesh/openlogging"
@@ -55,7 +54,9 @@ func (r *KVResource) Put(context *restful.Context) {
 		WriteErrResponse(context, http.StatusInternalServerError, MsgDomainMustNotBeEmpty, common.ContentTypeText)
 	}
 	kv.Key = key
-	kv, err = kvsvc.CreateOrUpdate(context.Ctx, domain.(string), kv, project)
+	kv.Domain = domain.(string)
+	kv.Project = project
+	kv, err = service.KVService.CreateOrUpdate(context.Ctx, kv)
 	if err != nil {
 		ErrLog("put", kv, err)
 		WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
@@ -101,10 +102,10 @@ func (r *KVResource) GetByKey(context *restful.Context) {
 		WriteErrResponse(context, http.StatusBadRequest, MsgIllegalDepth, common.ContentTypeText)
 		return
 	}
-	kvs, err := kvsvc.FindKV(context.Ctx, domain.(string), project,
-		kvsvc.WithKey(key), kvsvc.WithLabels(labels), kvsvc.WithDepth(d))
+	kvs, err := service.KVService.FindKV(context.Ctx, domain.(string), project,
+		service.WithKey(key), service.WithLabels(labels), service.WithDepth(d))
 	if err != nil {
-		if err == db.ErrKeyNotExists {
+		if err == service.ErrKeyNotExists {
 			WriteErrResponse(context, http.StatusNotFound, err.Error(), common.ContentTypeText)
 			return
 		}
@@ -141,9 +142,9 @@ func (r *KVResource) SearchByLabels(context *restful.Context) {
 		openlogging.Debug("find by combination", openlogging.WithTags(openlogging.Tags{
 			"q": labels,
 		}))
-		result, err := kvsvc.FindKV(context.Ctx, domain.(string), project, kvsvc.WithLabels(labels))
+		result, err := service.KVService.FindKV(context.Ctx, domain.(string), project, service.WithLabels(labels))
 		if err != nil {
-			if err == db.ErrKeyNotExists {
+			if err == service.ErrKeyNotExists {
 				continue
 			} else {
 				openlogging.Error("can not find by labels", openlogging.WithTags(openlogging.Tags{
@@ -185,7 +186,7 @@ func (r *KVResource) Delete(context *restful.Context) {
 		return
 	}
 	labelID := context.ReadQueryParameter("labelID")
-	err := kvsvc.Delete(kvID, labelID, domain.(string), project)
+	err := service.KVService.Delete(kvID, labelID, domain.(string), project)
 	if err != nil {
 		openlogging.Error("delete failed ,", openlogging.WithTags(openlogging.Tags{
 			"kvID":    kvID,
diff --git a/server/resource/v1/kv_resource_test.go b/server/resource/v1/kv_resource_test.go
index afe9a25..c4c575e 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -20,6 +20,7 @@ package v1_test
 import (
 	"bytes"
 	"encoding/json"
+	"github.com/apache/servicecomb-kie/server/service"
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
@@ -32,9 +33,9 @@ import (
 
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/config"
-	"github.com/apache/servicecomb-kie/server/db"
 	noop "github.com/apache/servicecomb-kie/server/handler"
 	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
+	_ "github.com/apache/servicecomb-kie/server/service/mongo"
 )
 
 var _ = Describe("v1 kv resource", func() {
@@ -45,7 +46,7 @@ var _ = Describe("v1 kv resource", func() {
 
 	Describe("put kv", func() {
 		config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
-		err := db.Init()
+		err := service.DBInit()
 		It("should not return err", func() {
 			Expect(err).Should(BeNil())
 		})
diff --git a/server/resource/v1/v1_suite_test.go b/server/resource/v1/v1_suite_test.go
index 545cd80..422226d 100644
--- a/server/resource/v1/v1_suite_test.go
+++ b/server/resource/v1/v1_suite_test.go
@@ -22,6 +22,8 @@ import (
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+
+	_ "github.com/apache/servicecomb-kie/server/service/mongo"
 )
 
 func TestV1(t *testing.T) {
diff --git a/server/service/history/service.go b/server/service/history/service.go
deleted file mode 100644
index 3a78dae..0000000
--- a/server/service/history/service.go
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 history
-
-import (
-	"context"
-	"fmt"
-
-	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	"github.com/apache/servicecomb-kie/server/service/label"
-	"github.com/go-mesh/openlogging"
-	"go.mongodb.org/mongo-driver/bson"
-)
-
-//GetAndAddHistory get latest labels revision and call AddHistory
-func GetAndAddHistory(ctx context.Context,
-	labelID string, labels map[string]string, kvs []*model.KVDoc, domain string, project string) (int, error) {
-	ctx, cancel := context.WithTimeout(ctx, db.Timeout)
-	defer cancel()
-	r, err := label.GetLatestLabel(ctx, labelID)
-	if err != nil {
-		if err == db.ErrRevisionNotExist {
-			openlogging.Warn(fmt.Sprintf("label revision not exists, create first label revision"))
-			r = &model.LabelRevisionDoc{
-				LabelID:  labelID,
-				Labels:   labels,
-				Domain:   domain,
-				Revision: 0,
-			}
-		} else {
-			openlogging.Error(fmt.Sprintf("get latest [%s] in [%s],err: %s",
-				labelID, domain, err.Error()))
-			return 0, err
-		}
-
-	}
-	r.Revision, err = AddHistory(ctx, r, labelID, kvs)
-	if err != nil {
-		return 0, err
-	}
-	return r.Revision, nil
-}
-
-//GetHistoryByLabelID get all history by label id
-func GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error) {
-	ctx, cancel := context.WithTimeout(ctx, db.Timeout)
-	defer cancel()
-	filter := bson.M{"label_id": labelID}
-	return getHistoryByLabelID(ctx, filter)
-}
diff --git a/server/service/history/dao.go b/server/service/mongo/history/dao.go
similarity index 65%
rename from server/service/history/dao.go
rename to server/service/mongo/history/dao.go
index 476b361..f445be0 100644
--- a/server/service/history/dao.go
+++ b/server/service/mongo/history/dao.go
@@ -20,9 +20,10 @@ package history
 import (
 	"context"
 	"fmt"
-
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -32,7 +33,7 @@ import (
 //AddHistory increment labels revision and save current label stats to history, then update current revision to db
 func AddHistory(ctx context.Context,
 	labelRevision *model.LabelRevisionDoc, labelID string, kvs []*model.KVDoc) (int, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return 0, err
 	}
@@ -42,7 +43,7 @@ func AddHistory(ctx context.Context,
 	labelRevision.KVs = kvs
 	//clear prev id
 	labelRevision.ID = primitive.NilObjectID
-	collection := c.Database(db.Name).Collection(db.CollectionLabelRevision)
+	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
 	_, err = collection.InsertOne(ctx, labelRevision)
 	if err != nil {
 		openlogging.Error(err.Error())
@@ -53,7 +54,7 @@ func AddHistory(ctx context.Context,
 		openlogging.Error(fmt.Sprintf("convert %s,err:%s", labelID, err))
 		return 0, err
 	}
-	labelCollection := c.Database(db.Name).Collection(db.CollectionLabel)
+	labelCollection := c.Database(session.Name).Collection(session.CollectionLabel)
 	_, err = labelCollection.UpdateOne(ctx, bson.M{"_id": hex}, bson.D{
 		{"$set", bson.D{
 			{"revision", labelRevision.Revision},
@@ -67,11 +68,11 @@ func AddHistory(ctx context.Context,
 }
 
 func getHistoryByLabelID(ctx context.Context, filter bson.M) ([]*model.LabelRevisionDoc, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionLabelRevision)
+	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
 	cur, err := collection.Find(ctx, filter, options.Find().SetSort(map[string]interface{}{
 		"revisions": -1,
 	}))
@@ -92,7 +93,36 @@ func getHistoryByLabelID(ctx context.Context, filter bson.M) ([]*model.LabelRevi
 		rvs = append(rvs, &elem)
 	}
 	if !exist {
-		return nil, db.ErrRevisionNotExist
+		return nil, service.ErrRevisionNotExist
 	}
 	return rvs, nil
 }
+
+//GetAndAddHistory get latest labels revision and call AddHistory
+func GetAndAddHistory(ctx context.Context,
+	labelID string, labels map[string]string, kvs []*model.KVDoc, domain string, project string) (int, error) {
+	ctx, cancel := context.WithTimeout(ctx, session.Timeout)
+	defer cancel()
+	r, err := label.GetLatestLabel(ctx, labelID)
+	if err != nil {
+		if err == service.ErrRevisionNotExist {
+			openlogging.Warn(fmt.Sprintf("label revision not exists, create first label revision"))
+			r = &model.LabelRevisionDoc{
+				LabelID:  labelID,
+				Labels:   labels,
+				Domain:   domain,
+				Revision: 0,
+			}
+		} else {
+			openlogging.Error(fmt.Sprintf("get latest [%s] in [%s],err: %s",
+				labelID, domain, err.Error()))
+			return 0, err
+		}
+
+	}
+	r.Revision, err = AddHistory(ctx, r, labelID, kvs)
+	if err != nil {
+		return 0, err
+	}
+	return r.Revision, nil
+}
diff --git a/server/service/label/service.go b/server/service/mongo/history/service.go
similarity index 52%
rename from server/service/label/service.go
rename to server/service/mongo/history/service.go
index 745548f..d99c8af 100644
--- a/server/service/label/service.go
+++ b/server/service/mongo/history/service.go
@@ -15,30 +15,20 @@
  * limitations under the License.
  */
 
-package label
+package history
 
 import (
 	"context"
-	"fmt"
-
-	"github.com/apache/servicecomb-kie/server/db"
-	"github.com/go-mesh/openlogging"
-	"go.mongodb.org/mongo-driver/bson/primitive"
+	"github.com/apache/servicecomb-kie/pkg/model"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
-//Exist check whether the project has certain label or not and return label ID
-func Exist(ctx context.Context, domain string, project string, labels map[string]string) (primitive.ObjectID, error) {
-	l, err := FindLabels(ctx, domain, project, labels)
-	if err != nil {
-		if err.Error() == context.DeadlineExceeded.Error() {
-			openlogging.Error("find label failed, dead line exceeded", openlogging.WithTags(openlogging.Tags{
-				"timeout": db.Timeout,
-			}))
-			return primitive.NilObjectID, fmt.Errorf("operation timout %s", db.Timeout)
-		}
-		return primitive.NilObjectID, err
-	}
-
-	return l.ID, nil
+//Service is the implementation
+type Service struct {
+}
 
+//GetHistoryByLabelID get all history by label id
+func (s *Service) GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error) {
+	filter := bson.M{"label_id": labelID}
+	return getHistoryByLabelID(ctx, filter)
 }
diff --git a/server/service/history/tool.go b/server/service/mongo/history/tool.go
similarity index 100%
rename from server/service/history/tool.go
rename to server/service/mongo/history/tool.go
diff --git a/server/service/mongo/init.go b/server/service/mongo/init.go
new file mode 100644
index 0000000..057caa1
--- /dev/null
+++ b/server/service/mongo/init.go
@@ -0,0 +1,16 @@
+package mongo
+
+import (
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/history"
+	"github.com/apache/servicecomb-kie/server/service/mongo/kv"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
+	"github.com/go-mesh/openlogging"
+)
+
+func init() {
+	openlogging.Info("use mongodb as storage")
+	service.DBInit = session.Init
+	service.KVService = &kv.Service{}
+	service.HistoryService = &history.Service{}
+}
diff --git a/server/service/kv/dao.go b/server/service/mongo/kv/kv_dao.go
similarity index 77%
rename from server/service/kv/dao.go
rename to server/service/mongo/kv/kv_dao.go
index f35fb95..f9aef91 100644
--- a/server/service/kv/dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -15,16 +15,17 @@
  * limitations under the License.
  */
 
-package kvsvc
+package kv
 
 import (
 	"context"
 	"fmt"
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	"github.com/apache/servicecomb-kie/server/service/history"
-	"github.com/apache/servicecomb-kie/server/service/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/history"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -35,13 +36,13 @@ import (
 //and increase revision of label
 //and insert key
 func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
 	r, err := label.GetLatestLabel(ctx, kv.LabelID)
 	if err != nil {
-		if err != db.ErrRevisionNotExist {
+		if err != service.ErrRevisionNotExist {
 			openlogging.Error(fmt.Sprintf("get latest [%s][%s] in [%s],err: %s",
 				kv.Key, kv.Labels, kv.Domain, err.Error()))
 			return nil, err
@@ -53,7 +54,7 @@ func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
 	if r != nil {
 		r.Revision = r.Revision + 1
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	res, err := collection.InsertOne(ctx, kv)
 	if err != nil {
 		return nil, err
@@ -62,7 +63,7 @@ func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
 	kv.ID = objectID
 	kvs, err := findKeys(ctx, bson.M{"label_id": kv.LabelID}, true)
 	//Key may be empty When delete
-	if err != nil && err != db.ErrKeyNotExists {
+	if err != nil && err != service.ErrKeyNotExists {
 		return nil, err
 	}
 	revision, err := history.GetAndAddHistory(ctx, kv.LabelID, kv.Labels, kvs, kv.Domain, kv.Project)
@@ -81,11 +82,11 @@ func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
 //and increase revision of label
 //and updateKeyValue and them add new revision
 func updateKeyValue(ctx context.Context, kv *model.KVDoc) (int, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return 0, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	ur, err := collection.UpdateOne(ctx, bson.M{"key": kv.Key, "label_id": kv.LabelID}, bson.D{
 		{"$set", bson.D{
 			{"value", kv.Value},
@@ -100,7 +101,7 @@ func updateKeyValue(ctx context.Context, kv *model.KVDoc) (int, error) {
 			kv.Key, kv.Labels, kv.Value, ur.ModifiedCount))
 	kvs, err := findKeys(ctx, bson.M{"label_id": kv.LabelID}, true)
 	//Key may be empty When delete
-	if err != nil && err != db.ErrKeyNotExists {
+	if err != nil && err != service.ErrKeyNotExists {
 		return 0, err
 	}
 	revision, err := history.GetAndAddHistory(ctx, kv.LabelID, kv.Labels, kvs, kv.Domain, kv.Project)
@@ -116,12 +117,12 @@ func updateKeyValue(ctx context.Context, kv *model.KVDoc) (int, error) {
 
 }
 
-func findKV(ctx context.Context, domain string, project string, opts FindOptions) (*mongo.Cursor, error) {
-	c, err := db.GetClient()
+func findKV(ctx context.Context, domain string, project string, opts service.FindOptions) (*mongo.Cursor, error) {
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	ctx, _ = context.WithTimeout(ctx, opts.Timeout)
 	filter := bson.M{"domain": domain, "project": project}
 	if opts.Key != "" {
@@ -144,11 +145,11 @@ func findKV(ctx context.Context, domain string, project string, opts FindOptions
 	return cur, err
 }
 func findOneKey(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	sr := collection.FindOne(ctx, filter)
 	if sr.Err() != nil {
 		return nil, sr.Err()
@@ -157,7 +158,7 @@ func findOneKey(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
 	err = sr.Decode(curKV)
 	if err != nil {
 		if err == mongo.ErrNoDocuments {
-			return nil, db.ErrKeyNotExists
+			return nil, service.ErrKeyNotExists
 		}
 		openlogging.Error("decode error: " + err.Error())
 		return nil, err
@@ -165,13 +166,13 @@ func findOneKey(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
 	return []*model.KVDoc{curKV}, nil
 }
 
-//DeleteKV by kvID
-func DeleteKV(ctx context.Context, hexID primitive.ObjectID, project string) error {
-	c, err := db.GetClient()
+//deleteKV by kvID
+func deleteKV(ctx context.Context, hexID primitive.ObjectID, project string) error {
+	c, err := session.GetClient()
 	if err != nil {
 		return err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	dr, err := collection.DeleteOne(ctx, bson.M{"_id": hexID, "project": project})
 	//check error and delete number
 	if err != nil {
@@ -186,16 +187,16 @@ func DeleteKV(ctx context.Context, hexID primitive.ObjectID, project string) err
 	return err
 }
 func findKeys(ctx context.Context, filter bson.M, withoutLabel bool) ([]*model.KVDoc, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionKV)
+	collection := c.Database(session.Name).Collection(session.CollectionKV)
 	cur, err := collection.Find(ctx, filter)
 	if err != nil {
 		if err.Error() == context.DeadlineExceeded.Error() {
 			openlogging.Error("find kvs failed, dead line exceeded", openlogging.WithTags(openlogging.Tags{
-				"timeout": db.Timeout,
+				"timeout": session.Timeout,
 			}))
 			return nil, fmt.Errorf("can not find keys due to timout")
 		}
@@ -220,7 +221,21 @@ func findKeys(ctx context.Context, filter bson.M, withoutLabel bool) ([]*model.K
 
 	}
 	if len(kvs) == 0 {
-		return nil, db.ErrKeyNotExists
+		return nil, service.ErrKeyNotExists
 	}
 	return kvs, nil
 }
+
+//findKVByLabelID get kvs by key and label id
+//key can be empty, then it will return all key values
+//if key is given, will return 0-1 key value
+func findKVByLabelID(ctx context.Context, domain, labelID, key string, project string) ([]*model.KVDoc, error) {
+
+	filter := bson.M{"label_id": labelID, "domain": domain, "project": project}
+	if key != "" {
+		filter["key"] = key
+		return findOneKey(ctx, filter)
+	}
+	return findKeys(ctx, filter, true)
+
+}
diff --git a/server/service/kv/service.go b/server/service/mongo/kv/kv_service.go
similarity index 70%
rename from server/service/kv/service.go
rename to server/service/mongo/kv/kv_service.go
index 091e125..f9af41c 100644
--- a/server/service/kv/service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -15,25 +15,26 @@
  * limitations under the License.
  */
 
-package kvsvc
+package kv
 
 import (
 	"context"
 	"fmt"
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	"reflect"
 	"time"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
-	"github.com/apache/servicecomb-kie/server/service/history"
-	"github.com/apache/servicecomb-kie/server/service/label"
+	"github.com/apache/servicecomb-kie/server/service/mongo/history"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
 )
 
-//MongodbService operate data in mongodb
-type MongodbService struct {
+//Service operate data in mongodb
+type Service struct {
 	timeout time.Duration
 }
 
@@ -42,10 +43,10 @@ type MongodbService struct {
 //if label exists, then get its latest revision, and update current revision,
 //save the current label and its all key values to history collection
 //then check key exists or not, then create or update it
-func CreateOrUpdate(ctx context.Context, domain string, kv *model.KVDoc, project string) (*model.KVDoc, error) {
-	ctx, _ = context.WithTimeout(ctx, db.Timeout)
-	if domain == "" {
-		return nil, db.ErrMissingDomain
+func (s *Service) CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
+	ctx, _ = context.WithTimeout(ctx, session.Timeout)
+	if kv.Domain == "" {
+		return nil, session.ErrMissingDomain
 	}
 	if len(kv.Labels) == 0 {
 		kv.Labels = map[string]string{
@@ -54,12 +55,12 @@ func CreateOrUpdate(ctx context.Context, domain string, kv *model.KVDoc, project
 	}
 
 	//check whether the projecr has certain labels or not
-	labelID, err := label.Exist(ctx, domain, project, kv.Labels)
+	labelID, err := label.Exist(ctx, kv.Domain, kv.Project, kv.Labels)
 
 	var l *model.LabelDoc
 	if err != nil {
-		if err == db.ErrLabelNotExists {
-			l, err = label.CreateLabel(ctx, domain, kv.Labels, project)
+		if err == session.ErrLabelNotExists {
+			l, err = label.CreateLabel(ctx, kv.Domain, kv.Labels, kv.Project)
 			if err != nil {
 				openlogging.Error("create label failed", openlogging.WithTags(openlogging.Tags{
 					"k":      kv.Key,
@@ -74,14 +75,12 @@ func CreateOrUpdate(ctx context.Context, domain string, kv *model.KVDoc, project
 
 	}
 	kv.LabelID = labelID.Hex()
-	kv.Project = project
-	kv.Domain = domain
 	if kv.ValueType == "" {
-		kv.ValueType = db.DefaultValueType
+		kv.ValueType = session.DefaultValueType
 	}
-	keyID, err := KVExist(ctx, domain, kv.Key, kv.Project, WithLabelID(kv.LabelID))
+	keyID, err := s.Exist(ctx, kv.Domain, kv.Key, kv.Project, service.WithLabelID(kv.LabelID))
 	if err != nil {
-		if err == db.ErrKeyNotExists {
+		if err == service.ErrKeyNotExists {
 			kv, err := createKey(ctx, kv)
 			if err != nil {
 				return nil, err
@@ -104,26 +103,26 @@ func CreateOrUpdate(ctx context.Context, domain string, kv *model.KVDoc, project
 
 }
 
-//KVExist supports you query by label map or labels id
-func KVExist(ctx context.Context, domain, key string, project string, options ...FindOption) (primitive.ObjectID, error) {
-	ctx, _ = context.WithTimeout(context.Background(), db.Timeout)
-	opts := FindOptions{}
+//Exist supports you query by label map or labels id
+func (s *Service) Exist(ctx context.Context, domain, key string, project string, options ...service.FindOption) (primitive.ObjectID, error) {
+	ctx, _ = context.WithTimeout(context.Background(), session.Timeout)
+	opts := service.FindOptions{}
 	for _, o := range options {
 		o(&opts)
 	}
 	if opts.LabelID != "" {
-		kvs, err := FindKVByLabelID(ctx, domain, opts.LabelID, key, project)
+		kvs, err := findKVByLabelID(ctx, domain, opts.LabelID, key, project)
 		if err != nil {
 			return primitive.NilObjectID, err
 		}
 		return kvs[0].ID, nil
 	}
-	kvs, err := FindKV(ctx, domain, project, WithExactLabels(), WithLabels(opts.Labels), WithKey(key))
+	kvs, err := s.FindKV(ctx, domain, project, service.WithExactLabels(), service.WithLabels(opts.Labels), service.WithKey(key))
 	if err != nil {
 		return primitive.NilObjectID, err
 	}
 	if len(kvs) != 1 {
-		return primitive.NilObjectID, db.ErrTooMany
+		return primitive.NilObjectID, session.ErrTooMany
 	}
 
 	return kvs[0].Data[0].ID, nil
@@ -133,13 +132,13 @@ func KVExist(ctx context.Context, domain, key string, project string, options ..
 //Delete delete kv,If the labelID is "", query the collection kv to get it
 //domain=tenant
 //1.delete kv;2.add history
-func Delete(kvID string, labelID string, domain string, project string) error {
-	ctx, _ := context.WithTimeout(context.Background(), db.Timeout)
+func (s *Service) Delete(kvID string, labelID string, domain string, project string) error {
+	ctx, _ := context.WithTimeout(context.Background(), session.Timeout)
 	if domain == "" {
-		return db.ErrMissingDomain
+		return session.ErrMissingDomain
 	}
 	if project == "" {
-		return db.ErrMissingProject
+		return session.ErrMissingProject
 	}
 	hex, err := primitive.ObjectIDFromHex(kvID)
 	if err != nil {
@@ -160,20 +159,20 @@ func Delete(kvID string, labelID string, domain string, project string) error {
 	//get Label and check labelID
 	r, err := label.GetLatestLabel(ctx, labelID)
 	if err != nil {
-		if err == db.ErrRevisionNotExist {
+		if err == service.ErrRevisionNotExist {
 			openlogging.Warn(fmt.Sprintf("failed,kvID and labelID do not match"))
-			return db.ErrKvIDAndLabelIDNotMatch
+			return session.ErrKvIDAndLabelIDNotMatch
 		}
 		return err
 	}
 	//delete kv
-	err = DeleteKV(ctx, hex, project)
+	err = deleteKV(ctx, hex, project)
 	if err != nil {
 		return err
 	}
 	kvs, err := findKeys(ctx, bson.M{"label_id": labelID, "project": project}, true)
 	//Key may be empty When delete
-	if err != nil && err != db.ErrKeyNotExists {
+	if err != nil && err != service.ErrKeyNotExists {
 		return err
 	}
 	//Labels will not be empty when deleted
@@ -194,36 +193,22 @@ func Delete(kvID string, labelID string, domain string, project string) error {
 	return nil
 }
 
-//FindKVByLabelID get kvs by key and label id
-//key can be empty, then it will return all key values
-//if key is given, will return 0-1 key value
-func FindKVByLabelID(ctx context.Context, domain, labelID, key string, project string) ([]*model.KVDoc, error) {
-
-	filter := bson.M{"label_id": labelID, "domain": domain, "project": project}
-	if key != "" {
-		filter["key"] = key
-		return findOneKey(ctx, filter)
-	}
-	return findKeys(ctx, filter, true)
-
-}
-
 //FindKV get kvs by key, labels
 //because labels has a a lot of combination,
 //you can use WithDepth(0) to return only one kv which's labels exactly match the criteria
-func FindKV(ctx context.Context, domain string, project string, options ...FindOption) ([]*model.KVResponse, error) {
-	opts := FindOptions{}
+func (s *Service) FindKV(ctx context.Context, domain string, project string, options ...service.FindOption) ([]*model.KVResponse, error) {
+	opts := service.FindOptions{}
 	for _, o := range options {
 		o(&opts)
 	}
 	if opts.Timeout == 0 {
-		opts.Timeout = db.DefaultTimeout
+		opts.Timeout = session.DefaultTimeout
 	}
 	if domain == "" {
-		return nil, db.ErrMissingDomain
+		return nil, session.ErrMissingDomain
 	}
 	if project == "" {
-		return nil, db.ErrMissingProject
+		return nil, session.ErrMissingProject
 	}
 
 	cur, err := findKV(ctx, domain, project, opts)
@@ -288,7 +273,7 @@ func FindKV(ctx context.Context, domain string, project string, options ...FindO
 
 	}
 	if len(kvResp) == 0 {
-		return nil, db.ErrKeyNotExists
+		return nil, service.ErrKeyNotExists
 	}
 	return kvResp, nil
 
diff --git a/server/service/kv/kv_suite_test.go b/server/service/mongo/kv/kv_suite_test.go
similarity index 98%
rename from server/service/kv/kv_suite_test.go
rename to server/service/mongo/kv/kv_suite_test.go
index 0470d54..3eb253f 100644
--- a/server/service/kv/kv_suite_test.go
+++ b/server/service/mongo/kv/kv_suite_test.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package kvsvc_test
+package kv_test
 
 import (
 	"testing"
diff --git a/server/service/kv/kv_test.go b/server/service/mongo/kv/kv_test.go
similarity index 76%
rename from server/service/kv/kv_test.go
rename to server/service/mongo/kv/kv_test.go
index 1d5287c..70a3bd9 100644
--- a/server/service/kv/kv_test.go
+++ b/server/service/mongo/kv/kv_test.go
@@ -15,15 +15,15 @@
  * limitations under the License.
  */
 
-package kvsvc_test
+package kv_test
 
 import (
 	"context"
-
 	"github.com/apache/servicecomb-kie/pkg/model"
 	"github.com/apache/servicecomb-kie/server/config"
-	"github.com/apache/servicecomb-kie/server/db"
-	kvsvc "github.com/apache/servicecomb-kie/server/service/kv"
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/kv"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
@@ -32,22 +32,25 @@ var _ = Describe("Kv mongodb service", func() {
 	var err error
 	Describe("connecting db", func() {
 		config.Configurations = &config.Config{DB: config.DB{URI: "mongodb://kie:123@127.0.0.1:27017"}}
-		err = db.Init()
+		err = session.Init()
 		It("should not return err", func() {
 			Expect(err).Should(BeNil())
 		})
 	})
-
+	kvsvc := &kv.Service{}
 	Describe("put kv timeout", func() {
+
 		Context("with labels app and service", func() {
-			kv, err := kvsvc.CreateOrUpdate(context.TODO(), "default", &model.KVDoc{
+			kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
 				Key:   "timeout",
 				Value: "2s",
 				Labels: map[string]string{
 					"app":     "mall",
 					"service": "cart",
 				},
-			}, "test")
+				Domain:  "default",
+				Project: "test",
+			})
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -57,7 +60,7 @@ var _ = Describe("Kv mongodb service", func() {
 
 		})
 		Context("with labels app, service and version", func() {
-			kv, err := kvsvc.CreateOrUpdate(context.TODO(), "default", &model.KVDoc{
+			kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
 				Key:   "timeout",
 				Value: "2s",
 				Labels: map[string]string{
@@ -65,8 +68,10 @@ var _ = Describe("Kv mongodb service", func() {
 					"service": "cart",
 					"version": "1.0.0",
 				},
-			}, "test")
-			oid, err := kvsvc.KVExist(context.TODO(), "default", "timeout", "test", kvsvc.WithLabels(map[string]string{
+				Domain:  "default",
+				Project: "test",
+			})
+			oid, err := kvsvc.Exist(context.TODO(), "default", "timeout", "test", service.WithLabels(map[string]string{
 				"app":     "mall",
 				"service": "cart",
 				"version": "1.0.0",
@@ -82,43 +87,45 @@ var _ = Describe("Kv mongodb service", func() {
 			})
 		})
 		Context("with labels app,and update value", func() {
-			beforeKV, err := kvsvc.CreateOrUpdate(context.Background(), "default", &model.KVDoc{
-				Key:    "timeout",
-				Value:  "1s",
-				Domain: "default",
+			beforeKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
+				Key:   "timeout",
+				Value: "1s",
 				Labels: map[string]string{
 					"app": "mall",
 				},
-			}, "test")
+				Domain:  "default",
+				Project: "test",
+			})
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
-			kvs1, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithKey("timeout"), kvsvc.WithLabels(map[string]string{
+			kvs1, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
 				"app": "mall",
-			}), kvsvc.WithExactLabels())
+			}), service.WithExactLabels())
 			It("should be 1s", func() {
 				Expect(kvs1[0].Data[0].Value).Should(Equal(beforeKV.Value))
 			})
-			afterKV, err := kvsvc.CreateOrUpdate(context.Background(), "default", &model.KVDoc{
-				Key:    "timeout",
-				Value:  "3s",
-				Domain: "default",
+			afterKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
+				Key:   "timeout",
+				Value: "3s",
 				Labels: map[string]string{
 					"app": "mall",
 				},
-			}, "test")
+				Domain:  "default",
+				Project: "test",
+			})
 			It("should has same id", func() {
 				Expect(afterKV.ID.Hex()).Should(Equal(beforeKV.ID.Hex()))
 			})
-			oid, err := kvsvc.KVExist(context.Background(), "default", "timeout", "test", kvsvc.WithLabels(map[string]string{
+			oid, err := kvsvc.Exist(context.Background(), "default", "timeout", "test", service.WithLabels(map[string]string{
 				"app": "mall",
 			}))
 			It("should exists", func() {
 				Expect(oid.Hex()).Should(Equal(beforeKV.ID.Hex()))
 			})
-			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithKey("timeout"), kvsvc.WithLabels(map[string]string{
+			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
 				"app": "mall",
-			}), kvsvc.WithExactLabels())
+			}), service.WithExactLabels())
 			It("should be 3s", func() {
 				Expect(kvs[0].Data[0].Value).Should(Equal(afterKV.Value))
 			})
@@ -128,7 +135,7 @@ var _ = Describe("Kv mongodb service", func() {
 	Describe("greedy find by kv and labels", func() {
 		Context("with labels app,depth is 1 ", func() {
 			kvs, err := kvsvc.FindKV(context.Background(), "default", "test",
-				kvsvc.WithKey("timeout"), kvsvc.WithLabels(map[string]string{
+				service.WithKey("timeout"), service.WithLabels(map[string]string{
 					"app": "mall",
 				}))
 			It("should not return err", func() {
@@ -140,11 +147,11 @@ var _ = Describe("Kv mongodb service", func() {
 
 		})
 		Context("with labels app,depth is 2 ", func() {
-			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithKey("timeout"),
-				kvsvc.WithLabels(map[string]string{
+			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"),
+				service.WithLabels(map[string]string{
 					"app": "mall",
 				}),
-				kvsvc.WithDepth(2))
+				service.WithDepth(2))
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -156,9 +163,9 @@ var _ = Describe("Kv mongodb service", func() {
 	})
 	Describe("exact find by kv and labels", func() {
 		Context("with labels app ", func() {
-			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithKey("timeout"), kvsvc.WithLabels(map[string]string{
+			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
 				"app": "mall",
-			}), kvsvc.WithExactLabels())
+			}), service.WithExactLabels())
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -170,9 +177,9 @@ var _ = Describe("Kv mongodb service", func() {
 	})
 	Describe("exact find by labels", func() {
 		Context("with labels app ", func() {
-			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithLabels(map[string]string{
+			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithLabels(map[string]string{
 				"app": "mall",
-			}), kvsvc.WithExactLabels())
+			}), service.WithExactLabels())
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -184,7 +191,7 @@ var _ = Describe("Kv mongodb service", func() {
 	})
 	Describe("greedy find by labels", func() {
 		Context("with labels app ans service ", func() {
-			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", kvsvc.WithLabels(map[string]string{
+			kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithLabels(map[string]string{
 				"app":     "mall",
 				"service": "cart",
 			}))
@@ -200,13 +207,15 @@ var _ = Describe("Kv mongodb service", func() {
 
 	Describe("delete key", func() {
 		Context("delete key by kvID", func() {
-			kv1, err := kvsvc.CreateOrUpdate(context.Background(), "default", &model.KVDoc{
+			kv1, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
 				Key:   "timeout",
 				Value: "20s",
 				Labels: map[string]string{
 					"env": "test",
 				},
-			}, "test")
+				Domain:  "default",
+				Project: "test",
+			})
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -221,13 +230,15 @@ var _ = Describe("Kv mongodb service", func() {
 
 		})
 		Context("delete key by kvID and labelID", func() {
-			kv1, err := kvsvc.CreateOrUpdate(context.Background(), "default", &model.KVDoc{
+			kv1, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
 				Key:   "timeout",
 				Value: "20s",
 				Labels: map[string]string{
 					"env": "test",
 				},
-			}, "test")
+				Domain:  "default",
+				Project: "test",
+			})
 			It("should not return err", func() {
 				Expect(err).Should(BeNil())
 			})
@@ -256,7 +267,7 @@ var _ = Describe("Kv mongodb service", func() {
 		Context("Test miss domain error ", func() {
 			err := kvsvc.Delete("12312312321", "", "", "test")
 			It("should return err", func() {
-				Expect(err).Should(Equal(db.ErrMissingDomain))
+				Expect(err).Should(Equal(session.ErrMissingDomain))
 			})
 		})
 	})
diff --git a/server/service/kv/tool.go b/server/service/mongo/kv/tool.go
similarity index 95%
rename from server/service/kv/tool.go
rename to server/service/mongo/kv/tool.go
index c620135..cbf40ec 100644
--- a/server/service/kv/tool.go
+++ b/server/service/mongo/kv/tool.go
@@ -15,13 +15,13 @@
  * limitations under the License.
  */
 
-package kvsvc
+package kv
 
 import (
 	"context"
+	"github.com/apache/servicecomb-kie/server/service"
 
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/mongo"
 )
@@ -64,5 +64,5 @@ func cursorToOneKV(ctx context.Context, cur *mongo.Cursor, labels map[string]str
 		}
 
 	}
-	return nil, db.ErrKeyNotExists
+	return nil, service.ErrKeyNotExists
 }
diff --git a/server/service/label/dao.go b/server/service/mongo/label/label_dao.go
similarity index 64%
rename from server/service/label/dao.go
rename to server/service/mongo/label/label_dao.go
index 66acbaa..c8119b4 100644
--- a/server/service/label/dao.go
+++ b/server/service/mongo/label/label_dao.go
@@ -1,28 +1,11 @@
-/*
- * 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 label
 
 import (
 	"context"
 	"fmt"
-
 	"github.com/apache/servicecomb-kie/pkg/model"
-	"github.com/apache/servicecomb-kie/server/db"
+	"github.com/apache/servicecomb-kie/server/service"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
 	"github.com/go-mesh/openlogging"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -33,35 +16,14 @@ const (
 	defaultLabels = "default"
 )
 
-//CreateLabel create a new label
-func CreateLabel(ctx context.Context, domain string, labels map[string]string, project string) (*model.LabelDoc, error) {
-	c, err := db.GetClient()
-	if err != nil {
-		return nil, err
-	}
-	l := &model.LabelDoc{
-		Domain:  domain,
-		Labels:  labels,
-		Project: project,
-	}
-	collection := c.Database(db.Name).Collection(db.CollectionLabel)
-	res, err := collection.InsertOne(ctx, l)
-	if err != nil {
-		return nil, err
-	}
-	objectID, _ := res.InsertedID.(primitive.ObjectID)
-	l.ID = objectID
-	return l, nil
-}
-
 //FindLabels find label doc by labels and project, check if the project has certain labels
 //if map is empty. will return default labels doc which has no labels
-func FindLabels(ctx context.Context, domain string, project string, labels map[string]string) (*model.LabelDoc, error) {
-	c, err := db.GetClient()
+func FindLabels(ctx context.Context, domain, project string, labels map[string]string) (*model.LabelDoc, error) {
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionLabel)
+	collection := c.Database(session.Name).Collection(session.CollectionLabel)
 
 	filter := bson.M{"domain": domain, "project": project}
 	for k, v := range labels {
@@ -79,7 +41,7 @@ func FindLabels(ctx context.Context, domain string, project string, labels map[s
 	if cur.Err() != nil {
 		return nil, err
 	}
-	openlogging.Debug(fmt.Sprintf("find lables [%s] in [%s]", labels, domain))
+	openlogging.Debug(fmt.Sprintf("find labels [%s] in [%s]", labels, domain))
 	curLabel := &model.LabelDoc{} //reuse this pointer to reduce GC, only clear label
 	//check label length to get the exact match
 	for cur.Next(ctx) { //although complexity is O(n), but there won't be so much labels
@@ -96,16 +58,16 @@ func FindLabels(ctx context.Context, domain string, project string, labels map[s
 		}
 
 	}
-	return nil, db.ErrLabelNotExists
+	return nil, session.ErrLabelNotExists
 }
 
 //GetLatestLabel query revision table and find maximum revision number
 func GetLatestLabel(ctx context.Context, labelID string) (*model.LabelRevisionDoc, error) {
-	c, err := db.GetClient()
+	c, err := session.GetClient()
 	if err != nil {
 		return nil, err
 	}
-	collection := c.Database(db.Name).Collection(db.CollectionLabelRevision)
+	collection := c.Database(session.Name).Collection(session.CollectionLabelRevision)
 
 	filter := bson.M{"label_id": labelID}
 
@@ -127,7 +89,45 @@ func GetLatestLabel(ctx context.Context, labelID string) (*model.LabelRevisionDo
 		break
 	}
 	if !exist {
-		return nil, db.ErrRevisionNotExist
+		return nil, service.ErrRevisionNotExist
 	}
 	return h, nil
 }
+
+//Exist check whether the project has certain label or not and return label ID
+func Exist(ctx context.Context, domain string, project string, labels map[string]string) (primitive.ObjectID, error) {
+	l, err := FindLabels(ctx, domain, project, labels)
+	if err != nil {
+		if err.Error() == context.DeadlineExceeded.Error() {
+			openlogging.Error("find label failed, dead line exceeded", openlogging.WithTags(openlogging.Tags{
+				"timeout": session.Timeout,
+			}))
+			return primitive.NilObjectID, fmt.Errorf("operation timout %s", session.Timeout)
+		}
+		return primitive.NilObjectID, err
+	}
+
+	return l.ID, nil
+
+}
+
+//CreateLabel create a new label
+func CreateLabel(ctx context.Context, domain string, labels map[string]string, project string) (*model.LabelDoc, error) {
+	c, err := session.GetClient()
+	if err != nil {
+		return nil, err
+	}
+	l := &model.LabelDoc{
+		Domain:  domain,
+		Labels:  labels,
+		Project: project,
+	}
+	collection := c.Database(session.Name).Collection(session.CollectionLabel)
+	res, err := collection.InsertOne(ctx, l)
+	if err != nil {
+		return nil, err
+	}
+	objectID, _ := res.InsertedID.(primitive.ObjectID)
+	l.ID = objectID
+	return l, nil
+}
diff --git a/server/db/db.go b/server/service/mongo/session/session.go
similarity index 84%
rename from server/db/db.go
rename to server/service/mongo/session/session.go
index 93c82b7..f1596bc 100644
--- a/server/db/db.go
+++ b/server/service/mongo/session/session.go
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-//Package db manage db connection
-package db
+//Package session manage db connection
+package session
 
 import (
 	"context"
@@ -47,13 +47,12 @@ const (
 
 //db errors
 var (
-	ErrMissingDomain          = errors.New("domain info missing, illegal access")
-	ErrMissingProject         = errors.New("project info missing, illegal access")
-	ErrKeyNotExists           = errors.New("key with labels does not exits")
-	ErrLabelNotExists         = errors.New("labels does not exits")
-	ErrTooMany                = errors.New("key with labels should be only one")
-	ErrKeyMustNotEmpty        = errors.New("must supply key if you want to get exact one result")
-	ErrRevisionNotExist       = errors.New("label revision not exist")
+	ErrMissingDomain   = errors.New("domain info missing, illegal access")
+	ErrMissingProject  = errors.New("project info missing, illegal access")
+	ErrLabelNotExists  = errors.New("labels does not exits")
+	ErrTooMany         = errors.New("key with labels should be only one")
+	ErrKeyMustNotEmpty = errors.New("must supply key if you want to get exact one result")
+
 	ErrKVIDIsNil              = errors.New("kvID id is nil")
 	ErrKvIDAndLabelIDNotMatch = errors.New("kvID and labelID do not match")
 	ErrRootCAMissing          = errors.New("rootCAFile is empty in config file")
diff --git a/server/service/kv/options.go b/server/service/options.go
similarity index 99%
rename from server/service/kv/options.go
rename to server/service/options.go
index 5097edb..e8eb5cb 100644
--- a/server/service/kv/options.go
+++ b/server/service/options.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package kvsvc
+package service
 
 import "time"
 
diff --git a/server/service/service.go b/server/service/service.go
new file mode 100644
index 0000000..0338091
--- /dev/null
+++ b/server/service/service.go
@@ -0,0 +1,35 @@
+package service
+
+import (
+	"context"
+	"errors"
+	"github.com/apache/servicecomb-kie/pkg/model"
+)
+
+//services
+var (
+	KVService      KV
+	HistoryService History
+	DBInit         Init
+)
+
+//db errors
+var (
+	ErrKeyNotExists     = errors.New("key with labels does not exits")
+	ErrRevisionNotExist = errors.New("label revision not exist")
+)
+
+//KV provide api of KV entity
+type KV interface {
+	CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error)
+	Delete(kvID string, labelID string, domain, project string) error
+	FindKV(ctx context.Context, domain, project string, options ...FindOption) ([]*model.KVResponse, error)
+}
+
+//History provide api of History entity
+type History interface {
+	GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error)
+}
+
+//Init init db session
+type Init func() error