This is an automated email from the ASF dual-hosted git repository.
tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new e436f72 Framework for service-center to support different storage
(#695)
e436f72 is described below
commit e436f72204c8ed7777c7b7af3428680ae4ff077e
Author: popozy <[email protected]>
AuthorDate: Thu Sep 24 11:04:09 2020 +0800
Framework for service-center to support different storage (#695)
1. Input: apply resources type(instances, service, tag, etc.) crud
operation for api service layer
2. Action: construct kv for different database(mongo, etcd) using the
inputs, request from api
3. Output: invoke registry/dicovery plugin to finish crud operation
---
go.mod | 3 +-
go.sum | 18 +++++
server/service/auth/datasource.go | 33 +++++++++
server/service/auth/etcd/etcd.go | 94 +++++++++++++++++++++++++
server/service/auth/manager.go | 58 +++++++++++++++
server/service/auth/manager_test.go | 48 +++++++++++++
server/service/auth/options.go | 22 ++++++
server/service/auth/types.go | 18 +++++
server/service/dep/datasource.go | 23 ++++++
server/service/dep/etcd/etcd.go | 62 ++++++++++++++++
server/service/dep/manager.go | 58 +++++++++++++++
server/service/dep/manager_test.go | 48 +++++++++++++
server/service/dep/options.go | 22 ++++++
server/service/dep/types.go | 18 +++++
server/service/microservice_test.go | 19 +++++
server/service/ms/datasource.go | 48 +++++++++++++
server/service/ms/etcd/etcd.go | 136 ++++++++++++++++++++++++++++++++++++
server/service/ms/manager.go | 58 +++++++++++++++
server/service/ms/manager_test.go | 69 ++++++++++++++++++
server/service/ms/options.go | 22 ++++++
server/service/ms/types.go | 18 +++++
21 files changed, 894 insertions(+), 1 deletion(-)
diff --git a/go.mod b/go.mod
index b668390..76f2622 100644
--- a/go.mod
+++ b/go.mod
@@ -19,6 +19,7 @@ require (
github.com/hashicorp/serf v0.8.3
github.com/karlseguin/ccache
v2.0.3-0.20170217060820-3ba9789cfd2c+incompatible
github.com/labstack/echo
v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible
+ github.com/labstack/echo/v4 v4.1.17
github.com/natefinch/lumberjack v0.0.0-20170531160350-a96e63847dc3
github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84
github.com/onsi/ginkgo v1.10.1
@@ -36,7 +37,7 @@ require (
github.com/stretchr/testify v1.4.0
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
go.uber.org/zap v1.10.0
- golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
+ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
google.golang.org/grpc v1.19.0
gopkg.in/yaml.v2 v2.2.4
diff --git a/go.sum b/go.sum
index c01032c..d4a8025 100644
--- a/go.sum
+++ b/go.sum
@@ -290,10 +290,14 @@ github.com/kubernetes/api
v0.0.0-20180601181742-8b7507fac302/go.mod h1:o5K7QWn2B
github.com/kubernetes/apimachinery v0.0.0-20180601181227-17529ec7eadb/go.mod
h1:Pe/YBTPc3vqoMkbuIWPH8CF9ehINdvNyS0dP3J6HC0s=
github.com/kubernetes/client-go v0.0.0-20180817174322-745ca8300397
h1:jx8QGtpqZkPXUz+DceA5DKIOXb0oTISb9th5GmJC4WE=
github.com/kubernetes/client-go v0.0.0-20180817174322-745ca8300397/go.mod
h1:kszVi2i+FeqECZHhjpkV5h5zM0GnURfJv897YzgoAQ8=
+github.com/labstack/echo v1.4.4 h1:1bEiBNeGSUKxcPDGfZ/7IgdhJJZx8wV/pICJh4W2NJI=
github.com/labstack/echo v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible
h1:myCOvigjM7zY/vWklhLPEw9HaOSrPXNtNGsZ3w6RHWs=
github.com/labstack/echo
v3.2.2-0.20180316170059-a5d81b8d4a62+incompatible/go.mod
h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
+github.com/labstack/echo v3.3.10+incompatible
h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo/v4 v4.1.16
h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
github.com/labstack/echo/v4 v4.1.16/go.mod
h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
+github.com/labstack/echo/v4 v4.1.17
h1:PQIBaRplyRy3OjwILGkPg89JRtH2x5bssi59G2EL3fo=
+github.com/labstack/echo/v4 v4.1.17/go.mod
h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
github.com/labstack/gommon v0.2.1
h1:C+I4NYknueQncqKYZQ34kHsLZJVeB5KwPUhnO0nmbpU=
github.com/labstack/gommon v0.2.1/go.mod
h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/labstack/gommon v0.3.0
h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
@@ -304,6 +308,8 @@ github.com/mattn/go-colorable v0.0.9/go.mod
h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-colorable v0.1.2/go.mod
h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6
h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod
h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.7
h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
+github.com/mattn/go-colorable v0.1.7/go.mod
h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod
h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7
h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod
h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -432,6 +438,8 @@ github.com/valyala/fasttemplate
v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50w
github.com/valyala/fasttemplate v1.0.1/go.mod
h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0
h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod
h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/fasttemplate v1.2.1
h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
+github.com/valyala/fasttemplate v1.2.1/go.mod
h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
h1:ieRJ8K7QAPWWltEOv7rzMruuPd7gbeAqTaBFhUECIy0=
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b/go.mod
h1:9W1pyetRkwXqjR9tjOSrSuhGHBK0EqXoQSwWbhBHHwA=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0
h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
@@ -461,6 +469,9 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586
h1:7KByu05hhLed2MO29w7p1X
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -489,6 +500,8 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
h1:rjwSpXsdiK0dV8/Naq3kAw9ym
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200822124328-c89045814202
h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod
h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
@@ -520,12 +533,17 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5
h1:LfCXLvNmTYH9kEmVgqbnsWfru
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae
h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6
h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/server/service/auth/datasource.go
b/server/service/auth/datasource.go
new file mode 100644
index 0000000..d627c96
--- /dev/null
+++ b/server/service/auth/datasource.go
@@ -0,0 +1,33 @@
+// 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 auth
+
+type DataSource interface {
+ AddAccount()
+ GetAccount()
+ UpdateAccount()
+ DeleteAccount()
+
+ AddDomain()
+ GetDomain()
+ UpdateDomain()
+ DeleteDomain()
+
+ AddDomainProject()
+ GetDomainProject()
+ UpdateDomainProject()
+ DeleteDomainProject()
+}
diff --git a/server/service/auth/etcd/etcd.go b/server/service/auth/etcd/etcd.go
new file mode 100644
index 0000000..6a194e8
--- /dev/null
+++ b/server/service/auth/etcd/etcd.go
@@ -0,0 +1,94 @@
+// 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 etcd
+
+import (
+ "github.com/apache/servicecomb-service-center/pkg/log"
+)
+
+// TODO: define error with names here
+
+func init() {
+ // TODO: set logger
+ // TODO: register storage plugin to plugin manager
+}
+
+type DataSource struct{}
+
+func NewDataSource() *DataSource {
+ // TODO: construct a reasonable DataSource instance
+ log.Warnf("auth data source enable etcd mode")
+
+ inst := &DataSource{}
+ // TODO: deal with exception
+ if err := inst.initialize(); err != nil {
+ return inst
+ }
+ return inst
+}
+
+func (ds *DataSource) initialize() error {
+ // TODO: init DataSource members
+ return nil
+}
+
+func (ds *DataSource) AddAccount() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetAccount() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateAccount() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteAccount() {
+ panic("implement me")
+}
+
+func (ds *DataSource) AddDomain() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetDomain() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateDomain() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteDomain() {
+ panic("implement me")
+}
+
+func (ds *DataSource) AddDomainProject() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetDomainProject() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateDomainProject() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteDomainProject() {
+ panic("implement me")
+}
diff --git a/server/service/auth/manager.go b/server/service/auth/manager.go
new file mode 100644
index 0000000..c772e23
--- /dev/null
+++ b/server/service/auth/manager.go
@@ -0,0 +1,58 @@
+// 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 auth
+
+import (
+ "fmt"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+)
+
+type dataSourceEngine func(opts Options) (DataSource, error)
+
+var (
+ plugins = make(map[ImplName]dataSourceEngine)
+ authDataSourceInst DataSource
+)
+
+// load plugins configuration into plugins
+func Install(pluginImplName string, engineFunc dataSourceEngine) {
+ plugins[ImplName(pluginImplName)] = engineFunc
+}
+
+// construct storage plugin instance
+// invoked by sc main process
+func Init(opts Options) error {
+ if opts.PluginImplName == "" {
+ return nil
+ }
+
+ authDataSourceEngine, ok := plugins[opts.PluginImplName]
+ if !ok {
+ return fmt.Errorf("plugin implement not supported [%s]",
opts.PluginImplName)
+ }
+ var err error
+ authDataSourceInst, err = authDataSourceEngine(opts)
+ if err != nil {
+ return err
+ }
+ log.Info(fmt.Sprintf("storage shim plugin [%s@%s] enabled",
opts.PluginImplName, opts.Endpoint))
+ return nil
+}
+
+// usage: auth.Auth().CreateAccount()
+func Auth() DataSource {
+ return authDataSourceInst
+}
diff --git a/server/service/auth/manager_test.go
b/server/service/auth/manager_test.go
new file mode 100644
index 0000000..40c77a9
--- /dev/null
+++ b/server/service/auth/manager_test.go
@@ -0,0 +1,48 @@
+// 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 auth
+
+import (
+ "github.com/apache/servicecomb-service-center/server/service/auth/etcd"
+ "github.com/go-chassis/go-archaius"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestInit(t *testing.T) {
+ _ = archaius.Init(archaius.WithMemorySource())
+ _ = archaius.Set("servicecomb.auth.name", "etcd")
+ t.Run("circuit datasource auth", func(t *testing.T) {
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName: "",
+ })
+ assert.NoError(t, err)
+ })
+ t.Run("install and init", func(t *testing.T) {
+ Install("etcd",
+ func(opts Options) (DataSource, error) {
+ return etcd.NewDataSource(), nil
+ })
+
+ // sc main function initialize step
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName:
ImplName(archaius.GetString("servicecomb.auth.name", "etcd")),
+ })
+ assert.NoError(t, err)
+ })
+}
diff --git a/server/service/auth/options.go b/server/service/auth/options.go
new file mode 100644
index 0000000..3166411
--- /dev/null
+++ b/server/service/auth/options.go
@@ -0,0 +1,22 @@
+// 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 auth
+
+//Options contains configuration for plugins
+type Options struct {
+ Endpoint string
+ PluginImplName ImplName
+}
diff --git a/server/service/auth/types.go b/server/service/auth/types.go
new file mode 100644
index 0000000..01355e3
--- /dev/null
+++ b/server/service/auth/types.go
@@ -0,0 +1,18 @@
+// 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 auth
+
+type ImplName string
diff --git a/server/service/dep/datasource.go b/server/service/dep/datasource.go
new file mode 100644
index 0000000..d26d969
--- /dev/null
+++ b/server/service/dep/datasource.go
@@ -0,0 +1,23 @@
+// 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 dep
+
+type DataSource interface {
+ AddDependency()
+ SearchDependency()
+ UpdateDependency()
+ DeleteDependency()
+}
diff --git a/server/service/dep/etcd/etcd.go b/server/service/dep/etcd/etcd.go
new file mode 100644
index 0000000..c2e2c02
--- /dev/null
+++ b/server/service/dep/etcd/etcd.go
@@ -0,0 +1,62 @@
+// 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 etcd
+
+import (
+ "github.com/apache/servicecomb-service-center/pkg/log"
+)
+
+// TODO: define error with names here
+
+func init() {
+ // TODO: set logger
+ // TODO: register storage plugin to plugin manager
+}
+
+type DataSource struct{}
+
+func NewDataSource() *DataSource {
+ // TODO: construct a reasonable DataSource instance
+ log.Warnf("dependency data source enable etcd mode")
+
+ inst := &DataSource{}
+ // TODO: deal with exception
+ if err := inst.initialize(); err != nil {
+ return inst
+ }
+ return inst
+}
+
+func (ds *DataSource) initialize() error {
+ // TODO: init dependency members
+ return nil
+}
+
+func (ds *DataSource) AddDependency() {
+ panic("implement me")
+}
+
+func (ds *DataSource) SearchDependency() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateDependency() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteDependency() {
+ panic("implement me")
+}
diff --git a/server/service/dep/manager.go b/server/service/dep/manager.go
new file mode 100644
index 0000000..1ff12ed
--- /dev/null
+++ b/server/service/dep/manager.go
@@ -0,0 +1,58 @@
+// 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 dep
+
+import (
+ "fmt"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+)
+
+type dataSourceEngine func(opts Options) (DataSource, error)
+
+var (
+ plugins = make(map[ImplName]dataSourceEngine)
+ depDataSourceInst DataSource
+)
+
+// load plugins configuration into plugins
+func Install(pluginImplName string, engineFunc dataSourceEngine) {
+ plugins[ImplName(pluginImplName)] = engineFunc
+}
+
+// construct storage plugin instance
+// invoked by sc main process
+func Init(opts Options) error {
+ if opts.PluginImplName == "" {
+ return nil
+ }
+
+ depDataSourceEngine, ok := plugins[opts.PluginImplName]
+ if !ok {
+ return fmt.Errorf("dependency datasource implementation not
supported [%s]", opts.PluginImplName)
+ }
+ var err error
+ depDataSourceInst, err = depDataSourceEngine(opts)
+ if err != nil {
+ return err
+ }
+ log.Info(fmt.Sprintf("dependency datasource mgt [%s@%s] enabled",
opts.PluginImplName, opts.Endpoint))
+ return nil
+}
+
+// usage: dep.Dependency()
+func Dependency() DataSource {
+ return depDataSourceInst
+}
diff --git a/server/service/dep/manager_test.go
b/server/service/dep/manager_test.go
new file mode 100644
index 0000000..f51cffb
--- /dev/null
+++ b/server/service/dep/manager_test.go
@@ -0,0 +1,48 @@
+// 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 dep
+
+import (
+ "github.com/apache/servicecomb-service-center/server/service/dep/etcd"
+ "github.com/go-chassis/go-archaius"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestInit(t *testing.T) {
+ _ = archaius.Init(archaius.WithMemorySource())
+ _ = archaius.Set("servicecomb.dep.name", "etcd")
+ t.Run("circuit dependency data source plugin", func(t *testing.T) {
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName: "",
+ })
+ assert.NoError(t, err)
+ })
+ t.Run(" dependency data source plugin install and init", func(t
*testing.T) {
+ Install("etcd",
+ func(opts Options) (DataSource, error) {
+ return etcd.NewDataSource(), nil
+ })
+
+ // sc main function initialize step
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName:
ImplName(archaius.GetString("servicecomb.dep.name", "etcd")),
+ })
+ assert.NoError(t, err)
+ })
+}
diff --git a/server/service/dep/options.go b/server/service/dep/options.go
new file mode 100644
index 0000000..f985069
--- /dev/null
+++ b/server/service/dep/options.go
@@ -0,0 +1,22 @@
+// 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 dep
+
+//Options contains configuration for plugins
+type Options struct {
+ Endpoint string
+ PluginImplName ImplName
+}
diff --git a/server/service/dep/types.go b/server/service/dep/types.go
new file mode 100644
index 0000000..34e0835
--- /dev/null
+++ b/server/service/dep/types.go
@@ -0,0 +1,18 @@
+// 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 dep
+
+type ImplName string
diff --git a/server/service/microservice_test.go
b/server/service/microservice_test.go
index ce8b0ba..2d8e779 100644
--- a/server/service/microservice_test.go
+++ b/server/service/microservice_test.go
@@ -22,6 +22,9 @@ import (
"github.com/apache/servicecomb-service-center/server/core/proto"
"github.com/apache/servicecomb-service-center/server/plugin/quota"
scerr "github.com/apache/servicecomb-service-center/server/scerror"
+ "github.com/apache/servicecomb-service-center/server/service/ms"
+ "github.com/apache/servicecomb-service-center/server/service/ms/etcd"
+ "github.com/go-chassis/go-archaius"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"strconv"
@@ -49,6 +52,22 @@ var _ = Describe("'Micro-service' service", func() {
Expect(err).To(BeNil())
Expect(resp.Response.GetCode()).To(Equal(scerr.ErrInvalidParams))
})
+
+ It("ms datasource etcd mode: should not be passed",
func() {
+ ms.Install("etcd",
+ func(opts ms.Options) (ms.DataSource,
error) {
+ return etcd.NewDataSource(), nil
+ })
+
+ // sc main function initialize step
+ err := ms.Init(ms.Options{
+ Endpoint: "",
+ PluginImplName:
ms.ImplName(archaius.GetString("servicecomb.ms.name", "etcd")),
+ })
+ resp, err :=
ms.MicroService().RegisterService(getContext(),
&pb.CreateServiceRequest{Service: nil})
+ Expect(err).To(BeNil())
+
Expect(resp.Response.GetCode()).To(Equal(scerr.ErrInvalidParams))
+ })
})
Context("all max", func() {
diff --git a/server/service/ms/datasource.go b/server/service/ms/datasource.go
new file mode 100644
index 0000000..f704a84
--- /dev/null
+++ b/server/service/ms/datasource.go
@@ -0,0 +1,48 @@
+// 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 ms
+
+import (
+ "context"
+ pb "github.com/apache/servicecomb-service-center/pkg/registry"
+)
+
+type DataSource interface {
+ RegisterService(ctx context.Context, service *pb.CreateServiceRequest)
(*pb.CreateServiceResponse, error)
+ GetService(ctx context.Context, service *pb.GetServiceRequest)
+ UpdateService(ctx context.Context, service
*pb.UpdateServicePropsRequest)
+ UnregisterService(ctx context.Context, service *pb.DeleteServiceRequest)
+
+ RegisterInstance()
+ SearchInstance()
+ UpdateInstance()
+ UnRegisterInstance()
+
+ AddSchema()
+ GetSchema()
+ UpdateSchema()
+ DeleteSchema()
+
+ AddTag()
+ GetTag()
+ UpdateTag()
+ DeleteTag()
+
+ AddRule()
+ GetRule()
+ UpdateRule()
+ DeleteRule()
+}
diff --git a/server/service/ms/etcd/etcd.go b/server/service/ms/etcd/etcd.go
new file mode 100644
index 0000000..10a6ba1
--- /dev/null
+++ b/server/service/ms/etcd/etcd.go
@@ -0,0 +1,136 @@
+// 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 etcd
+
+import (
+ "context"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+ pb "github.com/apache/servicecomb-service-center/pkg/registry"
+ "github.com/apache/servicecomb-service-center/server/core/proto"
+ scerr "github.com/apache/servicecomb-service-center/server/scerror"
+)
+
+// TODO: define error with names here
+
+func init() {
+ // TODO: set logger
+ // TODO: register storage plugin to plugin manager
+}
+
+type DataSource struct{}
+
+func NewDataSource() *DataSource {
+ // TODO: construct a reasonable DataSource instance
+ log.Warnf("microservice mgt data source enable etcd mode")
+
+ inst := &DataSource{}
+ // TODO: deal with exception
+ if err := inst.initialize(); err != nil {
+ return inst
+ }
+ return inst
+}
+
+func (ds *DataSource) initialize() error {
+ // TODO: init DataSource members
+ return nil
+}
+
+func (ds *DataSource) RegisterService(ctx context.Context, service
*pb.CreateServiceRequest) (*pb.CreateServiceResponse, error) {
+ if service == nil || service.Service == nil {
+ log.Errorf(nil, "create micro-service failed: request body is
empty")
+ return &pb.CreateServiceResponse{
+ Response: proto.CreateResponse(scerr.ErrInvalidParams,
"Request body is empty"),
+ }, nil
+ }
+ return nil, nil
+}
+
+func (ds *DataSource) GetService(ctx context.Context, service
*pb.GetServiceRequest) {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateService(ctx context.Context, service
*pb.UpdateServicePropsRequest) {
+ panic("implement me")
+}
+
+func (ds *DataSource) UnregisterService(ctx context.Context, service
*pb.DeleteServiceRequest) {
+ panic("implement me")
+}
+
+func (ds *DataSource) RegisterInstance() {
+ panic("implement me")
+}
+
+func (ds *DataSource) SearchInstance() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateInstance() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UnRegisterInstance() {
+ panic("implement me")
+}
+
+func (ds *DataSource) AddSchema() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetSchema() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateSchema() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteSchema() {
+ panic("implement me")
+}
+
+func (ds *DataSource) AddTag() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetTag() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateTag() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteTag() {
+ panic("implement me")
+}
+
+func (ds *DataSource) AddRule() {
+ panic("implement me")
+}
+
+func (ds *DataSource) GetRule() {
+ panic("implement me")
+}
+
+func (ds *DataSource) UpdateRule() {
+ panic("implement me")
+}
+
+func (ds *DataSource) DeleteRule() {
+ panic("implement me")
+}
diff --git a/server/service/ms/manager.go b/server/service/ms/manager.go
new file mode 100644
index 0000000..0453020
--- /dev/null
+++ b/server/service/ms/manager.go
@@ -0,0 +1,58 @@
+// 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 ms
+
+import (
+ "fmt"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+)
+
+type dataSourceEngine func(opts Options) (DataSource, error)
+
+var (
+ plugins = make(map[ImplName]dataSourceEngine)
+ msDataSourceInst DataSource
+)
+
+// load plugins configuration into plugins
+func Install(pluginImplName string, engineFunc dataSourceEngine) {
+ plugins[ImplName(pluginImplName)] = engineFunc
+}
+
+// construct storage plugin instance
+// invoked by sc main process
+func Init(opts Options) error {
+ if opts.PluginImplName == "" {
+ return nil
+ }
+
+ msDataSourceEngine, ok := plugins[opts.PluginImplName]
+ if !ok {
+ return fmt.Errorf("microservice datasource implementation not
supported [%s]", opts.PluginImplName)
+ }
+ var err error
+ msDataSourceInst, err = msDataSourceEngine(opts)
+ if err != nil {
+ return err
+ }
+ log.Info(fmt.Sprintf("microservice datasource mgt [%s@%s] enabled",
opts.PluginImplName, opts.Endpoint))
+ return nil
+}
+
+// usage: ms.MicroService().create()
+func MicroService() DataSource {
+ return msDataSourceInst
+}
diff --git a/server/service/ms/manager_test.go
b/server/service/ms/manager_test.go
new file mode 100644
index 0000000..b8f594b
--- /dev/null
+++ b/server/service/ms/manager_test.go
@@ -0,0 +1,69 @@
+// 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 ms
+
+import (
+ "context"
+ pb "github.com/apache/servicecomb-service-center/pkg/registry"
+ "github.com/apache/servicecomb-service-center/pkg/util"
+ scerr "github.com/apache/servicecomb-service-center/server/scerror"
+ "github.com/apache/servicecomb-service-center/server/service/ms/etcd"
+ "github.com/go-chassis/go-archaius"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestInit(t *testing.T) {
+ _ = archaius.Init(archaius.WithMemorySource())
+ _ = archaius.Set("servicecomb.ms.name", "etcd")
+ t.Run("circuit microservice data source plugin", func(t *testing.T) {
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName: "",
+ })
+ assert.NoError(t, err)
+ })
+ t.Run("microservice data source plugin install and init", func(t
*testing.T) {
+ Install("etcd", func(opts Options) (DataSource, error) {
+ return etcd.NewDataSource(), nil
+ })
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName:
ImplName(archaius.GetString("servicecomb.ms.name", "etcd")),
+ })
+ assert.NoError(t, err)
+ })
+ t.Run("Register service,should success", func(t *testing.T) {
+ Install("etcd", func(opts Options) (DataSource, error) {
+ return etcd.NewDataSource(), nil
+ })
+
+ err := Init(Options{
+ Endpoint: "",
+ PluginImplName:
ImplName(archaius.GetString("servicecomb.ms.name", "etcd")),
+ })
+ assert.NoError(t, err)
+ resp, err := MicroService().RegisterService(getContext(),
&pb.CreateServiceRequest{Service: nil})
+ assert.NotNil(t, resp)
+ assert.Equal(t, resp.Response.GetCode(), scerr.ErrInvalidParams)
+ })
+}
+
+func getContext() context.Context {
+ return util.SetContext(
+ util.SetDomainProject(context.Background(), "default",
"default"),
+ util.CtxNocache, "1")
+}
diff --git a/server/service/ms/options.go b/server/service/ms/options.go
new file mode 100644
index 0000000..485bcf5
--- /dev/null
+++ b/server/service/ms/options.go
@@ -0,0 +1,22 @@
+// 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 ms
+
+//Options contains configuration for plugins
+type Options struct {
+ Endpoint string
+ PluginImplName ImplName
+}
diff --git a/server/service/ms/types.go b/server/service/ms/types.go
new file mode 100644
index 0000000..7046d0f
--- /dev/null
+++ b/server/service/ms/types.go
@@ -0,0 +1,18 @@
+// 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 ms
+
+type ImplName string