From dd2abb94e880cc433f6a6f053bc649b70239085c Mon Sep 17 00:00:00 2001
From: "vito.he" <hxmhlt@163.com>
Date: Sat, 14 Mar 2020 21:42:11 +0800
Subject: [PATCH] Add:interface definition of metadata

---
 common/constant/key.go                        |  8 +-
 common/extension/metadata_report_factory.go   | 39 ++++++++
 config/consumer_config.go                     | 16 +---
 config/metadata_report_config.go              | 23 +++++
 config/metadata_report_config_test.go         |  6 +-
 config/provider_config.go                     |  5 +-
 metadata/definition/definition.go             | 41 +++++++++
 metadata/exporter.go                          | 27 ++++++
 .../identifier/base_metadata_identifier.go    | 92 +++++++++++++++++++
 metadata/identifier/metadata_identifier.go    | 33 +++++++
 .../identifier/service_metadata_identifier.go | 36 ++++++++
 .../subscribe_metadata_identifier.go          | 16 ++++
 metadata/instance.go                          | 40 ++++++++
 metadata/report.go                            | 35 +++++++
 metadata/report_factory.go                    | 28 ++++++
 metadata/service.go                           | 37 ++++++++
 16 files changed, 467 insertions(+), 15 deletions(-)
 create mode 100644 common/extension/metadata_report_factory.go
 create mode 100644 metadata/definition/definition.go
 create mode 100644 metadata/exporter.go
 create mode 100644 metadata/identifier/base_metadata_identifier.go
 create mode 100644 metadata/identifier/metadata_identifier.go
 create mode 100644 metadata/identifier/service_metadata_identifier.go
 create mode 100644 metadata/identifier/subscribe_metadata_identifier.go
 create mode 100644 metadata/instance.go
 create mode 100644 metadata/report.go
 create mode 100644 metadata/report_factory.go
 create mode 100644 metadata/service.go

