Skip to content
Snippets Groups Projects
Commit 45c3c471 authored by flycash's avatar flycash
Browse files

Fix Review And UT

parent ea09ebbf
No related branches found
No related tags found
No related merge requests found
Showing
with 216 additions and 44 deletions
......@@ -278,6 +278,4 @@ const (
// SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used
SERVICE_DISCOVERY_KEY = "service_discovery"
LANGUAGE_KEY = "language"
GO_LANG = "golang"
)
......@@ -19,10 +19,16 @@ package config
import (
"time"
)
import (
"github.com/apache/dubbo-go/common/logger"
)
// RemoteConfig: usually we need some middleware, including nacos, zookeeper
// this represents an instance of this middleware
// so that other module, like config center, registry could reuse the config
// but now, only metadata report, metadata service, service discovery use this structure
type RemoteConfig struct {
Address string `yaml:"address" json:"address,omitempty"`
TimeoutStr string `default:"5s" yaml:"timeout" json:"timeout,omitempty"`
......@@ -31,6 +37,8 @@ type RemoteConfig struct {
Params map[string]string `yaml:"params" json:"address,omitempty"`
}
// Timeout return timeout duration.
// if the configure is invalid, or missing, the default value 5s will be returned
func (rc *RemoteConfig) Timeout() time.Duration {
if res, err := time.ParseDuration(rc.TimeoutStr); err == nil {
return res
......
......@@ -19,7 +19,8 @@ package config
import (
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
......
......@@ -44,9 +44,7 @@ import (
"github.com/apache/dubbo-go/protocol/protocolwrapper"
)
// ServiceConfig is a newest structure to support Dubbo 2.7.5
// But I think it's not very necessary,
// we should think about how to reuse current ProviderConfig rather than use this
// ServiceConfig is the configuration of the service provider
type ServiceConfig struct {
context context.Context
id string
......@@ -86,12 +84,12 @@ type ServiceConfig struct {
exporters []protocol.Exporter
}
// Prefix ...
// Prefix return dubbo.service.${interface}.
func (c *ServiceConfig) Prefix() string {
return constant.ServiceConfigPrefix + c.InterfaceName + "."
}
// UnmarshalYAML ...
// UnmarshalYAML unmarshals the ServiceConfig by @unmarshal function
func (c *ServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := defaults.Set(c); err != nil {
return err
......@@ -143,7 +141,7 @@ func getRandomPort(protocolConfigs []*ProtocolConfig) *list.List {
return ports
}
// Export ...
// Export export the service
func (c *ServiceConfig) Export() error {
// TODO: config center start here
......@@ -251,7 +249,7 @@ func (c *ServiceConfig) Unexport() {
c.unexported.Store(true)
}
// Implement ...
// Implement only store the @s and return
func (c *ServiceConfig) Implement(s common.RPCService) {
c.rpcService = s
}
......
......@@ -38,9 +38,14 @@ import (
const (
nacosClientName = "nacos config_center"
maxKeysNum = 9999
// the number is a little big tricky
// it will be used in query which looks up all keys with the target group
// now, one key represents one application
// so only a group has more than 9999 applications will failed
maxKeysNum = 9999
)
// nacosDynamicConfiguration is the implementation of DynamicConfiguration based on nacos
type nacosDynamicConfiguration struct {
url *common.URL
rootPath string
......
......@@ -26,7 +26,7 @@ import (
/**
* If the invocation cannot pass any validation in filter, like ExecuteLimitFilter and TpsLimitFilter,
* the implementation will be used.
* The event case is that sometimes you want to return the default value when the request was rejected.
* The common case is that sometimes you want to return the default value when the request was rejected.
* Or you want to be warned if any request was rejected.
* In such situation, implement this interface and register it by invoking extension.SetRejectedExecutionHandler.
*/
......
......@@ -42,10 +42,12 @@ type ServiceDefinition struct {
Types []TypeDefinition
}
// ToBytes convert ServiceDefinition to json string
func (def *ServiceDefinition) ToBytes() ([]byte, error) {
return json.Marshal(def)
}
// String will iterate all methods and parameters and convert them to json string
func (def *ServiceDefinition) String() string {
var methodStr strings.Builder
for _, m := range def.Methods {
......
......@@ -49,7 +49,7 @@ func joinParams(joinChar string, params []string) string {
return joinedStr
}
// getIdentifierKey will return string format as service:Version:Group:Side:param1:param2...
// getIdentifierKey returns string that format is service:Version:Group:Side:param1:param2...
func (mdi *BaseMetadataIdentifier) getIdentifierKey(params ...string) string {
return mdi.ServiceInterface +
constant.KEY_SEPARATOR + mdi.Version +
......@@ -58,7 +58,7 @@ func (mdi *BaseMetadataIdentifier) getIdentifierKey(params ...string) string {
joinParams(constant.KEY_SEPARATOR, params)
}
// getFilePathKey will return string format as metadata/path/Version/Group/Side/param1/param2...
// getFilePathKey returns string that format is metadata/path/Version/Group/Side/param1/param2...
func (mdi *BaseMetadataIdentifier) getFilePathKey(params ...string) string {
path := serviceToPath(mdi.ServiceInterface)
......@@ -71,7 +71,7 @@ func (mdi *BaseMetadataIdentifier) getFilePathKey(params ...string) string {
}
// serviceToPath...
// serviceToPath uss URL encode to decode the @serviceInterface
func serviceToPath(serviceInterface string) string {
if serviceInterface == constant.ANY_VALUE {
return ""
......@@ -85,7 +85,7 @@ func serviceToPath(serviceInterface string) string {
}
//withPathSeparator...
// withPathSeparator return "/" + @path
func withPathSeparator(path string) string {
if len(path) != 0 {
path = constant.PATH_SEPARATOR + path
......
......@@ -23,12 +23,12 @@ type MetadataIdentifier struct {
BaseMetadataIdentifier
}
// GetIdentifierKey will return string format as service:Version:Group:Side:Application
// GetIdentifierKey returns string that format is service:Version:Group:Side:Application
func (mdi *MetadataIdentifier) GetIdentifierKey() string {
return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Application)
}
// GetFilePathKey will return string format as metadata/path/Version/Group/Side/Application
// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Application
func (mdi *MetadataIdentifier) GetFilePathKey() string {
return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Application)
}
......@@ -29,6 +29,9 @@ type ServiceMetadataIdentifier struct {
BaseMetadataIdentifier
}
// NewServiceMetadataIdentifier create instance.
// The ServiceInterface is the @url.Service()
// other parameters are read from @url
func NewServiceMetadataIdentifier(url common.URL) *ServiceMetadataIdentifier {
return &ServiceMetadataIdentifier{
BaseMetadataIdentifier: BaseMetadataIdentifier{
......@@ -41,12 +44,12 @@ func NewServiceMetadataIdentifier(url common.URL) *ServiceMetadataIdentifier {
}
}
// GetIdentifierKey will return string format as service:Version:Group:Side:Protocol:"revision-"+Revision
// GetIdentifierKey returns string that format is service:Version:Group:Side:Protocol:"revision"+Revision
func (mdi *ServiceMetadataIdentifier) GetIdentifierKey() string {
return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Protocol, constant.KEY_REVISON_PREFIX+mdi.Revision)
}
// GetFilePathKey will return string format as metadata/path/Version/Group/Side/Protocol/"revision"+Revision
// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Protocol/"revision"+Revision
func (mdi *ServiceMetadataIdentifier) GetFilePathKey() string {
return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Protocol, constant.KEY_REVISON_PREFIX+mdi.Revision)
}
......@@ -23,12 +23,12 @@ type SubscriberMetadataIdentifier struct {
MetadataIdentifier
}
// GetIdentifierKey will return string format as service:Version:Group:Side:Revision
// GetIdentifierKey returns string that format is service:Version:Group:Side:Revision
func (mdi *SubscriberMetadataIdentifier) GetIdentifierKey() string {
return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Revision)
}
// GetFilePathKey will return string format as metadata/path/Version/Group/Side/Revision
// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Revision
func (mdi *SubscriberMetadataIdentifier) GetFilePathKey() string {
return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Revision)
}
......@@ -21,10 +21,6 @@ import (
"strconv"
"sync"
"time"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/metadata/mapping"
)
import (
......@@ -33,10 +29,13 @@ import (
)
import (
common_cfg "github.com/apache/dubbo-go/common/config"
commonCfg "github.com/apache/dubbo-go/common/config"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/metadata/mapping"
)
const (
......@@ -87,12 +86,15 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str
return defaultGroup + slash + serviceInterface
}
var serviceNameMappingInstance *DynamicConfigurationServiceNameMapping
var serviceNameMappingOnce sync.Once
var (
serviceNameMappingInstance *DynamicConfigurationServiceNameMapping
serviceNameMappingOnce sync.Once
)
// GetNameMappingInstance return an instance, if not found, it creates one
func GetNameMappingInstance() mapping.ServiceNameMapping {
serviceNameMappingOnce.Do(func() {
dc := common_cfg.GetEnvInstance().GetDynamicConfiguration()
dc := commonCfg.GetEnvInstance().GetDynamicConfiguration()
serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc}
})
return serviceNameMappingInstance
......
......@@ -39,9 +39,9 @@ import (
)
func init() {
ftry := &nacosMetadataReportFactory{}
ins := &nacosMetadataReportFactory{}
extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory {
return ftry
return ins
})
}
......
......@@ -56,7 +56,7 @@ func (exporter *MetadataServiceExporter) Export() error {
}
serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME
// identify this is a golang server
serviceConfig.Params = map[string]string{constant.LANGUAGE_KEY: constant.GO_LANG}
serviceConfig.Params = map[string]string{}
serviceConfig.Group = config.GetApplicationConfig().Name
// now the error will always be nil
serviceConfig.Version, _ = exporter.metadataService.Version()
......
......@@ -19,7 +19,9 @@ package inmemory
import (
"encoding/json"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
......@@ -35,6 +37,10 @@ func init() {
})
}
// createProxy creates an instance of MetadataServiceProxy
// we read the metadata from ins.Metadata()
// and then create an Invoker instance
// also we will mark this proxy as golang's proxy
func createProxy(ins registry.ServiceInstance) service.MetadataService {
urls := buildStandardMetadataServiceURL(ins)
if len(urls) == 0 {
......@@ -45,15 +51,12 @@ func createProxy(ins registry.ServiceInstance) service.MetadataService {
u := urls[0]
p := extension.GetProtocol(u.Protocol)
invoker := p.Refer(*u)
golang := u.GetParam(constant.LANGUAGE_KEY, "")
return &MetadataServiceProxy{invkr: invoker,
golangServer: golang == constant.GO_LANG,
return &MetadataServiceProxy{
invkr: invoker,
}
}
// buildStandardMetadataServiceURL will use standard format to build the metadata service url.
// Now we don't need to support spring-cloud format metadata service url.
//
func buildStandardMetadataServiceURL(ins registry.ServiceInstance) []*common.URL {
ps := getMetadataServiceUrlParams(ins)
res := make([]*common.URL, 0, len(ps))
......
......@@ -18,15 +18,83 @@
package inmemory
import (
"context"
"encoding/json"
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/registry"
)
func TestMetadataService_GetMetadataServiceUrlParams(t *testing.T) {
str := `{"dubbo":{"timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"20880"}}`
tmp := make(map[string]map[string]string)
err := json.Unmarshal([]byte(str), &tmp)
assert.Nil(t, err)
}
func TestCreateProxy(t *testing.T) {
extension.SetProtocol("mock", func() protocol.Protocol {
return &mockProtocol{}
})
ins := &registry.DefaultServiceInstance{
Id: "test-id",
ServiceName: "com.dubbo",
Host: "localhost",
Port: 8080,
Enable: true,
Healthy: true,
}
pxy := createProxy(ins)
assert.Nil(t, pxy)
ins.Metadata = map[string]string{constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"mock":{"timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"20880"}}`}
pxy = createProxy(ins)
assert.NotNil(t, pxy)
}
type mockProtocol struct {
}
func (m mockProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
panic("implement me")
}
func (m mockProtocol) Refer(url common.URL) protocol.Invoker {
return &mockInvoker{}
}
func (m mockProtocol) Destroy() {
panic("implement me")
}
type mockInvoker struct {
}
func (m *mockInvoker) GetUrl() common.URL {
panic("implement me")
}
func (m *mockInvoker) IsAvailable() bool {
panic("implement me")
}
func (m *mockInvoker) Destroy() {
panic("implement me")
}
func (m *mockInvoker) Invoke(context.Context, protocol.Invocation) protocol.Result {
return &protocol.RPCResult{
Rest: &[]interface{}{"dubbo://localhost"},
}
}
......@@ -19,9 +19,6 @@ package inmemory
import (
"sort"
"sync"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/config"
)
import (
......@@ -32,7 +29,9 @@ import (
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/metadata/definition"
"github.com/apache/dubbo-go/metadata/service"
)
......
......@@ -21,7 +21,9 @@ import (
"context"
"reflect"
"time"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
......@@ -36,7 +38,7 @@ import (
// so in client-side, if we want to get the metadata information,
// we must call metadata service
// this is the stub, or proxy
// for now, only GetExportedURLs will be implemented
// for now, only GetExportedURLs need to be implemented
type MetadataServiceProxy struct {
invkr protocol.Invoker
golangServer bool
......
......@@ -15,41 +15,68 @@
* limitations under the License.
*/
package memory
package inmemory
import (
"sync"
gxset "github.com/dubbogo/gost/container/set"
"testing"
)
"github.com/apache/dubbo-go/metadata/mapping"
import (
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/metadata/service"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/registry"
)
func init() {
extension.SetGlobalServiceNameMapping(GetNameMappingInstance)
}
func TestMetadataServiceProxy_GetExportedURLs(t *testing.T) {
type InMemoryServiceNameMapping struct{}
pxy := createPxy()
assert.NotNil(t, pxy)
res, err := pxy.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE)
assert.Nil(t, err)
assert.Len(t, res, 1)
func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, version string, protocol string) error {
return nil
}
func (i InMemoryServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) {
return gxset.NewSet(config.GetApplicationConfig().Name), nil
}
// TestNewMetadataService: those methods are not implemented
// when we implement them, adding UT
func TestNewMetadataService(t *testing.T) {
pxy := createPxy()
pxy.ServiceName()
pxy.PublishServiceDefinition(common.URL{})
pxy.GetServiceDefinition(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE)
pxy.Version()
pxy.GetSubscribedURLs()
pxy.UnsubscribeURL(common.URL{})
pxy.GetServiceDefinitionByServiceKey("any")
pxy.ExportURL(common.URL{})
pxy.SubscribeURL(common.URL{})
pxy.MethodMapper()
pxy.UnexportURL(common.URL{})
pxy.RefreshMetadata(constant.ANY_VALUE, constant.ANY_VALUE)
var serviceNameMappingInstance *InMemoryServiceNameMapping
var serviceNameMappingOnce sync.Once
}
func GetNameMappingInstance() mapping.ServiceNameMapping {
serviceNameMappingOnce.Do(func() {
serviceNameMappingInstance = &InMemoryServiceNameMapping{}
func createPxy() service.MetadataService {
extension.SetProtocol("mock", func() protocol.Protocol {
return &mockProtocol{}
})
return serviceNameMappingInstance
ins := &registry.DefaultServiceInstance{
Id: "test-id",
ServiceName: "com.dubbo",
Host: "localhost",
Port: 8080,
Enable: true,
Healthy: true,
Metadata: map[string]string{constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"mock":{"timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"20880"}}`},
}
return extension.GetMetadataServiceProxyFactory(local).GetProxy(ins)
}
......@@ -19,15 +19,16 @@ package remote
import (
"sync"
)
import (
"go.uber.org/atomic"
"github.com/apache/dubbo-go/common/extension"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/metadata/definition"
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment