This is an automated email from the ASF dual-hosted git repository.
Alanxtl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 5eb9b25a7 docs(metadata): complete metadatainfo comments and unit test
coverage (#3666)
5eb9b25a7 is described below
commit 5eb9b25a7851127cb40b953afecb66b0919633e3
Author: MaoMeng <[email protected]>
AuthorDate: Sat Aug 15 23:44:48 2026 +0800
docs(metadata): complete metadatainfo comments and unit test coverage
(#3666)
* docs(metadata): complete metadatainfo comments and unit test coverage
* docs(metadata): add some unit test to metadatainfo
---
metadata/info/metadata_info.go | 74 +++++++++++++++++++++++++++----------
metadata/info/metadata_info_test.go | 56 ++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 20 deletions(-)
diff --git a/metadata/info/metadata_info.go b/metadata/info/metadata_info.go
index c8f770a37..52c82e30f 100644
--- a/metadata/info/metadata_info.go
+++ b/metadata/info/metadata_info.go
@@ -44,6 +44,8 @@ func init() {
hessian.RegisterPOJO(&ServiceInfo{})
}
+// IncludeKeys is a whitelist of provider URL parameter keys
+// that are copied into ServiceInfo.Params and exposed to consumers.
var IncludeKeys = gxset.NewSet(
constant.ApplicationKey,
constant.GroupKey,
@@ -61,20 +63,30 @@ var IncludeKeys = gxset.NewSet(
// MetadataInfo the metadata information of instance
type MetadataInfo struct {
- App string `json:"app,omitempty"
hessian:"app"`
- Revision string
`json:"revision,omitempty" hessian:"revision"`
- Tag string `json:"tag,omitempty"
hessian:"tag"`
- Services map[string]*ServiceInfo
`json:"services,omitempty" hessian:"services"`
- exportedServiceURLs map[string][]*common.URL `hessian:"-"` // server
exported service urls
- subscribedServiceURLs map[string][]*common.URL `hessian:"-"` // client
subscribed service urls
- mu sync.RWMutex `json:"-" hessian:"-"`
- LastUpdatedTime int64
`json:"lastUpdatedTime,omitempty" hessian:"-"`
+ // App is the application name.
+ App string `json:"app,omitempty" hessian:"app"`
+ // Revision is a content hash of app name and its services.
+ Revision string `json:"revision,omitempty" hessian:"revision"`
+ // Tag is the application tag.
+ Tag string `json:"tag,omitempty" hessian:"tag"`
+ // Services is the exported services.
+ Services map[string]*ServiceInfo `json:"services,omitempty"
hessian:"services"`
+ // exportedServiceURLs is the server exported service urls.
+ exportedServiceURLs map[string][]*common.URL `hessian:"-"`
+ // subscribedServiceURLs is the client subscribed service urls.
+ subscribedServiceURLs map[string][]*common.URL `hessian:"-"`
+ // mu is the read-write lock for the metadata.
+ mu sync.RWMutex `json:"-" hessian:"-"`
+ // LastUpdatedTime is the last updated time of the metadata.
+ LastUpdatedTime int64 `json:"lastUpdatedTime,omitempty" hessian:"-"`
}
+// NewAppMetadataInfo creates an empty MetadataInfo for the given application.
func NewAppMetadataInfo(app string) *MetadataInfo {
return NewMetadataInfo(app, "")
}
+// NewMetadataInfo creates an empty MetadataInfo with the given application
name and tag.
func NewMetadataInfo(app, tag string) *MetadataInfo {
return &MetadataInfo{
App: app,
@@ -85,6 +97,7 @@ func NewMetadataInfo(app, tag string) *MetadataInfo {
}
}
+// NewMetadataInfoWithParams creates a MetadataInfo with the given application
name, revision, and services.
func NewMetadataInfoWithParams(app string, revision string, services
map[string]*ServiceInfo) *MetadataInfo {
return &MetadataInfo{
App: app,
@@ -95,6 +108,7 @@ func NewMetadataInfoWithParams(app string, revision string,
services map[string]
}
}
+// JavaClassName aligns the class name with the Java implementation.
func (info *MetadataInfo) JavaClassName() string {
return "org.apache.dubbo.metadata.MetadataInfo"
}
@@ -121,6 +135,7 @@ func (info *MetadataInfo) addServiceWithoutLock(url
*common.URL) {
}
}
+// addUrl adds a service URL to the map depending on the ServiceKey.
func addUrl(m map[string][]*common.URL, url *common.URL) {
if _, ok := m[url.ServiceKey()]; !ok {
m[url.ServiceKey()] = make([]*common.URL, 0)
@@ -128,6 +143,7 @@ func addUrl(m map[string][]*common.URL, url *common.URL) {
m[url.ServiceKey()] = append(m[url.ServiceKey()], url)
}
+// removeUrl removes a service URL from the map depending on the ServiceKey.
func removeUrl(m map[string][]*common.URL, url *common.URL) {
if urls, ok := m[url.ServiceKey()]; ok {
for i, u := range urls {
@@ -177,6 +193,7 @@ func (info *MetadataInfo) RemoveSubscribeURL(url
*common.URL) {
removeUrl(info.subscribedServiceURLs, url)
}
+// GetExportedServiceURLs returns all the exported service urls.
func (info *MetadataInfo) GetExportedServiceURLs() []*common.URL {
info.mu.RLock()
defer info.mu.RUnlock()
@@ -188,6 +205,7 @@ func (info *MetadataInfo) GetExportedServiceURLs()
[]*common.URL {
return res
}
+// GetSubscribedURLs returns all the subscribed service urls.
func (info *MetadataInfo) GetSubscribedURLs() []*common.URL {
info.mu.RLock()
defer info.mu.RUnlock()
@@ -212,6 +230,7 @@ func (info *MetadataInfo) GetServices()
map[string]*ServiceInfo {
return cp
}
+// ReplaceExportedServices replaces the exported services with the given URLs.
func (info *MetadataInfo) ReplaceExportedServices(urls []*common.URL) {
info.mu.Lock()
defer info.mu.Unlock()
@@ -242,6 +261,7 @@ func (info *MetadataInfo) Snapshot() MetadataInfo {
}
}
+// findExportedServiceURL finds the service URL for a given match key.
func (info *MetadataInfo) findExportedServiceURL(matchKey string) *common.URL {
for _, urls := range info.exportedServiceURLs {
for _, serviceURL := range urls {
@@ -253,19 +273,31 @@ func (info *MetadataInfo) findExportedServiceURL(matchKey
string) *common.URL {
return nil
}
-// ServiceInfo the information of service
+// ServiceInfo is the metadata information of a service instance from a
provider URL.
type ServiceInfo struct {
- Name string `json:"name,omitempty" hessian:"name"`
- Group string `json:"group,omitempty" hessian:"group"`
- Version string `json:"version,omitempty" hessian:"version"`
- Protocol string `json:"protocol,omitempty"
hessian:"protocol"`
- Port int `json:"port,omitempty" hessian:"port"`
- Path string `json:"path,omitempty" hessian:"path"`
- Params map[string]string `json:"params,omitempty" hessian:"params"`
-
- ServiceKey string `json:"-" hessian:"-"`
- MatchKey string `json:"-" hessian:"-"`
- URL *common.URL `json:"-" hessian:"-"`
+ // Name is the service interface name.
+ Name string `json:"name,omitempty" hessian:"name"`
+ // Group is the service group name.
+ Group string `json:"group,omitempty" hessian:"group"`
+ // Version is the service version, 0.0.0 means no version.
+ Version string `json:"version,omitempty" hessian:"version"`
+ // Protocol is the service protocol.
+ Protocol string `json:"protocol,omitempty" hessian:"protocol"`
+ // Port is the service port.
+ Port int `json:"port,omitempty" hessian:"port"`
+ // Path is the service path.
+ Path string `json:"path,omitempty" hessian:"path"`
+ // Params holds the provider URL parameters exposed to consumers.
+ // It is derived from the provider URL. It contains whitelist-filtered
+ // service-level parameters, method-level parameters and the method
name list.
+ Params map[string]string `json:"params,omitempty" hessian:"params"`
+
+ // ServiceKey is the service key, computed from Name, Group, and
Version.
+ ServiceKey string `json:"-" hessian:"-"`
+ // MatchKey is the match key, computed from ServiceKey and Protocol.
+ MatchKey string `json:"-" hessian:"-"`
+ // URL points to the source provider URL.
+ URL *common.URL `json:"-" hessian:"-"`
}
// NewServiceInfoWithURL builds a service-level metadata view from provider
URL.
@@ -295,6 +327,7 @@ func NewServiceInfoWithURL(url *common.URL) *ServiceInfo {
return service
}
+// NewServiceInfo creates a ServiceInfo with the given identity fields and
params, computing ServiceKey and MatchKey.
func NewServiceInfo(name, group, version, protocol, path string, params
map[string]string) *ServiceInfo {
serviceKey := common.ServiceKey(name, group, version)
matchKey := common.MatchKey(serviceKey, protocol)
@@ -310,6 +343,7 @@ func NewServiceInfo(name, group, version, protocol, path
string, params map[stri
}
}
+// JavaClassName aligns the class name with the Java implementation.
func (si *ServiceInfo) JavaClassName() string {
return "org.apache.dubbo.metadata.MetadataInfo$ServiceInfo"
}
diff --git a/metadata/info/metadata_info_test.go
b/metadata/info/metadata_info_test.go
index 59c99812c..1c11c512e 100644
--- a/metadata/info/metadata_info_test.go
+++ b/metadata/info/metadata_info_test.go
@@ -147,6 +147,23 @@ func TestNewMetadataInfo(t *testing.T) {
info := NewMetadataInfo("dubbo", "tag")
assert.Equal(t, "dubbo", info.App)
assert.Equal(t, "tag", info.Tag)
+ assert.NotNil(t, info.Services)
+ assert.Empty(t, info.Services)
+ assert.NotNil(t, info.exportedServiceURLs)
+ assert.NotNil(t, info.subscribedServiceURLs)
+}
+
+func TestNewAppMetadataInfo(t *testing.T) {
+ info := NewAppMetadataInfo("dubbo")
+ assert.Equal(t, "dubbo", info.App)
+ assert.Empty(t, info.Tag)
+ assert.Empty(t, info.Revision)
+ assert.NotNil(t, info.Services)
+ assert.Empty(t, info.Services)
+ assert.NotNil(t, info.exportedServiceURLs)
+ assert.Empty(t, info.GetExportedServiceURLs())
+ assert.NotNil(t, info.subscribedServiceURLs)
+ assert.Empty(t, info.GetSubscribedURLs())
}
func TestNewMetadataInfoWithParams(t *testing.T) {
@@ -169,16 +186,50 @@ func TestNewServiceInfoWithURL(t *testing.T) {
assert.Equal(t, "1000", info.Params["Greet.timeout"])
}
+func TestNewServiceInfo(t *testing.T) {
+ params := map[string]string{"timeout": "3000"}
+ si := NewServiceInfo("test", "test", "1.0.0", "dubbo",
"/org.apache.dubbo.samples.proto.GreetService", params)
+ assert.Equal(t, "test", si.Name)
+ assert.Equal(t, "test", si.Group)
+ assert.Equal(t, "1.0.0", si.Version)
+ assert.Equal(t, "dubbo", si.Protocol)
+ assert.Equal(t, "org.apache.dubbo.samples.proto.GreetService", si.Path)
+ assert.Equal(t, params, si.Params)
+ assert.Equal(t, "test/test:1.0.0", si.ServiceKey)
+ assert.Equal(t, "test/test:1.0.0:dubbo", si.MatchKey)
+}
+
+func TestNewServiceInfoWithEmptyPath(t *testing.T) {
+ si := NewServiceInfo("test", "", "", "dubbo", "", nil)
+ assert.Empty(t, si.Path)
+ assert.Equal(t, "test", si.ServiceKey)
+ assert.Equal(t, "test:dubbo", si.MatchKey)
+}
+
func TestServiceInfoGetMethods(t *testing.T) {
service := NewServiceInfoWithURL(serviceUrl)
assert.Equal(t, []string{"Greet", "SayHello"}, service.GetMethods())
}
+func TestServiceInfoGetMethodsWithEmptyMap(t *testing.T) {
+ si := NewServiceInfo("", "", "", "", "", nil)
+ assert.Equal(t, []string{""}, si.GetMethods())
+ si.Params = map[string]string{constant.MethodsKey: ""}
+ assert.Equal(t, []string{""}, si.GetMethods())
+}
+
func TestServiceInfoGetParams(t *testing.T) {
service := NewServiceInfoWithURL(serviceUrl)
assert.Equal(t, []string{"random"}, service.GetParams()["loadbalance"])
}
+func TestServiceInfoGetParamWithEmptyMap(t *testing.T) {
+ si := NewServiceInfo("", "", "", "", "", nil)
+ assert.Empty(t, si.GetParams())
+ si.Params = map[string]string{}
+ assert.Empty(t, si.GetParams())
+}
+
func TestServiceInfoExcludesInstanceLevelParams(t *testing.T) {
serviceURL, err :=
common.NewURL("tri://127.0.0.1:20000/org.apache.dubbo.samples.proto.GreetService",
common.WithInterface("org.apache.dubbo.samples.proto.GreetService"),
@@ -205,6 +256,11 @@ func TestServiceInfoGetMatchKey(t *testing.T) {
assert.NotEmpty(t, si.GetMatchKey())
}
+func TestCalRevisionWithEmptyServices(t *testing.T) {
+ assert.Equal(t, "0", CalRevision("dubbo", nil))
+ assert.Equal(t, "0", CalRevision("dubbo", map[string]*ServiceInfo{}))
+}
+
func TestMetadataInfoGetServices(t *testing.T) {
metadataInfo := &MetadataInfo{
Services: make(map[string]*ServiceInfo),