diff --git a/common/constant/key.go b/common/constant/key.go
index b2afb0162..4794842bc 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -164,6 +164,10 @@ const (
 // metadata report
 
 const (
-	METACONFIG_REMOTE = "remote"
-	METACONFIG_LOCAL  = "local"
+	METACONFIG_REMOTE  = "remote"
+	METACONFIG_LOCAL   = "local"
+	KEY_SEPARATOR      = ":"
+	DEFAULT_PATH_TAG   = "metadata"
+	PATH_SEPARATOR     = "/"
+	KEY_REVISON_PREFIX = "revision"
 )
diff --git a/common/extension/metadata_report_factory.go b/common/extension/metadata_report_factory.go
new file mode 100644
index 000000000..a28eb2e3c
--- /dev/null
+++ b/common/extension/metadata_report_factory.go
@@ -0,0 +1,39 @@
+/*
+ * 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 extension
+
+import (
+	"github.com/apache/dubbo-go/metadata"
+)
+
+var (
+	metaDataReportFactories = make(map[string]func() metadata.MetadataReportFactory)
+)
+
+// SetMetadataReportFactory ...
+func SetMetadataReportFactory(name string, v func() metadata.MetadataReportFactory) {
+	metaDataReportFactories[name] = v
+}
+
+// GetConfigCenterFactory ...
+func GetMetadataReportFactory(name string) metadata.MetadataReportFactory {
+	if metaDataReportFactories[name] == nil {
+		panic("metadata report for " + name + " is not existing, make sure you have import the package.")
+	}
+	return metaDataReportFactories[name]()
+}
diff --git a/config/consumer_config.go b/config/consumer_config.go
index 0d9c9585c..e853fc1b1 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -129,6 +129,11 @@ func ConsumerInit(confConFile string) error {
 			return perrors.WithMessagef(err, "time.ParseDuration(Connect_Timeout{%#v})", consumerConfig.Connect_Timeout)
 		}
 	}
+
+	//start the metadata report if config set
+	if err := startMetadataReport(); err != nil {
+		return perrors.WithMessagef(err, "Consumer start metadata report error ,error is {%#v}", err)
+	}
 	logger.Debugf("consumer config{%#v}\n", consumerConfig)
 	return nil
 }
@@ -155,14 +160,3 @@ func configCenterRefreshConsumer() error {
 	}
 	return err
 }
-
-// StartMetadataReport: The entry of metadata report start
-func startMetadataReport() error {
-	metadataConfig := consumerConfig.ApplicationConfig.MetadataType
-	if metadataConfig == constant.METACONFIG_REMOTE && consumerConfig.MetadataReportConfig == nil {
-		return perrors.New("No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled.")
-	} else if metadataConfig == constant.METACONFIG_REMOTE && len(consumerConfig.MetadataReportConfig.Address) == 0 {
-		return perrors.New("MetadataConfig address can not be empty.")
-	}
-	return nil
-}
diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go
index 3f170606e..6616cf192 100644
--- a/config/metadata_report_config.go
+++ b/config/metadata_report_config.go
@@ -18,6 +18,7 @@
 package config
 
 import (
+	"github.com/apache/dubbo-go/metadata"
 	"net/url"
 )
 import (
@@ -32,6 +33,7 @@ import (
 
 // MethodConfig ...
 type MetadataReportConfig struct {
+	Protocol   string            `required:"true"  yaml:"protocol"  json:"protocol,omitempty"`
 	Address    string            `yaml:"address" json:"address,omitempty" property:"address"`
 	Username   string            `yaml:"username" json:"username,omitempty" property:"username"`
 	Password   string            `yaml:"password" json:"password,omitempty"  property:"password"`
@@ -70,6 +72,7 @@ func (c *MetadataReportConfig) ToUrl() (*common.URL, error) {
 		common.WithUsername(c.Username),
 		common.WithPassword(c.Password),
 		common.WithLocation(c.Address),
+		common.WithProtocol(c.Protocol),
 	)
 	if err != nil {
 		return nil, perrors.New("Invalid MetadataReportConfig.")
@@ -77,3 +80,23 @@ func (c *MetadataReportConfig) ToUrl() (*common.URL, error) {
 	url.SetParam("metadata", url.Protocol)
 	return &url, nil
 }
+
+// StartMetadataReport: The entry of metadata report start
+func startMetadataReport() error {
+	metadataConfig := consumerConfig.ApplicationConfig.MetadataType
+	if consumerConfig.MetadataReportConfig == nil {
+		return nil
+	} else {
+		if metadataConfig == constant.METACONFIG_REMOTE {
+			return perrors.New("No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled.")
+		} else if metadataConfig == constant.METACONFIG_REMOTE && len(consumerConfig.MetadataReportConfig.Address) == 0 {
+			return perrors.New("MetadataConfig address can not be empty.")
+		}
+		if url, err := consumerConfig.MetadataReportConfig.ToUrl(); err == nil {
+			metadata.Init(url)
+		} else {
+			return perrors.New("MetadataConfig is invalid!")
+		}
+	}
+	return nil
+}
diff --git a/config/metadata_report_config_test.go b/config/metadata_report_config_test.go
index 322d50c10..d6b08d5fb 100644
--- a/config/metadata_report_config_test.go
+++ b/config/metadata_report_config_test.go
@@ -8,7 +8,8 @@ import (
 
 func TestMetadataReportConfig_ToUrl(t *testing.T) {
 	metadataReportConfig := MetadataReportConfig{
-		Address:    "mock://127.0.0.1",
+		Protocol:   "mock",
+		Address:    "127.0.0.1:2181",
 		Username:   "test",
 		Password:   "test",
 		TimeoutStr: "3s",
@@ -19,6 +20,9 @@ func TestMetadataReportConfig_ToUrl(t *testing.T) {
 	url, error := metadataReportConfig.ToUrl()
 	assert.NoError(t, error)
 	assert.Equal(t, "mock", url.Protocol)
+	assert.Equal(t, "127.0.0.1:2181", url.Location)
+	assert.Equal(t, "127.0.0.1", url.Ip)
+	assert.Equal(t, "2181", url.Port)
 	assert.Equal(t, "test", url.Username)
 	assert.Equal(t, "test", url.Password)
 	assert.Equal(t, "v", url.GetParam("k", ""))
diff --git a/config/provider_config.go b/config/provider_config.go
index 2967ecad3..2265f5954 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -103,7 +103,10 @@ func ProviderInit(confProFile string) error {
 			n.InterfaceId = k
 		}
 	}
-
+	//start the metadata report if config set
+	if err := startMetadataReport(); err != nil {
+		return perrors.WithMessagef(err, "Provider start metadata report error ,error is {%#v}", err)
+	}
 	logger.Debugf("provider config{%#v}\n", providerConfig)
 
 	return nil
diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go
new file mode 100644
index 000000000..ead984345
--- /dev/null
+++ b/metadata/definition/definition.go
@@ -0,0 +1,41 @@
+/*
+ * 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 definition
+
+type ServiceDefinition struct {
+	CanonicalName string
+	CodeSource    string
+	Methods       []MethodDefinition
+	Types         []TypeDefinition
+}
+
+type MethodDefinition struct {
+	Name           string
+	ParameterTypes []string
+	ReturnType     string
+	Parameters     []TypeDefinition
+}
+
+type TypeDefinition struct {
+	Id              string
+	Type            string
+	Items           []TypeDefinition
+	Enums           []string
+	Properties      map[string]TypeDefinition
+	TypeBuilderName string
+}
diff --git a/metadata/exporter.go b/metadata/exporter.go
new file mode 100644
index 000000000..a5693613c
--- /dev/null
+++ b/metadata/exporter.go
@@ -0,0 +1,27 @@
+/*
+ * 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 metadata
+
+import "github.com/apache/dubbo-go/common"
+
+type MetadataExporter interface {
+	Export() MetadataExporter
+	Unexport() MetadataExporter
+	GetExportedURLs() []*common.URL
+	IsExported() bool
+}
diff --git a/metadata/identifier/base_metadata_identifier.go b/metadata/identifier/base_metadata_identifier.go
new file mode 100644
index 000000000..c29dcf97d
--- /dev/null
+++ b/metadata/identifier/base_metadata_identifier.go
@@ -0,0 +1,92 @@
+/*
+ * 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 identifier
+
+import (
+	"encoding/base64"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+)
+
+type BaseMetadataIdentifier interface {
+	getFilePathKey(params ...string) string
+	getIdentifierKey(params ...string) string
+}
+
+type BaseServiceMetadataIdentifier struct {
+	serviceInterface string
+	version          string
+	group            string
+	side             string
+}
+
+// joinParams...
+func joinParams(joinChar string, params []string) string {
+	var joinedStr string
+	for _, param := range params {
+		joinedStr += joinChar
+		joinedStr += param
+	}
+	return joinedStr
+}
+
+// getIdentifierKey...
+func (mdi *BaseServiceMetadataIdentifier) getIdentifierKey(params ...string) string {
+	return mdi.serviceInterface +
+		constant.KEY_SEPARATOR + mdi.version +
+		constant.KEY_SEPARATOR + mdi.group +
+		constant.KEY_SEPARATOR + mdi.side +
+		joinParams(constant.KEY_SEPARATOR, params)
+}
+
+// getIdentifierKey...
+func (mdi *BaseServiceMetadataIdentifier) getFilePathKey(params ...string) string {
+	path := serviceToPath(mdi.serviceInterface)
+
+	return constant.DEFAULT_PATH_TAG +
+		withPathSeparator(path) +
+		withPathSeparator(mdi.version) +
+		withPathSeparator(mdi.group) +
+		withPathSeparator(mdi.side) +
+		joinParams(constant.PATH_SEPARATOR, params)
+
+}
+
+// serviceToPath...
+func serviceToPath(serviceInterface string) string {
+	if serviceInterface == constant.ANY_VALUE {
+		return ""
+	} else {
+		decoded, err := base64.URLEncoding.DecodeString(serviceInterface)
+		if err != nil {
+			return ""
+		}
+		return string(decoded)
+	}
+
+}
+
+//withPathSeparator...
+func withPathSeparator(path string) string {
+	if len(path) != 0 {
+		path = constant.PATH_SEPARATOR + path
+	}
+	return path
+}
diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go
new file mode 100644
index 000000000..f3df8f365
--- /dev/null
+++ b/metadata/identifier/metadata_identifier.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 identifier
+
+type MetadataIdentifier struct {
+	application string
+	BaseMetadataIdentifier
+}
+
+// getIdentifierKey...
+func (mdi *MetadataIdentifier) getIdentifierKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.application)
+}
+
+// getIdentifierKey...
+func (mdi *MetadataIdentifier) getFilePathKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.application)
+}
diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go
new file mode 100644
index 000000000..157b9c54a
--- /dev/null
+++ b/metadata/identifier/service_metadata_identifier.go
@@ -0,0 +1,36 @@
+/*
+ * 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 identifier
+
+import "github.com/apache/dubbo-go/common/constant"
+
+type ServiceMetadataIdentifier struct {
+	revision string
+	protocol string
+	BaseMetadataIdentifier
+}
+
+// getIdentifierKey...
+func (mdi *ServiceMetadataIdentifier) getIdentifierKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.protocol + constant.KEY_REVISON_PREFIX + mdi.revision)
+}
+
+// getIdentifierKey...
+func (mdi *ServiceMetadataIdentifier) getFilePathKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.protocol + constant.KEY_REVISON_PREFIX + mdi.revision)
+}
diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go
new file mode 100644
index 000000000..fd3a290b4
--- /dev/null
+++ b/metadata/identifier/subscribe_metadata_identifier.go
@@ -0,0 +1,16 @@
+package identifier
+
+type SubscriberMetadataIdentifier struct {
+	revision string
+	BaseMetadataIdentifier
+}
+
+// getIdentifierKey...
+func (mdi *SubscriberMetadataIdentifier) getIdentifierKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.revision)
+}
+
+// getIdentifierKey...
+func (mdi *SubscriberMetadataIdentifier) getFilePathKey(params ...string) string {
+	return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.revision)
+}
diff --git a/metadata/instance.go b/metadata/instance.go
new file mode 100644
index 000000000..10de0451f
--- /dev/null
+++ b/metadata/instance.go
@@ -0,0 +1,40 @@
+/*
+ * 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 metadata
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"sync"
+)
+
+var (
+	instance MetadataReport
+	once     sync.Once
+)
+
+// GetEnvInstance ...
+func Init(url *common.URL) {
+	once.Do(func() {
+		instance = extension.GetMetadataReportFactory(url.Protocol).createMetadataReport(url)
+	})
+}
+
+func GetMetadataReportInstance() MetadataReport {
+	return instance
+}
diff --git a/metadata/report.go b/metadata/report.go
new file mode 100644
index 000000000..3fcc71241
--- /dev/null
+++ b/metadata/report.go
@@ -0,0 +1,35 @@
+/*
+ * 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 metadata
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/metadata/definition"
+	"github.com/apache/dubbo-go/metadata/identifier"
+)
+
+type MetadataReport interface {
+	StoreProviderMetadata(*identifier.MetadataIdentifier, *definition.ServiceDefinition)
+	StoreConsumeretadata(*identifier.MetadataIdentifier, map[string]string)
+	SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, *common.URL)
+	RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier)
+	GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string
+	SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []*common.URL)
+	GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string
+	GetServiceDefinition(*identifier.MetadataIdentifier)
+}
diff --git a/metadata/report_factory.go b/metadata/report_factory.go
new file mode 100644
index 000000000..60b0b2b57
--- /dev/null
+++ b/metadata/report_factory.go
@@ -0,0 +1,28 @@
+/*
+ * 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 metadata
+
+import "github.com/apache/dubbo-go/common"
+
+var (
+	MetadataReportInstance MetadataReport
+)
+
+type MetadataReportFactory interface {
+	createMetadataReport(*common.URL) MetadataReport
+}
diff --git a/metadata/service.go b/metadata/service.go
new file mode 100644
index 000000000..d85703c95
--- /dev/null
+++ b/metadata/service.go
@@ -0,0 +1,37 @@
+/*
+ * 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 metadata
+
+import (
+	"github.com/apache/dubbo-go/common"
+	gxset "github.com/dubbogo/gost/container/set"
+)
+
+type MetadataService interface {
+	ServiceName() string
+	ExportURL(url *common.URL) bool
+	UnexportURL(url *common.URL) bool
+	RefreshMetadata(exportedRevision string, subscribedRevision string) bool
+	SubscribeURL(url *common.URL) bool
+	UnsubscribeURL(url *common.URL) bool
+	PublishServiceDefinition(url *common.URL)
+
+	GetExportedURLs(serviceInterface string, group string, version string, protocol string) gxset.HashSet
+	GetServiceDefinition(interfaceName string, version string, group string) string
+	GetServiceDefinitionByServiceKey(serviceKey string) string
+}
-- 
GitLab