blob: 417cc4cf8d0725882928c5fd4fa56e040520de1e [file] [log] [blame]
/*
* 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 local
import (
"encoding/json"
"sync"
)
import (
"github.com/dubbogo/gost/log/logger"
)
import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/common/extension"
"dubbo.apache.org/dubbo-go/v3/metadata/service"
"dubbo.apache.org/dubbo-go/v3/registry"
)
func init() {
factory := service.NewBaseMetadataServiceProxyFactory(createProxy)
extension.SetMetadataServiceProxyFactory(constant.DefaultKey, func() service.MetadataServiceProxyFactory {
return factory
})
}
var (
factory service.MetadataServiceProxyFactory
once *sync.Once
)
func GetInMemoryMetadataServiceProxyFactory() service.MetadataServiceProxyFactory {
once.Do(func() {
factory = service.NewBaseMetadataServiceProxyFactory(createProxy)
})
return factory
}
// 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 {
logger.Errorf("metadata service urls not found, %v", ins)
return nil
}
u := urls[0]
p := extension.GetProtocol(u.Protocol)
invoker := p.Refer(u)
return &MetadataServiceProxy{
invkr: invoker,
}
}
// buildStandardMetadataServiceURL will use standard format to build the metadata service url.
func buildStandardMetadataServiceURL(ins registry.ServiceInstance) []*common.URL {
ps := getMetadataServiceUrlParams(ins)
if ps[constant.ProtocolKey] == "" {
return nil
}
res := make([]*common.URL, 0, len(ps))
sn := ins.GetServiceName()
host := ins.GetHost()
convertedParams := make(map[string][]string, len(ps))
for k, v := range ps {
convertedParams[k] = []string{v}
}
u := common.NewURLWithOptions(common.WithIp(host),
common.WithPath(constant.MetadataServiceName),
common.WithProtocol(ps[constant.ProtocolKey]),
common.WithPort(ps[constant.PortKey]),
common.WithParams(convertedParams),
common.WithParamsValue(constant.GroupKey, sn),
common.WithParamsValue(constant.InterfaceKey, constant.MetadataServiceName))
res = append(res, u)
return res
}
// getMetadataServiceUrlParams this will convert the metadata service url parameters to map structure
// it looks like:
// {"dubbo":{"timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"20880"}}
func getMetadataServiceUrlParams(ins registry.ServiceInstance) map[string]string {
ps := ins.GetMetadata()
res := make(map[string]string, 2)
if str, ok := ps[constant.MetadataServiceURLParamsPropertyName]; ok && len(str) > 0 {
err := json.Unmarshal([]byte(str), &res)
if err != nil {
logger.Errorf("could not parse the metadata service url parameters to map", err)
}
}
return res
}