dubbo.apache.org/dubbo-go/v3@v3.1.1/metadata/service/remote/service.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package remote 19 20 import ( 21 "sync" 22 ) 23 24 import ( 25 "github.com/dubbogo/gost/log/logger" 26 27 "go.uber.org/atomic" 28 ) 29 30 import ( 31 "dubbo.apache.org/dubbo-go/v3/common" 32 "dubbo.apache.org/dubbo-go/v3/common/constant" 33 "dubbo.apache.org/dubbo-go/v3/common/extension" 34 "dubbo.apache.org/dubbo-go/v3/metadata/definition" 35 "dubbo.apache.org/dubbo-go/v3/metadata/identifier" 36 "dubbo.apache.org/dubbo-go/v3/metadata/report/delegate" 37 "dubbo.apache.org/dubbo-go/v3/metadata/service" 38 "dubbo.apache.org/dubbo-go/v3/metadata/service/local" 39 "dubbo.apache.org/dubbo-go/v3/registry" 40 ) 41 42 type MetadataService struct { 43 *local.MetadataService 44 exportedRevision atomic.String 45 subscribedRevision atomic.String 46 delegateReport *delegate.MetadataReport 47 } 48 49 var ( 50 metadataServiceOnce sync.Once 51 remoteMetadataServiceInstance service.RemoteMetadataService 52 ) 53 54 func init() { 55 extension.SetRemoteMetadataService(GetRemoteMetadataService) 56 } 57 58 // GetRemoteMetadataService will create a new remote MetadataService instance 59 func GetRemoteMetadataService() (service.RemoteMetadataService, error) { 60 var err error 61 metadataServiceOnce.Do(func() { 62 var mr *delegate.MetadataReport 63 mr, err = delegate.NewMetadataReport() 64 if err != nil { 65 return 66 } 67 // it will never return error 68 inms, _ := local.GetLocalMetadataService() 69 remoteMetadataServiceInstance = &MetadataService{ 70 // todo serviceName 71 //BaseMetadataService: service.NewBaseMetadataService(""), 72 MetadataService: inms.(*local.MetadataService), 73 delegateReport: mr, 74 } 75 }) 76 return remoteMetadataServiceInstance, err 77 } 78 79 // PublishMetadata publishes the metadata info of @service to remote metadata center 80 func (s *MetadataService) PublishMetadata(service string) { 81 info, err := s.MetadataService.GetMetadataInfo("") 82 if err != nil { 83 logger.Errorf("GetMetadataInfo error[%v]", err) 84 return 85 } 86 if info.HasReported() { 87 return 88 } 89 id := identifier.NewSubscriberMetadataIdentifier(service, info.CalAndGetRevision()) 90 err = s.delegateReport.PublishAppMetadata(id, info) 91 if err != nil { 92 logger.Errorf("Publishing metadata to error[%v]", err) 93 return 94 } 95 info.MarkReported() 96 } 97 98 // GetMetadata get the medata info of service from report 99 func (s *MetadataService) GetMetadata(instance registry.ServiceInstance) (*common.MetadataInfo, error) { 100 revision := instance.GetMetadata()[constant.ExportedServicesRevisionPropertyName] 101 id := identifier.NewSubscriberMetadataIdentifier(instance.GetServiceName(), revision) 102 return s.delegateReport.GetAppMetadata(id) 103 } 104 105 // PublishServiceDefinition will call remote metadata's StoreProviderMetadata to store url info and service definition 106 func (s *MetadataService) PublishServiceDefinition(url *common.URL) error { 107 interfaceName := url.GetParam(constant.InterfaceKey, "") 108 isGeneric := url.GetParamBool(constant.GenericKey, false) 109 if common.RoleType(common.PROVIDER).Role() == url.GetParam(constant.SideKey, "") { 110 if len(interfaceName) > 0 && !isGeneric { 111 sv := common.ServiceMap.GetServiceByServiceKey(url.Protocol, url.ServiceKey()) 112 sd := definition.BuildFullDefinition(*sv, url) 113 id := &identifier.MetadataIdentifier{ 114 BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ 115 ServiceInterface: interfaceName, 116 Version: url.GetParam(constant.VersionKey, ""), 117 Group: url.GetParam(constant.GroupKey, constant.Dubbo), 118 Side: url.GetParam(constant.SideKey, constant.ProviderProtocol), 119 }, 120 } 121 s.delegateReport.StoreProviderMetadata(id, sd) 122 return nil 123 } 124 logger.Errorf("publishProvider interfaceName is empty . providerUrl:%v ", url) 125 } else { 126 params := make(map[string]string, len(url.GetParams())) 127 url.RangeParams(func(key, value string) bool { 128 params[key] = value 129 return true 130 }) 131 id := &identifier.MetadataIdentifier{ 132 BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ 133 ServiceInterface: interfaceName, 134 Version: url.GetParam(constant.VersionKey, ""), 135 Group: url.GetParam(constant.GroupKey, constant.Dubbo), 136 Side: url.GetParam(constant.SideKey, "consumer"), 137 }, 138 } 139 s.delegateReport.StoreConsumerMetadata(id, params) 140 return nil 141 } 142 143 return nil 144 }