From 6e574cc9c1770a3862c289d4ea4da7d295cbae18 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 22 Mar 2020 15:44:37 +0800 Subject: [PATCH 001/209] Add:format dir --- common/extension/metadata_report_factory.go | 8 +- config/instance/metedata_report.go | 6 +- go.mod | 1 + go.sum | 2 + metadata/{ => exporter}/exporter.go | 2 +- metadata/{ => report}/report.go | 2 +- .../{ => report_factory}/report_factory.go | 7 +- metadata/service/inmemory/in_memory.go | 116 ++++++++++++++++++ metadata/{ => service}/service.go | 35 ++++-- 9 files changed, 159 insertions(+), 20 deletions(-) rename metadata/{ => exporter}/exporter.go (98%) rename metadata/{ => report}/report.go (98%) rename metadata/{ => report_factory}/report_factory.go (84%) create mode 100644 metadata/service/inmemory/in_memory.go rename metadata/{ => service}/service.go (56%) diff --git a/common/extension/metadata_report_factory.go b/common/extension/metadata_report_factory.go index 0ae0793bb4..7a113c4606 100644 --- a/common/extension/metadata_report_factory.go +++ b/common/extension/metadata_report_factory.go @@ -18,20 +18,20 @@ package extension import ( - "github.com/apache/dubbo-go/metadata" + "github.com/apache/dubbo-go/metadata/report_factory" ) var ( - metaDataReportFactories = make(map[string]func() metadata.MetadataReportFactory, 8) + metaDataReportFactories = make(map[string]func() report_factory.MetadataReportFactory, 8) ) // SetMetadataReportFactory ... -func SetMetadataReportFactory(name string, v func() metadata.MetadataReportFactory) { +func SetMetadataReportFactory(name string, v func() report_factory.MetadataReportFactory) { metaDataReportFactories[name] = v } // GetMetadataReportFactory ... -func GetMetadataReportFactory(name string) metadata.MetadataReportFactory { +func GetMetadataReportFactory(name string) report_factory.MetadataReportFactory { if metaDataReportFactories[name] == nil { panic("metadata report for " + name + " is not existing, make sure you have import the package.") } diff --git a/config/instance/metedata_report.go b/config/instance/metedata_report.go index cd54b0a794..6adc7e8a68 100644 --- a/config/instance/metedata_report.go +++ b/config/instance/metedata_report.go @@ -18,22 +18,22 @@ package instance import ( + "github.com/apache/dubbo-go/metadata/report" "sync" ) import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/metadata" ) var ( - instance metadata.MetadataReport + instance report.MetadataReport once sync.Once ) // GetMetadataReportInstance ... -func GetMetadataReportInstance(url *common.URL) metadata.MetadataReport { +func GetMetadataReportInstance(url *common.URL) report.MetadataReport { once.Do(func() { instance = extension.GetMetadataReportFactory(url.Protocol).CreateMetadataReport(url) }) diff --git a/go.mod b/go.mod index a4294a62dd..5aaa1152bc 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/dubbogo/getty v1.3.3 github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.7.0 + github.com/emirpasic/gods v1.12.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect diff --git a/go.sum b/go.sum index 6dc55c634c..65aba5e0e2 100644 --- a/go.sum +++ b/go.sum @@ -116,6 +116,8 @@ github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIh github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0 h1:ZoRgc53qJCfSLimXqJDrmBhnt5GChDsExMCK7t48o0Y= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1dNoi6Zs1+Ybvk= github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk= github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM= diff --git a/metadata/exporter.go b/metadata/exporter/exporter.go similarity index 98% rename from metadata/exporter.go rename to metadata/exporter/exporter.go index 5d47f8bd80..a6290c1ea9 100644 --- a/metadata/exporter.go +++ b/metadata/exporter/exporter.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package metadata +package exporter import ( "github.com/apache/dubbo-go/common" diff --git a/metadata/report.go b/metadata/report/report.go similarity index 98% rename from metadata/report.go rename to metadata/report/report.go index 3fcc712414..d3436101a3 100644 --- a/metadata/report.go +++ b/metadata/report/report.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package metadata +package report import ( "github.com/apache/dubbo-go/common" diff --git a/metadata/report_factory.go b/metadata/report_factory/report_factory.go similarity index 84% rename from metadata/report_factory.go rename to metadata/report_factory/report_factory.go index 19b1004eee..f4497f415b 100644 --- a/metadata/report_factory.go +++ b/metadata/report_factory/report_factory.go @@ -15,16 +15,17 @@ * limitations under the License. */ -package metadata +package report_factory import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/metadata/report" ) var ( - MetadataReportInstance MetadataReport + MetadataReportInstance report.MetadataReport ) type MetadataReportFactory interface { - CreateMetadataReport(*common.URL) MetadataReport + CreateMetadataReport(*common.URL) report.MetadataReport } diff --git a/metadata/service/inmemory/in_memory.go b/metadata/service/inmemory/in_memory.go new file mode 100644 index 0000000000..981af666e6 --- /dev/null +++ b/metadata/service/inmemory/in_memory.go @@ -0,0 +1,116 @@ +/* + * 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 inmemory + +import ( + "sync" +) + +import ( + "github.com/emirpasic/gods/sets" + "github.com/emirpasic/gods/sets/treeset" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/metadata/service" +) + +// InMemoryMetadataService is store and query the metadata info in memory when each service registry +type MetadataService struct { + service.BaseMetadataService + exportedServiceURLs sync.Map + subscribedServiceURLs sync.Map +} + +// urlComparator: defined as utils.Comparator for treeset to compare the URL +func urlComparator(a, b interface{}) int { + url1 := a.(common.URL) + url2 := b.(common.URL) + switch { + case url1.String() > url2.String(): + return 1 + case url1.String() < url2.String(): + return -1 + default: + return 0 + } +} + +// addURL: add URL in memory +func addURL(targetMap sync.Map, url common.URL) bool { + var ( + urlSet interface{} + loaded bool + lock sync.RWMutex + ) + if urlSet, loaded = targetMap.LoadOrStore(url.ServiceKey(), treeset.NewWith(urlComparator)); loaded { + lock.RLock() + if urlSet.(treeset.Set).Contains(url) { + lock.RUnlock() + return false + } + lock.RUnlock() + } + lock.Lock() + urlSet.(treeset.Set).Add(url) + lock.Unlock() + return true +} + +// name... +func removeURL(targetMap sync.Map, url common.URL) string { + if value, loaded := targetMap.Load(url.ServiceKey()); loaded { + value.(treeset.Set).Remove(url) + if value.(treeset.Set).Empty() { + targetMap.Delete(url.ServiceKey()) + } + } +} + +// ExportURL: store the in memory treeset +func (mts *MetadataService) ExportURL(url common.URL) bool { + return addURL(mts.exportedServiceURLs, url) +} + +func (MetadataService) UnexportURL(url common.URL) bool { + panic("implement me") +} + +func (mts *MetadataService) SubscribeURL(url common.URL) bool { + return addURL(mts.subscribedServiceURLs, url) +} + +func (MetadataService) UnsubscribeURL(url common.URL) bool { + panic("implement me") +} + +func (MetadataService) PublishServiceDefinition(url common.URL) { + panic("implement me") +} + +func (MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) sets.Set { + panic("implement me") +} + +func (MetadataService) GetServiceDefinition(interfaceName string, version string, group string) string { + panic("implement me") +} + +func (MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) string { + panic("implement me") +} diff --git a/metadata/service.go b/metadata/service/service.go similarity index 56% rename from metadata/service.go rename to metadata/service/service.go index d85703c95a..af819cba85 100644 --- a/metadata/service.go +++ b/metadata/service/service.go @@ -15,23 +15,42 @@ * limitations under the License. */ -package metadata +package service + +import ( + "github.com/emirpasic/gods/sets" +) import ( "github.com/apache/dubbo-go/common" - gxset "github.com/dubbogo/gost/container/set" + "github.com/apache/dubbo-go/config" ) +// Metadataservice is used to define meta data related behaviors type MetadataService interface { ServiceName() string - ExportURL(url *common.URL) bool - UnexportURL(url *common.URL) bool + 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) + 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 + GetExportedURLs(serviceInterface string, group string, version string, protocol string) sets.Set GetServiceDefinition(interfaceName string, version string, group string) string GetServiceDefinitionByServiceKey(serviceKey string) string } + +// BaseMetadataService: is used for the common logic for struct who will implement interface MetadataService +type BaseMetadataService struct { +} + +// ServiceName: get the service's name in meta service , which is application name +func (mts *BaseMetadataService) ServiceName() string { + return config.GetApplicationConfig().Name +} + +// RefreshMetadata: used for event listener's calling, to refresh metadata +func (mts *BaseMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { + return true +} From 485cd5f788c68d601fc9582a696362b6ba8d791e Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 22 Mar 2020 18:43:29 +0800 Subject: [PATCH 002/209] Mod:format mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ac76a7dec9..26c724d177 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,8 @@ require ( github.com/dubbogo/getty v1.3.3 github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.7.0 - github.com/emirpasic/gods v1.12.0 github.com/emicklei/go-restful/v3 v3.0.0 + github.com/emirpasic/gods v1.12.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 From 95b4658c34bf086905173950659b5134038175d8 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 24 Mar 2020 20:20:44 +0800 Subject: [PATCH 003/209] align 2.7.8: direct event dispatcher --- common/extension/event_dispatcher.go | 32 +++++ common/observer/direct_event_dispatcher.go | 60 +++++++++ common/observer/event.go | 66 ++++++++++ .../event/ServiceInstancesChangedEvent.go | 29 +++++ common/observer/event_dispatcher.go | 27 ++++ .../observer}/event_listener.go | 9 +- common/observer/listenable.go | 120 ++++++++++++++++++ common/observer/listenable_test.go | 30 +++++ .../ServiceInstancesChangedListener.go | 41 ++++++ registry/event.go | 44 ------- registry/service_discovery.go | 6 +- 11 files changed, 413 insertions(+), 51 deletions(-) create mode 100644 common/extension/event_dispatcher.go create mode 100644 common/observer/direct_event_dispatcher.go create mode 100644 common/observer/event.go create mode 100644 common/observer/event/ServiceInstancesChangedEvent.go create mode 100644 common/observer/event_dispatcher.go rename {registry => common/observer}/event_listener.go (92%) create mode 100644 common/observer/listenable.go create mode 100644 common/observer/listenable_test.go create mode 100644 common/observer/listener/ServiceInstancesChangedListener.go diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go new file mode 100644 index 0000000000..9bc7842469 --- /dev/null +++ b/common/extension/event_dispatcher.go @@ -0,0 +1,32 @@ +/* + * 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/common/observer" + +func GetDispatcherEvent(name string) { + +} + +func SetDefaultDispatcherEvent() { + +} + +func AddEventListener(listener observer.EventListener) { + +} diff --git a/common/observer/direct_event_dispatcher.go b/common/observer/direct_event_dispatcher.go new file mode 100644 index 0000000000..ddd999c2a5 --- /dev/null +++ b/common/observer/direct_event_dispatcher.go @@ -0,0 +1,60 @@ +/* + * 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 observer + +import ( + "github.com/apache/dubbo-go/common/logger" + "reflect" +) + +var directEventDispatcher *DirectEventDispatcher + +// DirectEventDispatcher is align with DirectEventDispatcher interface in Java. +// it's the top abstraction +// Align with 2.7.5 +// Dispatcher event to listener direct +type DirectEventDispatcher struct { + BaseListenable + EventDispatcher +} + +func NewDirectEventDispatcher() *DirectEventDispatcher { + return &DirectEventDispatcher{} +} + +func (ded *DirectEventDispatcher) Dispatch(event Event) { + eventType := reflect.TypeOf(event).Elem() + value, loaded := ded.listenersCache.Load(eventType) + if !loaded { + return + } + listenersSlice := value.([]EventListener) + for _, listener := range listenersSlice { + if err := listener.OnEvent(event); err != nil { + logger.Warnf("[DirectEventDispatcher] dispatch event error:%v", err) + } + } +} + +// GetSingleDirectEventDispatcher ... +func GetSingleDirectEventDispatcher() EventDispatcher { + if directEventDispatcher == nil { + directEventDispatcher = NewDirectEventDispatcher() + } + return directEventDispatcher +} diff --git a/common/observer/event.go b/common/observer/event.go new file mode 100644 index 0000000000..d63d7836bb --- /dev/null +++ b/common/observer/event.go @@ -0,0 +1,66 @@ +/* + * 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 observer + +import ( + "fmt" + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// Event is align with Event interface in Java. +// it's the top abstraction +// Align with 2.7.5 +type Event interface { + fmt.Stringer + GetSource() interface{} + GetTimestamp() time.Time +} + +// baseEvent is the base implementation of Event +// You should never use it directly +type BaseEvent struct { + source interface{} + timestamp time.Time +} + +// GetSource return the source +func (b *BaseEvent) GetSource() interface{} { + return b.source +} + +// GetTimestamp return the timestamp when the event is created +func (b *BaseEvent) GetTimestamp() time.Time { + return b.timestamp +} + +// String return a human readable string representing this event +func (b *BaseEvent) String() string { + return fmt.Sprintf("baseEvent[source = %#v]", b.source) +} + +func newBaseEvent(source interface{}) *BaseEvent { + return &BaseEvent{ + source: source, + timestamp: time.Now(), + } +} diff --git a/common/observer/event/ServiceInstancesChangedEvent.go b/common/observer/event/ServiceInstancesChangedEvent.go new file mode 100644 index 0000000000..d85a6d5737 --- /dev/null +++ b/common/observer/event/ServiceInstancesChangedEvent.go @@ -0,0 +1,29 @@ +/* + * 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 event + +import ( + "fmt" + "github.com/apache/dubbo-go/common/observer" +) + +// ServiceInstancesChangedEvent represents service instances make some changing +type ServiceInstancesChangedEvent struct { + fmt.Stringer + observer.BaseEvent +} diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go new file mode 100644 index 0000000000..17745e68c0 --- /dev/null +++ b/common/observer/event_dispatcher.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 observer + +// EventDispatcher is align with EventDispatcher interface in Java. +// it's the top abstraction +// Align with 2.7.5 +type EventDispatcher interface { + Listenable + // Dispatch event + Dispatch(event Event) +} diff --git a/registry/event_listener.go b/common/observer/event_listener.go similarity index 92% rename from registry/event_listener.go rename to common/observer/event_listener.go index 810420319b..2b71faf2f5 100644 --- a/registry/event_listener.go +++ b/common/observer/event_listener.go @@ -15,10 +15,11 @@ * limitations under the License. */ -package registry +package observer import ( gxsort "github.com/dubbogo/gost/sort" + "reflect" ) // EventListener is an new interface used to align with dubbo 2.7.5 @@ -27,6 +28,8 @@ type EventListener interface { gxsort.Prioritizer // OnEvent handle this event OnEvent(e Event) error + // GetEventType listen which event type + GetEventType() reflect.Type } // ConditionalEventListener only handle the event which it can handle @@ -35,7 +38,3 @@ type ConditionalEventListener interface { // Accept will make the decision whether it should handle this event Accept(e Event) bool } - -// TODO (implement ConditionalEventListener) -type ServiceInstancesChangedListener struct { -} diff --git a/common/observer/listenable.go b/common/observer/listenable.go new file mode 100644 index 0000000000..f91e96902c --- /dev/null +++ b/common/observer/listenable.go @@ -0,0 +1,120 @@ +/* + * 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 observer + +import ( + "sort" + "sync" +) + +type Listenable interface { + AddEventListener(listener EventListener) + AddEventListeners(listenersSlice []EventListener) + RemoveEventListener(listener EventListener) + RemoveEventListeners(listenersSlice []EventListener) + GetAllEventListeners() []EventListener + RemoveAllEventListeners() +} + +type BaseListenable struct { + Listenable + listenersCache sync.Map + mutex sync.Mutex +} + +func (bl *BaseListenable) AddEventListener(listener EventListener) { + eventType := listener.GetEventType() + var listenersSlice []EventListener + bl.mutex.Lock() + defer bl.mutex.Unlock() + if value, loaded := bl.listenersCache.Load(eventType); loaded { + listenersSlice = value.([]EventListener) + if !containListener(listenersSlice, listener) { + listenersSlice = append(listenersSlice, listener) + } + } else { + listenersSlice = make([]EventListener, 0, 8) + listenersSlice = append(listenersSlice, listener) + } + sort.Slice(listenersSlice, func(i, j int) bool { + return listenersSlice[i].GetPriority() < listenersSlice[j].GetPriority() + }) + bl.listenersCache.Store(eventType, listenersSlice) +} + +func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { + bl.mutex.Lock() + defer bl.mutex.Unlock() + for _, listener := range listenersSlice { + bl.AddEventListener(listener) + } +} + +func (bl *BaseListenable) RemoveEventListener(listener EventListener) { + eventType := listener.GetEventType() + bl.mutex.Lock() + defer bl.mutex.Unlock() + value, loaded := bl.listenersCache.Load(eventType) + if !loaded { + return + } + listenersSlice := value.([]EventListener) + for i, listener := range listenersSlice { + if listener == listener { + listenersSlice = append(listenersSlice[:i], listenersSlice[i+1:]...) + } + } +} + +func (bl *BaseListenable) RemoveEventListeners(listenersSlice []EventListener) { + bl.mutex.Lock() + defer bl.mutex.Unlock() + for _, listener := range listenersSlice { + bl.RemoveEventListener(listener) + } +} + +func (bl *BaseListenable) RemoveAllEventListeners() { + bl.mutex.Lock() + defer bl.mutex.Unlock() + bl.listenersCache = *new(sync.Map) +} + +func (bl *BaseListenable) GetAllEventListeners() []EventListener { + bl.mutex.Lock() + defer bl.mutex.Unlock() + allListenersSlice := make([]EventListener, 0, 16) + bl.listenersCache.Range(func(_, value interface{}) bool { + listenersSlice := value.([]EventListener) + allListenersSlice = append(allListenersSlice, listenersSlice...) + return true + }) + sort.Slice(allListenersSlice, func(i, j int) bool { + return allListenersSlice[i].GetPriority() < allListenersSlice[j].GetPriority() + }) + return allListenersSlice +} + +func containListener(listenersSlice []EventListener, listener EventListener) bool { + for _, loadListener := range listenersSlice { + if loadListener == listener { + return true + } + } + return false +} diff --git a/common/observer/listenable_test.go b/common/observer/listenable_test.go new file mode 100644 index 0000000000..35843bc91a --- /dev/null +++ b/common/observer/listenable_test.go @@ -0,0 +1,30 @@ +/* + * 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 observer + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestListenable(t *testing.T) { + var b EventListener = &ServiceInstancesChangedListener{} + var a EventListener = &ServiceInstancesChangedListener{} + + assert.True(t, b == a) +} diff --git a/common/observer/listener/ServiceInstancesChangedListener.go b/common/observer/listener/ServiceInstancesChangedListener.go new file mode 100644 index 0000000000..6ba680e2a7 --- /dev/null +++ b/common/observer/listener/ServiceInstancesChangedListener.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 listener + +import ( + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/common/observer/event" + "reflect" +) + +// TODO (implement ConditionalEventListener) +type ServiceInstancesChangedListener struct { + observer.EventListener +} + +func (sicl *ServiceInstancesChangedListener) OnEvent(e observer.Event) error { + return nil +} + +func (sicl *ServiceInstancesChangedListener) GetPriority() int { + return -1 +} + +func (sicl *ServiceInstancesChangedListener) GetEventType() reflect.Type { + return reflect.TypeOf(&event.ServiceInstancesChangedEvent{}) +} diff --git a/registry/event.go b/registry/event.go index 0500cc7018..7a41973b24 100644 --- a/registry/event.go +++ b/registry/event.go @@ -45,47 +45,3 @@ type ServiceEvent struct { func (e ServiceEvent) String() string { return fmt.Sprintf("ServiceEvent{Action{%s}, Path{%s}}", e.Action, e.Service) } - -// Event is align with Event interface in Java. -// it's the top abstraction -// Align with 2.7.5 -type Event interface { - fmt.Stringer - GetSource() interface{} - GetTimestamp() time.Time -} - -// baseEvent is the base implementation of Event -// You should never use it directly -type baseEvent struct { - source interface{} - timestamp time.Time -} - -// GetSource return the source -func (b *baseEvent) GetSource() interface{} { - return b.source -} - -// GetTimestamp return the timestamp when the event is created -func (b *baseEvent) GetTimestamp() time.Time { - return b.timestamp -} - -// String return a human readable string representing this event -func (b *baseEvent) String() string { - return fmt.Sprintf("baseEvent[source = %#v]", b.source) -} - -func newBaseEvent(source interface{}) *baseEvent { - return &baseEvent{ - source: source, - timestamp: time.Now(), - } -} - -// ServiceInstancesChangedEvent represents service instances make some changing -type ServiceInstancesChangedEvent struct { - fmt.Stringer - baseEvent -} diff --git a/registry/service_discovery.go b/registry/service_discovery.go index 5577f52930..5a65e9f679 100644 --- a/registry/service_discovery.go +++ b/registry/service_discovery.go @@ -28,6 +28,8 @@ import ( import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/observer/event" + eventlistener "github.com/apache/dubbo-go/common/observer/listener" ) type ServiceDiscovery interface { @@ -78,7 +80,7 @@ type ServiceDiscovery interface { // ----------------- event ---------------------- // AddListener adds a new ServiceInstancesChangedListener - AddListener(listener *ServiceInstancesChangedListener) error + AddListener(listener *eventlistener.ServiceInstancesChangedListener) error // DispatchEventByServiceName dispatches the ServiceInstancesChangedEvent to service instance whose name is serviceName DispatchEventByServiceName(serviceName string) error @@ -87,5 +89,5 @@ type ServiceDiscovery interface { DispatchEventForInstances(serviceName string, instances []ServiceInstance) error // DispatchEvent dispatches the event - DispatchEvent(event ServiceInstancesChangedEvent) error + DispatchEvent(event event.ServiceInstancesChangedEvent) error } From 259e3c182bc658543890e0f8b95624d3b31a4fd9 Mon Sep 17 00:00:00 2001 From: Patrick Date: Thu, 26 Mar 2020 20:33:32 +0800 Subject: [PATCH 004/209] dispatcher in extension --- common/extension/event_dispatcher.go | 34 ++++++++++++++++--- .../direct_event_dispatcher.go | 28 +++++++-------- common/observer/listenable.go | 32 +++++++---------- common/observer/listenable_test.go | 5 +-- config/base_config.go | 15 ++++---- config/config_loader.go | 12 +++++++ .../ServiceInstancesChangedListener.go | 5 +++ registry/service_discovery.go | 2 +- 8 files changed, 83 insertions(+), 50 deletions(-) rename common/observer/{ => dispatcher}/direct_event_dispatcher.go (72%) rename {common/observer => registry}/listener/ServiceInstancesChangedListener.go (91%) diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go index 9bc7842469..d2349e0db8 100644 --- a/common/extension/event_dispatcher.go +++ b/common/extension/event_dispatcher.go @@ -17,16 +17,42 @@ package extension -import "github.com/apache/dubbo-go/common/observer" +import ( + "github.com/apache/dubbo-go/common/observer" + "github.com/prometheus/common/log" +) -func GetDispatcherEvent(name string) { +var eventListeners []observer.EventListener -} +var globalEventDispatcher observer.EventDispatcher -func SetDefaultDispatcherEvent() { +var ( + dispatchers = make(map[string]func() observer.EventDispatcher, 8) +) +func SetEventDispatcher(name string, v func() observer.EventDispatcher) { + dispatchers[name] = v } func AddEventListener(listener observer.EventListener) { + eventListeners = append(eventListeners, listener) +} + +// s +func SetAndInitGlobalDispatcher(name string) { + if len(name) == 0 { + name = "direct" + } + if globalEventDispatcher != nil { + log.Warnf("EventDispatcher already init. It will be replaced") + } + if dispatchers[name] == nil { + panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") + } + globalEventDispatcher = dispatchers[name]() + globalEventDispatcher.AddEventListeners(eventListeners) +} +func GetGlobalDispatcher() observer.EventDispatcher { + return globalEventDispatcher } diff --git a/common/observer/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go similarity index 72% rename from common/observer/direct_event_dispatcher.go rename to common/observer/dispatcher/direct_event_dispatcher.go index ddd999c2a5..ab53ef0b2f 100644 --- a/common/observer/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -15,46 +15,42 @@ * limitations under the License. */ -package observer +package dispatcher import ( + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/common/observer" "reflect" ) -var directEventDispatcher *DirectEventDispatcher +func init() { + extension.SetEventDispatcher("direct", NewDirectEventDispatcher) +} // DirectEventDispatcher is align with DirectEventDispatcher interface in Java. // it's the top abstraction // Align with 2.7.5 // Dispatcher event to listener direct type DirectEventDispatcher struct { - BaseListenable - EventDispatcher + observer.BaseListenable + observer.EventDispatcher } -func NewDirectEventDispatcher() *DirectEventDispatcher { +func NewDirectEventDispatcher() observer.EventDispatcher { return &DirectEventDispatcher{} } -func (ded *DirectEventDispatcher) Dispatch(event Event) { +func (ded *DirectEventDispatcher) Dispatch(event observer.Event) { eventType := reflect.TypeOf(event).Elem() - value, loaded := ded.listenersCache.Load(eventType) + value, loaded := ded.ListenersCache.Load(eventType) if !loaded { return } - listenersSlice := value.([]EventListener) + listenersSlice := value.([]observer.EventListener) for _, listener := range listenersSlice { if err := listener.OnEvent(event); err != nil { logger.Warnf("[DirectEventDispatcher] dispatch event error:%v", err) } } } - -// GetSingleDirectEventDispatcher ... -func GetSingleDirectEventDispatcher() EventDispatcher { - if directEventDispatcher == nil { - directEventDispatcher = NewDirectEventDispatcher() - } - return directEventDispatcher -} diff --git a/common/observer/listenable.go b/common/observer/listenable.go index f91e96902c..4ceb03b0ae 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -33,16 +33,16 @@ type Listenable interface { type BaseListenable struct { Listenable - listenersCache sync.Map - mutex sync.Mutex + ListenersCache sync.Map + Mutex sync.Mutex } func (bl *BaseListenable) AddEventListener(listener EventListener) { eventType := listener.GetEventType() var listenersSlice []EventListener - bl.mutex.Lock() - defer bl.mutex.Unlock() - if value, loaded := bl.listenersCache.Load(eventType); loaded { + bl.Mutex.Lock() + defer bl.Mutex.Unlock() + if value, loaded := bl.ListenersCache.Load(eventType); loaded { listenersSlice = value.([]EventListener) if !containListener(listenersSlice, listener) { listenersSlice = append(listenersSlice, listener) @@ -54,12 +54,10 @@ func (bl *BaseListenable) AddEventListener(listener EventListener) { sort.Slice(listenersSlice, func(i, j int) bool { return listenersSlice[i].GetPriority() < listenersSlice[j].GetPriority() }) - bl.listenersCache.Store(eventType, listenersSlice) + bl.ListenersCache.Store(eventType, listenersSlice) } func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { - bl.mutex.Lock() - defer bl.mutex.Unlock() for _, listener := range listenersSlice { bl.AddEventListener(listener) } @@ -67,9 +65,9 @@ func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { func (bl *BaseListenable) RemoveEventListener(listener EventListener) { eventType := listener.GetEventType() - bl.mutex.Lock() - defer bl.mutex.Unlock() - value, loaded := bl.listenersCache.Load(eventType) + bl.Mutex.Lock() + defer bl.Mutex.Unlock() + value, loaded := bl.ListenersCache.Load(eventType) if !loaded { return } @@ -82,24 +80,20 @@ func (bl *BaseListenable) RemoveEventListener(listener EventListener) { } func (bl *BaseListenable) RemoveEventListeners(listenersSlice []EventListener) { - bl.mutex.Lock() - defer bl.mutex.Unlock() for _, listener := range listenersSlice { bl.RemoveEventListener(listener) } } func (bl *BaseListenable) RemoveAllEventListeners() { - bl.mutex.Lock() - defer bl.mutex.Unlock() - bl.listenersCache = *new(sync.Map) + bl.Mutex.Lock() + defer bl.Mutex.Unlock() + bl.ListenersCache = *new(sync.Map) } func (bl *BaseListenable) GetAllEventListeners() []EventListener { - bl.mutex.Lock() - defer bl.mutex.Unlock() allListenersSlice := make([]EventListener, 0, 16) - bl.listenersCache.Range(func(_, value interface{}) bool { + bl.ListenersCache.Range(func(_, value interface{}) bool { listenersSlice := value.([]EventListener) allListenersSlice = append(allListenersSlice, listenersSlice...) return true diff --git a/common/observer/listenable_test.go b/common/observer/listenable_test.go index 35843bc91a..d1a16176f0 100644 --- a/common/observer/listenable_test.go +++ b/common/observer/listenable_test.go @@ -18,13 +18,14 @@ package observer import ( + "github.com/apache/dubbo-go/registry/listener" "github.com/stretchr/testify/assert" "testing" ) func TestListenable(t *testing.T) { - var b EventListener = &ServiceInstancesChangedListener{} - var a EventListener = &ServiceInstancesChangedListener{} + var b EventListener = &listener.ServiceInstancesChangedListener{} + var a EventListener = &listener.ServiceInstancesChangedListener{} assert.True(t, b == a) } diff --git a/config/base_config.go b/config/base_config.go index 93c0ce6a66..74634a5f63 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -42,14 +42,13 @@ type multiConfiger interface { // BaseConfig is the common configuration for provider and consumer type BaseConfig struct { - ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` - configCenterUrl *common.URL - prefix string - fatherConfig interface{} - - MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"` - - fileStream *bytes.Buffer + ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` + configCenterUrl *common.URL + prefix string + fatherConfig interface{} + eventDispatcherType string `yaml:"direct" json:"direct,omitempty"` + MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"` + fileStream *bytes.Buffer } // startConfigCenter will start the config center. diff --git a/config/config_loader.go b/config/config_loader.go index c0687d8fc1..7af073923e 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -33,6 +33,7 @@ import ( "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/common/observer/dispatcher" ) var ( @@ -91,6 +92,17 @@ func Load() { } } + var eventDispatcherType string + if consumerConfig != nil { + eventDispatcherType = consumerConfig.eventDispatcherType + } + // notice consumerConfig.eventDispatcherType will be replaced + if providerConfig != nil { + eventDispatcherType = providerConfig.eventDispatcherType + } + // init EventDispatcher + extension.SetAndInitGlobalDispatcher(eventDispatcherType) + // reference config if consumerConfig == nil { logger.Warnf("consumerConfig is nil!") diff --git a/common/observer/listener/ServiceInstancesChangedListener.go b/registry/listener/ServiceInstancesChangedListener.go similarity index 91% rename from common/observer/listener/ServiceInstancesChangedListener.go rename to registry/listener/ServiceInstancesChangedListener.go index 6ba680e2a7..cd48ceb4f2 100644 --- a/common/observer/listener/ServiceInstancesChangedListener.go +++ b/registry/listener/ServiceInstancesChangedListener.go @@ -18,11 +18,16 @@ package listener import ( + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/common/observer/event" "reflect" ) +func init() { + extension.AddEventListener(&ServiceInstancesChangedListener{}) +} + // TODO (implement ConditionalEventListener) type ServiceInstancesChangedListener struct { observer.EventListener diff --git a/registry/service_discovery.go b/registry/service_discovery.go index 5a65e9f679..b3ebc05564 100644 --- a/registry/service_discovery.go +++ b/registry/service_discovery.go @@ -29,7 +29,7 @@ import ( import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/observer/event" - eventlistener "github.com/apache/dubbo-go/common/observer/listener" + eventlistener "github.com/apache/dubbo-go/registry/listener" ) type ServiceDiscovery interface { From 8e2adc55136f97107fb55def3da568ccadbff3ff Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 29 Mar 2020 14:16:00 +0800 Subject: [PATCH 005/209] add unit test and move extension to observer --- common/extension/event_dispatcher.go | 58 --------------- .../dispatcher/direct_event_dispatcher.go | 4 +- .../direct_event_dispatcher_test.go | 71 +++++++++++++++++++ common/observer/event_dispatcher.go | 33 +++++++++ common/observer/event_listener.go | 7 ++ common/observer/listenable.go | 23 ++++-- common/observer/listenable_test.go | 38 ++++++++-- config/config_loader.go | 3 +- .../ServiceInstancesChangedListener.go | 3 +- 9 files changed, 166 insertions(+), 74 deletions(-) delete mode 100644 common/extension/event_dispatcher.go create mode 100644 common/observer/dispatcher/direct_event_dispatcher_test.go diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go deleted file mode 100644 index d2349e0db8..0000000000 --- a/common/extension/event_dispatcher.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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/common/observer" - "github.com/prometheus/common/log" -) - -var eventListeners []observer.EventListener - -var globalEventDispatcher observer.EventDispatcher - -var ( - dispatchers = make(map[string]func() observer.EventDispatcher, 8) -) - -func SetEventDispatcher(name string, v func() observer.EventDispatcher) { - dispatchers[name] = v -} - -func AddEventListener(listener observer.EventListener) { - eventListeners = append(eventListeners, listener) -} - -// s -func SetAndInitGlobalDispatcher(name string) { - if len(name) == 0 { - name = "direct" - } - if globalEventDispatcher != nil { - log.Warnf("EventDispatcher already init. It will be replaced") - } - if dispatchers[name] == nil { - panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") - } - globalEventDispatcher = dispatchers[name]() - globalEventDispatcher.AddEventListeners(eventListeners) -} - -func GetGlobalDispatcher() observer.EventDispatcher { - return globalEventDispatcher -} diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index ab53ef0b2f..ac918dd709 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -18,14 +18,13 @@ package dispatcher import ( - "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" "reflect" ) func init() { - extension.SetEventDispatcher("direct", NewDirectEventDispatcher) + observer.SetEventDispatcher("direct", NewDirectEventDispatcher) } // DirectEventDispatcher is align with DirectEventDispatcher interface in Java. @@ -34,7 +33,6 @@ func init() { // Dispatcher event to listener direct type DirectEventDispatcher struct { observer.BaseListenable - observer.EventDispatcher } func NewDirectEventDispatcher() observer.EventDispatcher { diff --git a/common/observer/dispatcher/direct_event_dispatcher_test.go b/common/observer/dispatcher/direct_event_dispatcher_test.go new file mode 100644 index 0000000000..d0b0e828c0 --- /dev/null +++ b/common/observer/dispatcher/direct_event_dispatcher_test.go @@ -0,0 +1,71 @@ +/* + * 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 dispatcher + +import ( + "fmt" + "github.com/apache/dubbo-go/common/observer" + "reflect" + "testing" +) + +func TestDirectEventDispatcher_Dispatch(t *testing.T) { + ded := NewDirectEventDispatcher() + ded.AddEventListener(&TestEventListener{}) + ded.AddEventListener(&TestEventListener1{}) + ded.Dispatch(&TestEvent{}) +} + +type TestEvent struct { + observer.BaseEvent +} + +type TestEventListener struct { + observer.BaseListenable + observer.EventListener +} + +func (tel *TestEventListener) OnEvent(e observer.Event) error { + fmt.Println("TestEventListener") + return nil +} + +func (tel *TestEventListener) GetPriority() int { + return -1 +} + +func (tel *TestEventListener) GetEventType() reflect.Type { + return reflect.TypeOf(TestEvent{}) +} + +type TestEventListener1 struct { + observer.EventListener +} + +func (tel *TestEventListener1) OnEvent(e observer.Event) error { + fmt.Println("TestEventListener1") + return nil +} + +func (tel *TestEventListener1) GetPriority() int { + return 1 +} + +func (tel *TestEventListener1) GetEventType() reflect.Type { + return reflect.TypeOf(TestEvent{}) +} diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go index 17745e68c0..bbb9004052 100644 --- a/common/observer/event_dispatcher.go +++ b/common/observer/event_dispatcher.go @@ -17,6 +17,10 @@ package observer +import "github.com/prometheus/common/log" + +var globalEventDispatcher EventDispatcher + // EventDispatcher is align with EventDispatcher interface in Java. // it's the top abstraction // Align with 2.7.5 @@ -25,3 +29,32 @@ type EventDispatcher interface { // Dispatch event Dispatch(event Event) } + +var ( + dispatchers = make(map[string]func() EventDispatcher, 8) +) + +// SetEventDispatcher by name +func SetEventDispatcher(name string, v func() EventDispatcher) { + dispatchers[name] = v +} + +// SetAndInitGlobalDispatcher +func SetAndInitGlobalDispatcher(name string) { + if len(name) == 0 { + name = "direct" + } + if globalEventDispatcher != nil { + log.Warnf("EventDispatcher already init. It will be replaced") + } + if dispatchers[name] == nil { + panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") + } + globalEventDispatcher = dispatchers[name]() + globalEventDispatcher.AddEventListeners(eventListeners) +} + +// GetGlobalDispatcher by name +func GetGlobalDispatcher() EventDispatcher { + return globalEventDispatcher +} diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index 2b71faf2f5..15a74b6157 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -22,6 +22,9 @@ import ( "reflect" ) +// All eventListeners +var eventListeners []EventListener + // EventListener is an new interface used to align with dubbo 2.7.5 // It contains the Prioritized means that the listener has its priority type EventListener interface { @@ -38,3 +41,7 @@ type ConditionalEventListener interface { // Accept will make the decision whether it should handle this event Accept(e Event) bool } + +func AddEventListener(listener EventListener) { + eventListeners = append(eventListeners, listener) +} diff --git a/common/observer/listenable.go b/common/observer/listenable.go index 4ceb03b0ae..6dced504eb 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -37,32 +37,39 @@ type BaseListenable struct { Mutex sync.Mutex } +func NewBaseListenable() Listenable { + return &BaseListenable{} +} + +// AddEventListener ... func (bl *BaseListenable) AddEventListener(listener EventListener) { eventType := listener.GetEventType() var listenersSlice []EventListener bl.Mutex.Lock() defer bl.Mutex.Unlock() - if value, loaded := bl.ListenersCache.Load(eventType); loaded { + if value, loaded := bl.ListenersCache.LoadOrStore(eventType, make([]EventListener, 0, 8)); loaded { listenersSlice = value.([]EventListener) - if !containListener(listenersSlice, listener) { - listenersSlice = append(listenersSlice, listener) + if containListener(listenersSlice, listener) { + return } } else { listenersSlice = make([]EventListener, 0, 8) - listenersSlice = append(listenersSlice, listener) } + listenersSlice = append(listenersSlice, listener) sort.Slice(listenersSlice, func(i, j int) bool { return listenersSlice[i].GetPriority() < listenersSlice[j].GetPriority() }) bl.ListenersCache.Store(eventType, listenersSlice) } +// AddEventListeners .. func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.AddEventListener(listener) } } +// RemoveEventListener ... func (bl *BaseListenable) RemoveEventListener(listener EventListener) { eventType := listener.GetEventType() bl.Mutex.Lock() @@ -72,25 +79,29 @@ func (bl *BaseListenable) RemoveEventListener(listener EventListener) { return } listenersSlice := value.([]EventListener) - for i, listener := range listenersSlice { - if listener == listener { + for i, l := range listenersSlice { + if l == listener { listenersSlice = append(listenersSlice[:i], listenersSlice[i+1:]...) } } + bl.ListenersCache.Store(eventType, listenersSlice) } +// RemoveEventListeners ... func (bl *BaseListenable) RemoveEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.RemoveEventListener(listener) } } +// RemoveAllEventListeners ... func (bl *BaseListenable) RemoveAllEventListeners() { bl.Mutex.Lock() defer bl.Mutex.Unlock() bl.ListenersCache = *new(sync.Map) } +// GetAllEventListeners ... func (bl *BaseListenable) GetAllEventListeners() []EventListener { allListenersSlice := make([]EventListener, 0, 16) bl.ListenersCache.Range(func(_, value interface{}) bool { diff --git a/common/observer/listenable_test.go b/common/observer/listenable_test.go index d1a16176f0..fa006db1b4 100644 --- a/common/observer/listenable_test.go +++ b/common/observer/listenable_test.go @@ -18,14 +18,44 @@ package observer import ( - "github.com/apache/dubbo-go/registry/listener" "github.com/stretchr/testify/assert" + "reflect" "testing" ) func TestListenable(t *testing.T) { - var b EventListener = &listener.ServiceInstancesChangedListener{} - var a EventListener = &listener.ServiceInstancesChangedListener{} + el := &TestEventListener{} + b := &BaseListenable{} + b.AddEventListener(el) + b.AddEventListener(el) + al := b.GetAllEventListeners() + assert.Equal(t, len(al), 1) + assert.Equal(t, al[0].GetEventType(), reflect.TypeOf(TestEvent{})) + b.RemoveEventListener(el) + assert.Equal(t, len(b.GetAllEventListeners()), 0) + var ts []EventListener + ts = append(ts, el) + b.AddEventListeners(ts) + assert.Equal(t, len(al), 1) - assert.True(t, b == a) +} + +type TestEvent struct { + BaseEvent +} + +type TestEventListener struct { + EventListener +} + +func (tel *TestEventListener) OnEvent(e Event) error { + return nil +} + +func (tel *TestEventListener) GetPriority() int { + return -1 +} + +func (tel *TestEventListener) GetEventType() reflect.Type { + return reflect.TypeOf(TestEvent{}) } diff --git a/config/config_loader.go b/config/config_loader.go index 7af073923e..8e2782e4a6 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -19,6 +19,7 @@ package config import ( "fmt" + "github.com/apache/dubbo-go/common/observer" "log" "os" "time" @@ -101,7 +102,7 @@ func Load() { eventDispatcherType = providerConfig.eventDispatcherType } // init EventDispatcher - extension.SetAndInitGlobalDispatcher(eventDispatcherType) + observer.SetAndInitGlobalDispatcher(eventDispatcherType) // reference config if consumerConfig == nil { diff --git a/registry/listener/ServiceInstancesChangedListener.go b/registry/listener/ServiceInstancesChangedListener.go index cd48ceb4f2..225c8febe7 100644 --- a/registry/listener/ServiceInstancesChangedListener.go +++ b/registry/listener/ServiceInstancesChangedListener.go @@ -18,14 +18,13 @@ package listener import ( - "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/common/observer/event" "reflect" ) func init() { - extension.AddEventListener(&ServiceInstancesChangedListener{}) + observer.AddEventListener(&ServiceInstancesChangedListener{}) } // TODO (implement ConditionalEventListener) From 357f536d493d9c6946e3bd1113eb3cfe4119cd48 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 29 Mar 2020 14:20:47 +0800 Subject: [PATCH 006/209] fix import --- common/observer/dispatcher/direct_event_dispatcher.go | 5 ++++- common/observer/event/ServiceInstancesChangedEvent.go | 3 +++ common/observer/event_dispatcher.go | 8 +++++--- common/observer/event_listener.go | 5 ++++- common/observer/listenable_test.go | 5 ++++- registry/listener/ServiceInstancesChangedListener.go | 5 ++++- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index ac918dd709..f255bd6c36 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -17,10 +17,13 @@ package dispatcher +import ( + "reflect" +) + import ( "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" - "reflect" ) func init() { diff --git a/common/observer/event/ServiceInstancesChangedEvent.go b/common/observer/event/ServiceInstancesChangedEvent.go index d85a6d5737..e86c8ddf89 100644 --- a/common/observer/event/ServiceInstancesChangedEvent.go +++ b/common/observer/event/ServiceInstancesChangedEvent.go @@ -19,6 +19,9 @@ package event import ( "fmt" +) + +import ( "github.com/apache/dubbo-go/common/observer" ) diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go index bbb9004052..259e32b32e 100644 --- a/common/observer/event_dispatcher.go +++ b/common/observer/event_dispatcher.go @@ -17,7 +17,9 @@ package observer -import "github.com/prometheus/common/log" +import ( + "github.com/apache/dubbo-go/common/logger" +) var globalEventDispatcher EventDispatcher @@ -45,7 +47,7 @@ func SetAndInitGlobalDispatcher(name string) { name = "direct" } if globalEventDispatcher != nil { - log.Warnf("EventDispatcher already init. It will be replaced") + logger.Warnf("EventDispatcher already init. It will be replaced") } if dispatchers[name] == nil { panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") @@ -54,7 +56,7 @@ func SetAndInitGlobalDispatcher(name string) { globalEventDispatcher.AddEventListeners(eventListeners) } -// GetGlobalDispatcher by name +// GetGlobalDispatcher func GetGlobalDispatcher() EventDispatcher { return globalEventDispatcher } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index 15a74b6157..f92f9d2c7d 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -18,10 +18,13 @@ package observer import ( - gxsort "github.com/dubbogo/gost/sort" "reflect" ) +import ( + gxsort "github.com/dubbogo/gost/sort" +) + // All eventListeners var eventListeners []EventListener diff --git a/common/observer/listenable_test.go b/common/observer/listenable_test.go index fa006db1b4..df46bfc2ba 100644 --- a/common/observer/listenable_test.go +++ b/common/observer/listenable_test.go @@ -18,11 +18,14 @@ package observer import ( - "github.com/stretchr/testify/assert" "reflect" "testing" ) +import ( + "github.com/stretchr/testify/assert" +) + func TestListenable(t *testing.T) { el := &TestEventListener{} b := &BaseListenable{} diff --git a/registry/listener/ServiceInstancesChangedListener.go b/registry/listener/ServiceInstancesChangedListener.go index 225c8febe7..3e3a5283de 100644 --- a/registry/listener/ServiceInstancesChangedListener.go +++ b/registry/listener/ServiceInstancesChangedListener.go @@ -17,10 +17,13 @@ package listener +import ( + "reflect" +) + import ( "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/common/observer/event" - "reflect" ) func init() { From ea24b176deafef2548a41b9229354aca3efda289 Mon Sep 17 00:00:00 2001 From: Patrick Date: Mon, 30 Mar 2020 19:06:52 +0800 Subject: [PATCH 007/209] add default eventDispatch type and handle eventType is ptr --- common/observer/dispatcher/direct_event_dispatcher.go | 4 ++++ common/observer/dispatcher/direct_event_dispatcher_test.go | 3 ++- common/observer/listenable.go | 7 +++++++ config/base_config.go | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index f255bd6c36..412585b795 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -43,6 +43,10 @@ func NewDirectEventDispatcher() observer.EventDispatcher { } func (ded *DirectEventDispatcher) Dispatch(event observer.Event) { + if event == nil { + logger.Warnf("[DirectEventDispatcher] dispatch event nil") + return + } eventType := reflect.TypeOf(event).Elem() value, loaded := ded.ListenersCache.Load(eventType) if !loaded { diff --git a/common/observer/dispatcher/direct_event_dispatcher_test.go b/common/observer/dispatcher/direct_event_dispatcher_test.go index d0b0e828c0..557dd15225 100644 --- a/common/observer/dispatcher/direct_event_dispatcher_test.go +++ b/common/observer/dispatcher/direct_event_dispatcher_test.go @@ -29,6 +29,7 @@ func TestDirectEventDispatcher_Dispatch(t *testing.T) { ded.AddEventListener(&TestEventListener{}) ded.AddEventListener(&TestEventListener1{}) ded.Dispatch(&TestEvent{}) + ded.Dispatch(nil) } type TestEvent struct { @@ -50,7 +51,7 @@ func (tel *TestEventListener) GetPriority() int { } func (tel *TestEventListener) GetEventType() reflect.Type { - return reflect.TypeOf(TestEvent{}) + return reflect.TypeOf(&TestEvent{}) } type TestEventListener1 struct { diff --git a/common/observer/listenable.go b/common/observer/listenable.go index 6dced504eb..6a5d4e35d3 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -18,6 +18,7 @@ package observer import ( + "reflect" "sort" "sync" ) @@ -44,6 +45,9 @@ func NewBaseListenable() Listenable { // AddEventListener ... func (bl *BaseListenable) AddEventListener(listener EventListener) { eventType := listener.GetEventType() + if eventType.Kind() == reflect.Ptr { + eventType = eventType.Elem() + } var listenersSlice []EventListener bl.Mutex.Lock() defer bl.Mutex.Unlock() @@ -72,6 +76,9 @@ func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { // RemoveEventListener ... func (bl *BaseListenable) RemoveEventListener(listener EventListener) { eventType := listener.GetEventType() + if eventType.Kind() == reflect.Ptr { + eventType = eventType.Elem() + } bl.Mutex.Lock() defer bl.Mutex.Unlock() value, loaded := bl.ListenersCache.Load(eventType) diff --git a/config/base_config.go b/config/base_config.go index 74634a5f63..f58138d2e5 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -46,7 +46,7 @@ type BaseConfig struct { configCenterUrl *common.URL prefix string fatherConfig interface{} - eventDispatcherType string `yaml:"direct" json:"direct,omitempty"` + eventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"` MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"` fileStream *bytes.Buffer } From 2925dd32cea78ac1e0899546486adf911bcfdd92 Mon Sep 17 00:00:00 2001 From: Patrick Date: Thu, 2 Apr 2020 23:37:00 +0800 Subject: [PATCH 008/209] modify some comments and optimize code --- common/observer/event_dispatcher.go | 9 ++++++++- common/observer/event_listener.go | 7 ------- common/observer/listenable.go | 31 +++++++++++++++-------------- config/config_loader.go | 4 ++-- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go index 259e32b32e..8b3950480b 100644 --- a/common/observer/event_dispatcher.go +++ b/common/observer/event_dispatcher.go @@ -23,6 +23,8 @@ import ( var globalEventDispatcher EventDispatcher +var allEventListeners []EventListener + // EventDispatcher is align with EventDispatcher interface in Java. // it's the top abstraction // Align with 2.7.5 @@ -53,10 +55,15 @@ func SetAndInitGlobalDispatcher(name string) { panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") } globalEventDispatcher = dispatchers[name]() - globalEventDispatcher.AddEventListeners(eventListeners) + globalEventDispatcher.AddEventListeners(allEventListeners) } // GetGlobalDispatcher func GetGlobalDispatcher() EventDispatcher { return globalEventDispatcher } + +// AddEventListener it will be added in global event dispatcher +func AddEventListener(listener EventListener) { + allEventListeners = append(allEventListeners, listener) +} diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index f92f9d2c7d..85a6fa22b7 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -25,9 +25,6 @@ import ( gxsort "github.com/dubbogo/gost/sort" ) -// All eventListeners -var eventListeners []EventListener - // EventListener is an new interface used to align with dubbo 2.7.5 // It contains the Prioritized means that the listener has its priority type EventListener interface { @@ -44,7 +41,3 @@ type ConditionalEventListener interface { // Accept will make the decision whether it should handle this event Accept(e Event) bool } - -func AddEventListener(listener EventListener) { - eventListeners = append(eventListeners, listener) -} diff --git a/common/observer/listenable.go b/common/observer/listenable.go index 6a5d4e35d3..7b64aa8f2d 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -23,6 +23,7 @@ import ( "sync" ) +// Listenable could add and remove the event listener type Listenable interface { AddEventListener(listener EventListener) AddEventListeners(listenersSlice []EventListener) @@ -32,32 +33,31 @@ type Listenable interface { RemoveAllEventListeners() } +// BaseListenable base listenable type BaseListenable struct { Listenable ListenersCache sync.Map Mutex sync.Mutex } +// NewBaseListenable a constructor of base listenable func NewBaseListenable() Listenable { return &BaseListenable{} } -// AddEventListener ... +// AddEventListener add event listener func (bl *BaseListenable) AddEventListener(listener EventListener) { eventType := listener.GetEventType() if eventType.Kind() == reflect.Ptr { eventType = eventType.Elem() } - var listenersSlice []EventListener bl.Mutex.Lock() defer bl.Mutex.Unlock() - if value, loaded := bl.ListenersCache.LoadOrStore(eventType, make([]EventListener, 0, 8)); loaded { - listenersSlice = value.([]EventListener) - if containListener(listenersSlice, listener) { - return - } - } else { - listenersSlice = make([]EventListener, 0, 8) + value, loaded := bl.ListenersCache.LoadOrStore(eventType, make([]EventListener, 0, 8)) + listenersSlice := value.([]EventListener) + // return if listenersSlice already has this listener + if loaded && containListener(listenersSlice, listener) { + return } listenersSlice = append(listenersSlice, listener) sort.Slice(listenersSlice, func(i, j int) bool { @@ -66,14 +66,14 @@ func (bl *BaseListenable) AddEventListener(listener EventListener) { bl.ListenersCache.Store(eventType, listenersSlice) } -// AddEventListeners .. +// AddEventListeners add the slice of event listener func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.AddEventListener(listener) } } -// RemoveEventListener ... +// RemoveEventListener remove the event listener func (bl *BaseListenable) RemoveEventListener(listener EventListener) { eventType := listener.GetEventType() if eventType.Kind() == reflect.Ptr { @@ -94,21 +94,21 @@ func (bl *BaseListenable) RemoveEventListener(listener EventListener) { bl.ListenersCache.Store(eventType, listenersSlice) } -// RemoveEventListeners ... +// RemoveEventListeners remove the slice of event listener func (bl *BaseListenable) RemoveEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.RemoveEventListener(listener) } } -// RemoveAllEventListeners ... +// RemoveAllEventListeners remove all func (bl *BaseListenable) RemoveAllEventListeners() { bl.Mutex.Lock() defer bl.Mutex.Unlock() - bl.ListenersCache = *new(sync.Map) + bl.ListenersCache = sync.Map{} } -// GetAllEventListeners ... +// GetAllEventListeners get all func (bl *BaseListenable) GetAllEventListeners() []EventListener { allListenersSlice := make([]EventListener, 0, 16) bl.ListenersCache.Range(func(_, value interface{}) bool { @@ -122,6 +122,7 @@ func (bl *BaseListenable) GetAllEventListeners() []EventListener { return allListenersSlice } +// containListener true if contain listener func containListener(listenersSlice []EventListener, listener EventListener) bool { for _, loadListener := range listenersSlice { if loadListener == listener { diff --git a/config/config_loader.go b/config/config_loader.go index 8e2782e4a6..b2ae9d2cc3 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -19,7 +19,6 @@ package config import ( "fmt" - "github.com/apache/dubbo-go/common/observer" "log" "os" "time" @@ -34,6 +33,7 @@ import ( "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/common/observer" _ "github.com/apache/dubbo-go/common/observer/dispatcher" ) @@ -101,7 +101,7 @@ func Load() { if providerConfig != nil { eventDispatcherType = providerConfig.eventDispatcherType } - // init EventDispatcher + // init EventDispatcher should before everything observer.SetAndInitGlobalDispatcher(eventDispatcherType) // reference config From a7828385a8c61ac8bf2919fa08817120015151b4 Mon Sep 17 00:00:00 2001 From: Patrick Date: Thu, 2 Apr 2020 23:42:32 +0800 Subject: [PATCH 009/209] optimize some code and fix imports --- common/observer/dispatcher/direct_event_dispatcher.go | 2 ++ common/observer/dispatcher/direct_event_dispatcher_test.go | 5 ++++- common/observer/event_dispatcher.go | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index 412585b795..b539ef92d5 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -38,10 +38,12 @@ type DirectEventDispatcher struct { observer.BaseListenable } +// NewDirectEventDispatcher ac constructor of DirectEventDispatcher func NewDirectEventDispatcher() observer.EventDispatcher { return &DirectEventDispatcher{} } +// Dispatch event directly func (ded *DirectEventDispatcher) Dispatch(event observer.Event) { if event == nil { logger.Warnf("[DirectEventDispatcher] dispatch event nil") diff --git a/common/observer/dispatcher/direct_event_dispatcher_test.go b/common/observer/dispatcher/direct_event_dispatcher_test.go index 557dd15225..355c930a9e 100644 --- a/common/observer/dispatcher/direct_event_dispatcher_test.go +++ b/common/observer/dispatcher/direct_event_dispatcher_test.go @@ -19,11 +19,14 @@ package dispatcher import ( "fmt" - "github.com/apache/dubbo-go/common/observer" "reflect" "testing" ) +import ( + "github.com/apache/dubbo-go/common/observer" +) + func TestDirectEventDispatcher_Dispatch(t *testing.T) { ded := NewDirectEventDispatcher() ded.AddEventListener(&TestEventListener{}) diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go index 8b3950480b..8513818041 100644 --- a/common/observer/event_dispatcher.go +++ b/common/observer/event_dispatcher.go @@ -51,7 +51,7 @@ func SetAndInitGlobalDispatcher(name string) { if globalEventDispatcher != nil { logger.Warnf("EventDispatcher already init. It will be replaced") } - if dispatchers[name] == nil { + if dp, ok := dispatchers[name]; !ok || dp == nil { panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") } globalEventDispatcher = dispatchers[name]() From 8c42b4c863a18fc78c0ec65f27244efcc5695b86 Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 8 Apr 2020 21:25:19 +0800 Subject: [PATCH 010/209] In memory service discovery support --- registry/inmemory/service_discovery.go | 130 +++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 registry/inmemory/service_discovery.go diff --git a/registry/inmemory/service_discovery.go b/registry/inmemory/service_discovery.go new file mode 100644 index 0000000000..73af948fc6 --- /dev/null +++ b/registry/inmemory/service_discovery.go @@ -0,0 +1,130 @@ +/* + * 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 inmemory + +import ( + "github.com/dubbogo/gost/container/set" + "github.com/dubbogo/gost/page" + + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/registry" +) + +const ( + name = "in-memory" +) + +func init() { + + instance := &InMemoryServiceDiscovery{ + instances: make(map[string]registry.ServiceInstance, 4), + } + + extension.SetServiceDiscovery(name, func(url *common.URL) (discovery registry.ServiceDiscovery, err error) { + return instance, nil + }) +} + +// InMemoryServiceDiscovery is an implementation based on memory. +// Usually you will not use this implementation except for tests. +type InMemoryServiceDiscovery struct { + instances map[string]registry.ServiceInstance +} + +func (i *InMemoryServiceDiscovery) String() string { + return name +} + +// Destroy doesn't destroy the instance, it just clear the instances +func (i *InMemoryServiceDiscovery) Destroy() error { + // reset to empty + i.instances = make(map[string]registry.ServiceInstance, 4) + return nil +} + +// Register will store the instance using its id as key +func (i *InMemoryServiceDiscovery) Register(instance registry.ServiceInstance) error { + i.instances[instance.GetId()] = instance + return nil +} + +// Update will act like register +func (i *InMemoryServiceDiscovery) Update(instance registry.ServiceInstance) error { + return i.Register(instance) +} + +// Unregister will remove the instance +func (i *InMemoryServiceDiscovery) Unregister(instance registry.ServiceInstance) error { + delete(i.instances, instance.GetId()) + return nil +} + +// GetDefaultPageSize will return the default page size +func (i *InMemoryServiceDiscovery) GetDefaultPageSize() int { + return registry.DefaultPageSize +} + +// GetServices will return all service names +func (i *InMemoryServiceDiscovery) GetServices() *gxset.HashSet { + result := gxset.NewSet() + for _, value := range i.instances { + result.Add(value.GetServiceName()) + } + return result +} + +// GetInstances will find out all instances with serviceName +func (i *InMemoryServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { + result := make([]registry.ServiceInstance, 0, len(i.instances)) + for _, value := range i.instances { + if value.GetServiceName() == serviceName { + result = append(result, value) + } + } + return result +} + +// +func (i *InMemoryServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) DispatchEventByServiceName(serviceName string) error { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + panic("implement me") +} + +func (i *InMemoryServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + panic("implement me") +} From c15a725c79c18263d2b51bc6b96a632bc8c8f2e1 Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 8 Apr 2020 22:23:26 +0800 Subject: [PATCH 011/209] Add in-memory service-discovery support --- registry/inmemory/service_discovery.go | 48 ++++++++-- registry/inmemory/service_discovery_test.go | 98 +++++++++++++++++++++ 2 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 registry/inmemory/service_discovery_test.go diff --git a/registry/inmemory/service_discovery.go b/registry/inmemory/service_discovery.go index 73af948fc6..3dac35cd38 100644 --- a/registry/inmemory/service_discovery.go +++ b/registry/inmemory/service_discovery.go @@ -20,7 +20,9 @@ package inmemory import ( "github.com/dubbogo/gost/container/set" "github.com/dubbogo/gost/page" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/registry" @@ -34,6 +36,7 @@ func init() { instance := &InMemoryServiceDiscovery{ instances: make(map[string]registry.ServiceInstance, 4), + listeners: make([]*registry.ServiceInstancesChangedListener, 0, 2), } extension.SetServiceDiscovery(name, func(url *common.URL) (discovery registry.ServiceDiscovery, err error) { @@ -45,6 +48,7 @@ func init() { // Usually you will not use this implementation except for tests. type InMemoryServiceDiscovery struct { instances map[string]registry.ServiceInstance + listeners []*registry.ServiceInstancesChangedListener } func (i *InMemoryServiceDiscovery) String() string { @@ -55,6 +59,7 @@ func (i *InMemoryServiceDiscovery) String() string { func (i *InMemoryServiceDiscovery) Destroy() error { // reset to empty i.instances = make(map[string]registry.ServiceInstance, 4) + i.listeners = make([]*registry.ServiceInstancesChangedListener, 0, 2) return nil } @@ -100,31 +105,58 @@ func (i *InMemoryServiceDiscovery) GetInstances(serviceName string) []registry.S return result } -// +// GetInstancesByPage will return the part of instances func (i *InMemoryServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { - panic("implement me") + instances := i.GetInstances(serviceName) + // we can not use []registry.ServiceInstance since New(...) received []interface{} as parameter + result := make([]interface{}, 0, pageSize) + for i := offset; i < len(instances) && i < offset+pageSize; i++ { + result = append(result, instances[i]) + } + return gxpage.New(offset, pageSize, result, len(instances)) } +// GetHealthyInstancesByPage will return the instances func (i *InMemoryServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { - panic("implement me") + instances := i.GetInstances(serviceName) + // we can not use []registry.ServiceInstance since New(...) received []interface{} as parameter + result := make([]interface{}, 0, pageSize) + count := 0 + for i := offset; i < len(instances) && count < pageSize; i++ { + if instances[i].IsHealthy() == healthy { + result = append(result, instances[i]) + count++ + } + } + return gxpage.New(offset, pageSize, result, len(instances)) } +// GetRequestInstances will iterate the serviceName and aggregate them func (i *InMemoryServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { - panic("implement me") + res := make(map[string]gxpage.Pager, len(serviceNames)) + for _, name := range serviceNames { + res[name] = i.GetInstancesByPage(name, offset, requestedSize) + } + return res } +// AddListener will save the listener inside the memory func (i *InMemoryServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { - panic("implement me") + i.listeners = append(i.listeners, listener) + return nil } +// DispatchEventByServiceName will do nothing func (i *InMemoryServiceDiscovery) DispatchEventByServiceName(serviceName string) error { - panic("implement me") + return nil } +// DispatchEventForInstances will do nothing func (i *InMemoryServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { - panic("implement me") + return nil } +// DispatchEvent will do nothing func (i *InMemoryServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { - panic("implement me") + return nil } diff --git a/registry/inmemory/service_discovery_test.go b/registry/inmemory/service_discovery_test.go new file mode 100644 index 0000000000..a934dbabff --- /dev/null +++ b/registry/inmemory/service_discovery_test.go @@ -0,0 +1,98 @@ +/* + * 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 inmemory + +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/registry" +) + +func TestInMemoryServiceDiscovery(t *testing.T) { + discovery, _ := extension.GetServiceDiscovery(name, nil) + serviceName := "my-service" + err := discovery.Register(®istry.DefaultServiceInstance{ + ServiceName: serviceName, + Id: "1", + Healthy: true, + }) + assert.Nil(t, err) + + err = discovery.Register(®istry.DefaultServiceInstance{ + Id: "2", + ServiceName: "mock-service", + Healthy: false, + }) + + assert.Nil(t, err) + + services := discovery.GetServices() + assert.Equal(t, 2, services.Size()) + assert.Equal(t, registry.DefaultPageSize, discovery.GetDefaultPageSize()) + + reqInstances := discovery.GetRequestInstances([]string{serviceName, "mock-service"}, 0, 10) + assert.Equal(t, 2, len(reqInstances)) + + page := discovery.GetInstancesByPage(serviceName, 0, 10) + assert.Equal(t, 1, page.GetDataSize()) + + discovery.GetHealthyInstancesByPage(serviceName, 0, 10, true) + page = discovery.GetInstancesByPage(serviceName, 0, 10) + assert.Equal(t, 1, page.GetDataSize()) + + err = discovery.AddListener(®istry.ServiceInstancesChangedListener{}) + assert.Nil(t, err) + + err = discovery.DispatchEvent(®istry.ServiceInstancesChangedEvent{}) + assert.Nil(t, err) + + err = discovery.DispatchEventForInstances(serviceName, nil) + assert.Nil(t, err) + + err = discovery.DispatchEventByServiceName(serviceName) + assert.Nil(t, err) + + err = discovery.Unregister(®istry.DefaultServiceInstance{ + Id: "2", + }) + assert.Nil(t, err) + + services = discovery.GetServices() + assert.Equal(t, 1, services.Size()) + + err = discovery.Update(®istry.DefaultServiceInstance{ + Id: "3", + }) + assert.Nil(t, err) + + services = discovery.GetServices() + assert.Equal(t, 2, services.Size()) + + err = discovery.Destroy() + assert.Nil(t, err) + + services = discovery.GetServices() + assert.Equal(t, 0, services.Size()) +} From 0b0fde8942bca09b4796212419e0fca22c3b9747 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 14:09:48 +0800 Subject: [PATCH 012/209] Add: add exporter --- common/rpc_service.go | 5 + config/config_loader.go | 1 + config/config_loader_test.go | 2 +- config/service_config.go | 99 ++++++++++++++++- config/service_config_test.go | 50 --------- metadata/definition/definition.go | 24 ++++- metadata/report/report.go | 1 + metadata/service/inmemory/in_memory_test.go | 37 ------- .../inmemory/{in_memory.go => service.go} | 97 +++++++++++------ metadata/service/inmemory/service_test.go | 95 +++++++++++++++++ metadata/service/service.go | 42 ++++---- .../service_exporter/configurable/exporter.go | 100 ++++++++++++++++++ .../configurable/exporter_test.go | 57 ++++++++++ .../exporter.go | 8 +- 14 files changed, 466 insertions(+), 152 deletions(-) delete mode 100644 metadata/service/inmemory/in_memory_test.go rename metadata/service/inmemory/{in_memory.go => service.go} (59%) create mode 100644 metadata/service/inmemory/service_test.go create mode 100644 metadata/service_exporter/configurable/exporter.go create mode 100644 metadata/service_exporter/configurable/exporter_test.go rename metadata/{exporter => service_exporter}/exporter.go (89%) diff --git a/common/rpc_service.go b/common/rpc_service.go index b235c32abc..cb4bc9d96b 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -132,6 +132,11 @@ func (s *Service) Method() map[string]*MethodType { return s.methods } +// Method ... +func (s *Service) Name() string { + return s.name +} + // RcvrType ... func (s *Service) RcvrType() reflect.Type { return s.rcvrType diff --git a/config/config_loader.go b/config/config_loader.go index c0687d8fc1..814c85b0a2 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -198,6 +198,7 @@ func Load() { } svs.id = key svs.Implement(rpcService) + svs.Protocols = providerConfig.Protocols if err := svs.Export(); err != nil { panic(fmt.Sprintf("service %s export failed! ", key)) } diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 498f826780..3105dc2c09 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -89,7 +89,7 @@ func TestLoad(t *testing.T) { func TestLoadWithSingleReg(t *testing.T) { doInitConsumerWithSingleRegistry() - doInitProviderWithSingleRegistry() + MockInitProviderWithSingleRegistry() ms := &MockService{} SetConsumerService(ms) diff --git a/config/service_config.go b/config/service_config.go index 5853146aa8..d5d087f425 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -71,11 +71,13 @@ type ServiceConfig struct { ParamSign string `yaml:"param.sign" json:"param.sign,omitempty" property:"param.sign"` Tag string `yaml:"tag" json:"tag,omitempty" property:"tag"` + Protocols map[string]*ProtocolConfig unexported *atomic.Bool exported *atomic.Bool rpcService common.RPCService cacheProtocol protocol.Protocol cacheMutex sync.Mutex + exporters []protocol.Exporter } // Prefix ... @@ -92,6 +94,8 @@ func (c *ServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal((*plain)(c)); err != nil { return err } + c.exported = atomic.NewBool(false) + c.unexported = atomic.NewBool(false) return nil } @@ -105,6 +109,11 @@ func NewServiceConfig(id string, context context.Context) *ServiceConfig { } } +// IsExport will return whether the service config is exported or not +func (c *ServiceConfig) IsExport() bool { + return c.exported.Load() +} + // Export ... func (c *ServiceConfig) Export() error { // TODO: config center start here @@ -122,7 +131,7 @@ func (c *ServiceConfig) Export() error { regUrls := loadRegistries(c.Registry, providerConfig.Registries, common.PROVIDER) urlMap := c.getUrlMap() - protocolConfigs := loadProtocol(c.Protocol, providerConfig.Protocols) + protocolConfigs := loadProtocol(c.Protocol, c.Protocols) if len(protocolConfigs) == 0 { logger.Warnf("The service %v's '%v' protocols don't has right protocolConfigs ", c.InterfaceName, c.Protocol) return nil @@ -148,6 +157,9 @@ func (c *ServiceConfig) Export() error { if len(c.Tag) > 0 { ivkURL.AddParam(constant.Tagkey, c.Tag) } + + var exporter protocol.Exporter + if len(regUrls) > 0 { for _, regUrl := range regUrls { regUrl.SubURL = ivkURL @@ -160,22 +172,39 @@ func (c *ServiceConfig) Export() error { c.cacheMutex.Unlock() invoker := extension.GetProxyFactory(providerConfig.ProxyFactory).GetInvoker(*regUrl) - exporter := c.cacheProtocol.Export(invoker) + exporter = c.cacheProtocol.Export(invoker) if exporter == nil { panic(perrors.New(fmt.Sprintf("Registry protocol new exporter error,registry is {%v},url is {%v}", regUrl, ivkURL))) } } } else { invoker := extension.GetProxyFactory(providerConfig.ProxyFactory).GetInvoker(*ivkURL) - exporter := extension.GetProtocol(protocolwrapper.FILTER).Export(invoker) + exporter = extension.GetProtocol(protocolwrapper.FILTER).Export(invoker) if exporter == nil { panic(perrors.New(fmt.Sprintf("Filter protocol without registry new exporter error,url is {%v}", ivkURL))) } } + c.exporters = append(c.exporters, exporter) } + c.exported.Store(true) return nil } +// Unexport will call unexport of all exporters service config exported +func (c *ServiceConfig) Unexport() { + if !c.exported.Load() { + return + } + if c.unexported.Load() { + return + } + for _, exporter := range c.exporters { + exporter.Unexport() + } + c.exporters = nil + c.unexported.Store(true) +} + // Implement ... func (c *ServiceConfig) Implement(s common.RPCService) { c.rpcService = s @@ -246,3 +275,67 @@ func (c *ServiceConfig) getUrlMap() url.Values { return urlMap } + +// GetExportedUrls will return the url in service config's exporter +func (c *ServiceConfig) GetExportedUrls() []*common.URL { + if c.exported.Load() { + var urls []*common.URL + for _, exporter := range c.exporters { + url := exporter.GetInvoker().GetUrl() + urls = append(urls, &url) + } + return urls + } + return nil +} + +// MockInitProviderWithSingleRegistry will init a mocked providerConfig +func MockInitProviderWithSingleRegistry() { + providerConfig = &ProviderConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registry: &RegistryConfig{ + Address: "mock://127.0.0.1:2181", + Username: "user1", + Password: "pwd1", + }, + Registries: map[string]*RegistryConfig{}, + Services: map[string]*ServiceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: "3", + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + Name: "GetUser", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + { + Name: "GetUser1", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + }, + }, + }, + Protocols: map[string]*ProtocolConfig{ + "mock": { + Name: "mock", + Ip: "127.0.0.1", + Port: "20000", + }, + }, + } +} diff --git a/config/service_config_test.go b/config/service_config_test.go index 6f32308903..2b53dc385b 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -128,56 +128,6 @@ func doInitProvider() { } } -func doInitProviderWithSingleRegistry() { - providerConfig = &ProviderConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, - Registry: &RegistryConfig{ - Address: "mock://127.0.0.1:2181", - Username: "user1", - Password: "pwd1", - }, - Registries: map[string]*RegistryConfig{}, - Services: map[string]*ServiceConfig{ - "MockService": { - InterfaceName: "com.MockService", - Protocol: "mock", - Cluster: "failover", - Loadbalance: "random", - Retries: "3", - Group: "huadong_idc", - Version: "1.0.0", - Methods: []*MethodConfig{ - { - Name: "GetUser", - Retries: "2", - Loadbalance: "random", - Weight: 200, - }, - { - Name: "GetUser1", - Retries: "2", - Loadbalance: "random", - Weight: 200, - }, - }, - }, - }, - Protocols: map[string]*ProtocolConfig{ - "mock": { - Name: "mock", - Ip: "127.0.0.1", - Port: "20000", - }, - }, - } -} - func Test_Export(t *testing.T) { doInitProvider() extension.SetProtocol("registry", GetProtocol) diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 5a983dd6d2..4676af3e75 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -19,8 +19,10 @@ package definition import ( "bytes" + "github.com/apache/dubbo-go/common" ) +// ServiceDefinition is the describer of service definition type ServiceDefinition struct { CanonicalName string CodeSource string @@ -28,6 +30,7 @@ type ServiceDefinition struct { Types []TypeDefinition } +// MethodDefinition is the describer of method definition type MethodDefinition struct { Name string ParameterTypes []string @@ -35,6 +38,7 @@ type MethodDefinition struct { Parameters []TypeDefinition } +// TypeDefinition is the describer of type definition type TypeDefinition struct { Id string Type string @@ -44,9 +48,23 @@ type TypeDefinition struct { TypeBuilderName string } -// name... -func ServiceDefinitionBuild() *ServiceDefinition { - sd := &ServiceDefinition{} +// BuildServiceDefinition can build service definition which will be used to describe a service +func BuildServiceDefinition(service common.Service, url common.URL) ServiceDefinition { + sd := ServiceDefinition{} + sd.CanonicalName = url.Service() + + for k, m := range service.Method() { + var paramTypes []string + for _, t := range m.ArgsType() { + paramTypes = append(paramTypes, t.Kind().String()) + } + methodD := MethodDefinition{ + Name: k, + ParameterTypes: paramTypes, + ReturnType: m.ReplyType().Kind().String(), + } + sd.Methods = append(sd.Methods, methodD) + } return sd } diff --git a/metadata/report/report.go b/metadata/report/report.go index d3436101a3..6b2efb2408 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -23,6 +23,7 @@ import ( "github.com/apache/dubbo-go/metadata/identifier" ) +// MetadataReport is an interface of remote metadata report type MetadataReport interface { StoreProviderMetadata(*identifier.MetadataIdentifier, *definition.ServiceDefinition) StoreConsumeretadata(*identifier.MetadataIdentifier, map[string]string) diff --git a/metadata/service/inmemory/in_memory_test.go b/metadata/service/inmemory/in_memory_test.go deleted file mode 100644 index 57d7664f5b..0000000000 --- a/metadata/service/inmemory/in_memory_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package inmemory - -import ( - "fmt" - "github.com/apache/dubbo-go/common" - "github.com/bmizerany/assert" - "testing" -) - -func TestMetadataService(t *testing.T) { - mts := NewMetadataService() - serviceName := "com.ikurento.user.UserProvider" - group := "group1" - version := "0.0.1" - protocol := "dubbo" - u, _ := common.NewURL(fmt.Sprintf("%v://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+ - "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ - "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&"+ - "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ - "side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v", protocol, serviceName, group, version)) - mts.ExportURL(u) - sets := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, 1, sets.Size()) - mts.SubscribeURL(u) - - mts.SubscribeURL(u) - sets2 := mts.GetSubscribedURLs() - assert.Equal(t, 1, sets2.Size()) - - mts.UnexportURL(u) - sets11 := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, 0, sets11.Size()) - - mts.UnsubscribeURL(u) - sets22 := mts.GetSubscribedURLs() - assert.Equal(t, 0, sets22.Size()) -} diff --git a/metadata/service/inmemory/in_memory.go b/metadata/service/inmemory/service.go similarity index 59% rename from metadata/service/inmemory/in_memory.go rename to metadata/service/inmemory/service.go index f61fe3de0d..d31e8d862d 100644 --- a/metadata/service/inmemory/in_memory.go +++ b/metadata/service/inmemory/service.go @@ -17,11 +17,11 @@ package inmemory import ( + "encoding/json" "sync" ) import ( - "github.com/apache/dubbo-go/common/logger" "github.com/emirpasic/gods/sets" "github.com/emirpasic/gods/sets/treeset" "github.com/emirpasic/gods/utils" @@ -30,15 +30,17 @@ import ( import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/metadata/definition" "github.com/apache/dubbo-go/metadata/service" ) -// InMemoryMetadataService is store and query the metadata info in memory when each service registry +// MetadataService is store and query the metadata info in memory when each service registry type MetadataService struct { service.BaseMetadataService exportedServiceURLs *sync.Map subscribedServiceURLs *sync.Map + serviceDefinitions *sync.Map lock *sync.RWMutex } @@ -47,11 +49,12 @@ func NewMetadataService() *MetadataService { return &MetadataService{ exportedServiceURLs: new(sync.Map), subscribedServiceURLs: new(sync.Map), + serviceDefinitions: new(sync.Map), lock: new(sync.RWMutex), } } -// urlComparator: defined as utils.Comparator for treeset to compare the URL +// urlComparator is defined as utils.Comparator for treeset to compare the URL func urlComparator(a, b interface{}) int { url1 := a.(*common.URL) url2 := b.(*common.URL) @@ -65,7 +68,7 @@ func urlComparator(a, b interface{}) int { } } -// addURL: add URL in memory +// addURL will add URL in memory func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { var ( urlSet interface{} @@ -91,7 +94,7 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { return true } -// removeURL: used to remove specified url +// removeURL is used to remove specified url func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { if value, loaded := targetMap.Load(url.ServiceKey()); loaded { mts.lock.Lock() @@ -105,7 +108,7 @@ func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { } } -// getAllService: return all the exportedUrlString except for metadataService +// getAllService can return all the exportedUrlString except for metadataService func (mts *MetadataService) getAllService(services *sync.Map) sets.Set { sets := treeset.NewWith(utils.StringComparator) services.Range(func(key, value interface{}) bool { @@ -121,7 +124,7 @@ func (mts *MetadataService) getAllService(services *sync.Map) sets.Set { return sets } -// getSpecifiedService: return specified service url by serviceKey +// getSpecifiedService can return specified service url by serviceKey func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) sets.Set { targetSets := treeset.NewWith(utils.StringComparator) serviceSet, loaded := services.Load(serviceKey) @@ -136,63 +139,89 @@ func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey s return targetSets } -// ExportURL: store the in memory treeset -func (mts *MetadataService) ExportURL(url common.URL) bool { - return mts.addURL(mts.exportedServiceURLs, &url) +// ExportURL can store the in memory treeset +func (mts *MetadataService) ExportURL(url common.URL) (bool, error) { + return mts.addURL(mts.exportedServiceURLs, &url), nil } -// UnexportURL: remove the url store in memory treeset -func (mts *MetadataService) UnexportURL(url common.URL) { +// UnexportURL can remove the url store in memory treeset +func (mts *MetadataService) UnexportURL(url common.URL) error { mts.removeURL(mts.exportedServiceURLs, &url) + return nil } -// SubscribeURL... -func (mts *MetadataService) SubscribeURL(url common.URL) bool { - return mts.addURL(mts.subscribedServiceURLs, &url) +// SubscribeURL can store the in memory treeset +func (mts *MetadataService) SubscribeURL(url common.URL) (bool, error) { + return mts.addURL(mts.subscribedServiceURLs, &url), nil } -// UnsubscribeURL... -func (mts *MetadataService) UnsubscribeURL(url common.URL) { +// UnsubscribeURL can remove the url store in memory treeset +func (mts *MetadataService) UnsubscribeURL(url common.URL) error { mts.removeURL(mts.subscribedServiceURLs, &url) + return nil } // PublishServiceDefinition: publish url's service metadata info, and write into memory -func (MetadataService) PublishServiceDefinition(url common.URL) { +func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { //judge is consumer or provider - role := url.GetParam(constant.SIDE_KEY, "") + //side := url.GetParam(constant.SIDE_KEY, "") //var service common.RPCService - if role == common.RoleType(common.CONSUMER).Role() { - - //TODO:BOSS FANG - } else if role == common.RoleType(common.PROVIDER).Role() { - //TODO:BOSS FANG + service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + //if side == common.RoleType(common.CONSUMER).Role() { + // //TODO:generate the service definition and store it + // + //} else if side == common.RoleType(common.PROVIDER).Role() { + // //TODO:generate the service definition and store it + //} + sd := definition.BuildServiceDefinition(*service, url) + data, err := json.Marshal(sd) + if err != nil { + logger.Errorf("publishProvider getServiceDescriptor error. providerUrl:%v , error: ", url, err) } - + mts.serviceDefinitions.Store(url.ServiceKey(), string(data)) + return nil } + logger.Errorf("publishProvider interfaceName is empty . providerUrl:%v ", url) + return nil } // GetExportedURLs get all exported urls -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) sets.Set { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (sets.Set, error) { if serviceInterface == constant.ANY_VALUE { - return mts.getAllService(mts.exportedServiceURLs) + return mts.getAllService(mts.exportedServiceURLs), nil } else { serviceKey := definition.ServiceDescriperBuild(serviceInterface, group, version) - return mts.getSpecifiedService(mts.exportedServiceURLs, serviceKey, protocol) + return mts.getSpecifiedService(mts.exportedServiceURLs, serviceKey, protocol), nil } } // GetSubscribedURLs get all subscribedUrl -func (mts *MetadataService) GetSubscribedURLs() sets.Set { - return mts.getAllService(mts.subscribedServiceURLs) +func (mts *MetadataService) GetSubscribedURLs() (sets.Set, error) { + return mts.getAllService(mts.subscribedServiceURLs), nil +} + +// GetServiceDefinition can get service definition by interfaceName, group and version +func (mts *MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + serviceKey := definition.ServiceDescriperBuild(interfaceName, group, version) + v, _ := mts.serviceDefinitions.Load(serviceKey) + return v.(string), nil +} + +// GetServiceDefinition can get service definition by serviceKey +func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + v, _ := mts.serviceDefinitions.Load(serviceKey) + return v.(string), nil } -func (MetadataService) GetServiceDefinition(interfaceName string, group string, version string) string { - panic("implement me") +// Version will return the version of metadata service +func (mts *MetadataService) Version() string { + return "1.0.0" } -func (MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) string { - panic("implement me") +// Version will return the version of metadata service +func (mts *MetadataService) Reference() string { + return "MetadataService" } diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go new file mode 100644 index 0000000000..93e31b523f --- /dev/null +++ b/metadata/service/inmemory/service_test.go @@ -0,0 +1,95 @@ +/* + * 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 inmemory + +import ( + "context" + "fmt" + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/metadata/definition" +) + +type User struct { + Id string + Name string + Age int32 + Time time.Time +} + +type UserProvider struct { +} + +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { + rsp := User{"A001", "Alex Stocks", 18, time.Now()} + return &rsp, nil +} + +func (u *UserProvider) Reference() string { + return "UserProvider" +} + +func (u User) JavaClassName() string { + return "com.ikurento.user.User" +} + +func TestMetadataService(t *testing.T) { + mts := NewMetadataService() + serviceName := "com.ikurento.user.UserProvider" + group := "group1" + version := "0.0.1" + protocol := "dubbo" + beanName := "UserProvider" + u, _ := common.NewURL(fmt.Sprintf("%v://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&"+ + "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ + "side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", protocol, serviceName, group, version, beanName)) + mts.ExportURL(u) + sets := mts.GetExportedURLs(serviceName, group, version, protocol) + assert.Equal(t, 1, sets.Size()) + mts.SubscribeURL(u) + + mts.SubscribeURL(u) + sets2 := mts.GetSubscribedURLs() + assert.Equal(t, 1, sets2.Size()) + + mts.UnexportURL(u) + sets11 := mts.GetExportedURLs(serviceName, group, version, protocol) + assert.Equal(t, 0, sets11.Size()) + + mts.UnsubscribeURL(u) + sets22 := mts.GetSubscribedURLs() + assert.Equal(t, 0, sets22.Size()) + + userProvider := &UserProvider{} + common.ServiceMap.Register(protocol, userProvider) + mts.PublishServiceDefinition(u) + expected := `{"CanonicalName":"com.ikurento.user.UserProvider","CodeSource":"","Methods":[{"Name":"GetUser","ParameterTypes":["slice"],"ReturnType":"ptr","Parameters":null}],"Types":null}` + assert.Equal(t, mts.GetServiceDefinition(serviceName, group, version), expected) + serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) + assert.Equal(t, mts.GetServiceDefinitionByServiceKey(serviceKey), expected) +} diff --git a/metadata/service/service.go b/metadata/service/service.go index 4682def41e..e3c6f21c58 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -28,30 +28,32 @@ import ( // Metadataservice is used to define meta data related behaviors type MetadataService interface { - ServiceName() string - ExportURL(url common.URL) bool - UnexportURL(url common.URL) - RefreshMetadata(exportedRevision string, subscribedRevision string) bool - SubscribeURL(url common.URL) bool - UnsubscribeURL(url common.URL) - PublishServiceDefinition(url common.URL) - - GetExportedURLs(serviceInterface string, group string, version string, protocol string) sets.Set - GetSubscribedURLs() sets.Set - GetServiceDefinition(interfaceName string, group string, version string) string - GetServiceDefinitionByServiceKey(serviceKey string) string + ServiceName() (string, error) + ExportURL(url common.URL) (bool, error) + UnexportURL(url common.URL) error + //RefreshMetadata(exportedRevision string, subscribedRevision string) bool + SubscribeURL(url common.URL) (bool, error) + UnsubscribeURL(url common.URL) error + PublishServiceDefinition(url common.URL) error + + GetExportedURLs(serviceInterface string, group string, version string, protocol string) (sets.Set, error) + GetSubscribedURLs() (sets.Set, error) + GetServiceDefinition(interfaceName string, group string, version string) (string, error) + GetServiceDefinitionByServiceKey(serviceKey string) (string, error) + Version() string + common.RPCService } -// BaseMetadataService: is used for the common logic for struct who will implement interface MetadataService +// BaseMetadataService is used for the common logic for struct who will implement interface MetadataService type BaseMetadataService struct { } -// ServiceName: get the service's name in meta service , which is application name -func (mts *BaseMetadataService) ServiceName() string { - return config.GetApplicationConfig().Name +// ServiceName can get the service's name in meta service , which is application name +func (mts *BaseMetadataService) ServiceName() (string, error) { + return config.GetApplicationConfig().Name, nil } -// RefreshMetadata: used for event listener's calling, to refresh metadata -func (mts *BaseMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { - return true -} +// RefreshMetadata is used for event listener's calling, to refresh metadata +//func (mts *BaseMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { +// return true +//} diff --git a/metadata/service_exporter/configurable/exporter.go b/metadata/service_exporter/configurable/exporter.go new file mode 100644 index 0000000000..8033e16420 --- /dev/null +++ b/metadata/service_exporter/configurable/exporter.go @@ -0,0 +1,100 @@ +/* + * 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 configurable + +import ( + "context" + "sync" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/metadata/service_exporter" +) + +// MetadataServiceExporter is the ConfigurableMetadataServiceExporter which implement MetadataServiceExporter interface +type MetadataServiceExporter struct { + serviceConfig *config.ServiceConfig + lock sync.RWMutex + metadataService service.MetadataService +} + +// NewMetadataServiceExporter will return a service_exporter.MetadataServiceExporter with the specified metadata service +func NewMetadataServiceExporter(metadataService service.MetadataService) service_exporter.MetadataServiceExporter { + return &MetadataServiceExporter{ + metadataService: metadataService, + } +} + +// Export will export the metadataService +func (exporter *MetadataServiceExporter) Export() error { + if !exporter.IsExported() { + exporter.lock.Lock() + defer exporter.lock.Unlock() + exporter.serviceConfig = config.NewServiceConfig("MetadataService", context.Background()) + exporter.serviceConfig.Protocol = constant.DEFAULT_PROTOCOL + exporter.serviceConfig.Protocols = map[string]*config.ProtocolConfig{ + constant.DEFAULT_PROTOCOL: generateMetadataProtocol(), + } + exporter.serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME + exporter.serviceConfig.Group = config.GetApplicationConfig().Name + exporter.serviceConfig.Version = exporter.metadataService.Version() + exporter.serviceConfig.Implement(exporter.metadataService) + err := exporter.serviceConfig.Export() + logger.Infof("The MetadataService exports urls : %v ", exporter.serviceConfig.GetExportedUrls()) + return err + } else { + logger.Warnf("The MetadataService has been exported : %v ", exporter.serviceConfig.GetExportedUrls()) + return nil + } + +} + +// Unexport will unexport the metadataService +func (exporter *MetadataServiceExporter) Unexport() { + if exporter.IsExported() { + exporter.lock.Lock() + defer exporter.lock.Unlock() + exporter.serviceConfig.Unexport() + } +} + +// GetExportedURLs will return the urls that export use. +// Notice!The exported url is not same as url in registry , for example it lack the ip. +func (exporter *MetadataServiceExporter) GetExportedURLs() []*common.URL { + return exporter.serviceConfig.GetExportedUrls() +} + +// isExported will return is metadataServiceExporter exported or not +func (exporter *MetadataServiceExporter) IsExported() bool { + exporter.lock.RLock() + defer exporter.lock.RUnlock() + return exporter.serviceConfig != nil && exporter.serviceConfig.IsExport() +} + +// generateMetadataProtocol will return a default ProtocolConfig +func generateMetadataProtocol() *config.ProtocolConfig { + return &config.ProtocolConfig{ + Name: constant.DEFAULT_PROTOCOL, + Port: "20000", + } +} diff --git a/metadata/service_exporter/configurable/exporter_test.go b/metadata/service_exporter/configurable/exporter_test.go new file mode 100644 index 0000000000..4056a00874 --- /dev/null +++ b/metadata/service_exporter/configurable/exporter_test.go @@ -0,0 +1,57 @@ +/* + * 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 configurable + +import ( + "fmt" + _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + "github.com/apache/dubbo-go/config" + _ "github.com/apache/dubbo-go/filter/filter_impl" + "github.com/apache/dubbo-go/metadata/service/inmemory" + "github.com/apache/dubbo-go/protocol/dubbo" + _ "github.com/apache/dubbo-go/protocol/dubbo" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConfigurableExporter(t *testing.T) { + dubbo.SetServerConfig(dubbo.ServerConfig{ + SessionNumber: 700, + SessionTimeout: "20s", + GettySessionParam: dubbo.GettySessionParam{ + CompressEncoding: false, + TcpNoDelay: true, + TcpKeepAlive: true, + KeepAlivePeriod: "120s", + TcpRBufSize: 262144, + TcpWBufSize: 65536, + PkgWQSize: 512, + TcpReadTimeout: "1s", + TcpWriteTimeout: "5s", + WaitTimeout: "1s", + MaxMsgLen: 10240000000, + SessionName: "server", + }}) + config.MockInitProviderWithSingleRegistry() + metadataService := inmemory.NewMetadataService() + exported := NewMetadataServiceExporter(metadataService) + assert.Equal(t, false, exported.IsExported()) + assert.NoError(t, exported.Export()) + assert.Equal(t, true, exported.IsExported()) + fmt.Println(exported.GetExportedURLs()) +} diff --git a/metadata/exporter/exporter.go b/metadata/service_exporter/exporter.go similarity index 89% rename from metadata/exporter/exporter.go rename to metadata/service_exporter/exporter.go index a6290c1ea9..2ccf17f4dd 100644 --- a/metadata/exporter/exporter.go +++ b/metadata/service_exporter/exporter.go @@ -15,15 +15,15 @@ * limitations under the License. */ -package exporter +package service_exporter import ( "github.com/apache/dubbo-go/common" ) -type MetadataExporter interface { - Export() MetadataExporter - Unexport() MetadataExporter +type MetadataServiceExporter interface { + Export() error + Unexport() GetExportedURLs() []*common.URL IsExported() bool } From 6a9591a90090368f04052bf103d2cf21ba1bb3cb Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 18:39:20 +0800 Subject: [PATCH 013/209] Add:identifier ut --- config/base_config_test.go | 8 ++-- config/service_config.go | 1 + config_center/zookeeper/impl_test.go | 2 +- metadata/definition/definition.go | 3 ++ .../identifier/base_metadata_identifier.go | 44 +++++++++--------- .../base_metadata_identifier_test.go | 41 +++++++++++++++++ metadata/identifier/metadata_identifier.go | 11 ++--- .../identifier/metadata_identifier_test.go | 44 ++++++++++++++++++ .../identifier/service_metadata_identifier.go | 13 +++--- .../service_metadata_identifier_test.go | 45 +++++++++++++++++++ .../subscribe_metadata_identifier.go | 28 +++++++++--- .../subscribe_metadata_identifier_test.go | 44 ++++++++++++++++++ .../configurable/exporter_test.go | 5 ++- 13 files changed, 245 insertions(+), 44 deletions(-) create mode 100644 metadata/identifier/base_metadata_identifier_test.go create mode 100644 metadata/identifier/metadata_identifier_test.go create mode 100644 metadata/identifier/service_metadata_identifier_test.go create mode 100644 metadata/identifier/subscribe_metadata_identifier_test.go diff --git a/config/base_config_test.go b/config/base_config_test.go index d16b242092..e06b68a9dc 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -57,7 +57,7 @@ func Test_refresh(t *testing.T) { // id: "shanghai_reg1", // Protocol: "mock", // TimeoutStr: "2s", - // Group: "shanghai_idc", + // group: "shanghai_idc", // Address: "127.0.0.1:2181", // Username: "user1", // Password: "pwd1", @@ -160,7 +160,7 @@ func Test_appExternal_refresh(t *testing.T) { // id: "shanghai_reg1", // Protocol: "mock", // TimeoutStr: "2s", - // Group: "shanghai_idc", + // group: "shanghai_idc", // Address: "127.0.0.1:2181", // Username: "user1", // Password: "pwd1", @@ -255,7 +255,7 @@ func Test_appExternalWithoutId_refresh(t *testing.T) { // id: "shanghai_reg1", // Protocol: "mock", // TimeoutStr: "2s", - // Group: "shanghai_idc", + // group: "shanghai_idc", // Address: "127.0.0.1:2181", // Username: "user1", // Password: "pwd1", @@ -412,7 +412,7 @@ func Test_refreshProvider(t *testing.T) { // id: "shanghai_reg1", // Protocol: "mock", // TimeoutStr: "2s", - // Group: "shanghai_idc", + // group: "shanghai_idc", // Address: "127.0.0.1:2181", // Username: "user1", // Password: "pwd1", diff --git a/config/service_config.go b/config/service_config.go index 048bedc632..de263d8c51 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -202,6 +202,7 @@ func (c *ServiceConfig) Unexport() { exporter.Unexport() } c.exporters = nil + c.exported.Store(false) c.unexported.Store(true) } diff --git a/config_center/zookeeper/impl_test.go b/config_center/zookeeper/impl_test.go index 30389122a3..b8c2cf49d1 100644 --- a/config_center/zookeeper/impl_test.go +++ b/config_center/zookeeper/impl_test.go @@ -159,7 +159,7 @@ func Test_RemoveListener(t *testing.T) { func TestZookeeperDynamicConfiguration_PublishConfig(t *testing.T) { value := "Test Data" - customGroup := "Custom Group" + customGroup := "Custom group" key := "myKey" ts, zk := initZkData(config_center.DEFAULT_GROUP, t) defer ts.Stop() diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 4676af3e75..81b9e58c82 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -19,6 +19,9 @@ package definition import ( "bytes" +) + +import ( "github.com/apache/dubbo-go/common" ) diff --git a/metadata/identifier/base_metadata_identifier.go b/metadata/identifier/base_metadata_identifier.go index 44238668e7..0cd8b075ff 100644 --- a/metadata/identifier/base_metadata_identifier.go +++ b/metadata/identifier/base_metadata_identifier.go @@ -25,19 +25,21 @@ import ( "github.com/apache/dubbo-go/common/constant" ) -type BaseMetadataIdentifier interface { - getFilePathKey(params ...string) string - getIdentifierKey(params ...string) string +// BaseMetadataIdentifier defined for describe the Metadata base identify +type IMetadataIdentifier interface { + GetFilePathKey() string + GetIdentifierKey() string } -type BaseServiceMetadataIdentifier struct { - serviceInterface string - version string - group string - side string +// BaseMetadataIdentifier is the base implement of BaseMetadataIdentifier interface +type BaseMetadataIdentifier struct { + ServiceInterface string + Version string + Group string + Side string } -// joinParams... +// joinParams will join the specified char in slice, and build as string func joinParams(joinChar string, params []string) string { var joinedStr string for _, param := range params { @@ -47,24 +49,24 @@ func joinParams(joinChar string, params []string) string { 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 + +// getIdentifierKey will return string format as service:Version:Group:Side:param1:param2... +func (mdi *BaseMetadataIdentifier) 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) } -// getFilePathKey... -func (mdi *BaseServiceMetadataIdentifier) getFilePathKey(params ...string) string { - path := serviceToPath(mdi.serviceInterface) +// getFilePathKey will return string format as metadata/path/Version/Group/Side/param1/param2... +func (mdi *BaseMetadataIdentifier) getFilePathKey(params ...string) string { + path := serviceToPath(mdi.ServiceInterface) return constant.DEFAULT_PATH_TAG + withPathSeparator(path) + - withPathSeparator(mdi.version) + - withPathSeparator(mdi.group) + - withPathSeparator(mdi.side) + + withPathSeparator(mdi.Version) + + withPathSeparator(mdi.Group) + + withPathSeparator(mdi.Side) + joinParams("/", params) } diff --git a/metadata/identifier/base_metadata_identifier_test.go b/metadata/identifier/base_metadata_identifier_test.go new file mode 100644 index 0000000000..5b60992ab6 --- /dev/null +++ b/metadata/identifier/base_metadata_identifier_test.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 identifier + +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +var baseId = &BaseMetadataIdentifier{ + ServiceInterface: "org.apache.pkg.mockService", + Version: "1.0.0", + Group: "Group", + Side: "provider", +} + +func TestBaseGetFilePathKey(t *testing.T) { + assert.Equal(t, "metadata/1.0.0/Group/provider/a/b/c", baseId.getFilePathKey("a", "b", "c")) +} + +func TestBaseGetIdentifierKey(t *testing.T) { + assert.Equal(t, "org.apache.pkg.mockService:1.0.0:Group:provider:a:b:c", baseId.getIdentifierKey("a", "b", "c")) +} diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go index f3df8f3654..b39d60eef8 100644 --- a/metadata/identifier/metadata_identifier.go +++ b/metadata/identifier/metadata_identifier.go @@ -17,17 +17,18 @@ package identifier +// MetadataIdentifier is inherit baseMetaIdentifier with Application name type MetadataIdentifier struct { - application string + Application string BaseMetadataIdentifier } // getIdentifierKey... -func (mdi *MetadataIdentifier) getIdentifierKey(params ...string) string { - return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.application) +func (mdi *MetadataIdentifier) GetIdentifierKey() string { + return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Application) } // getIdentifierKey... -func (mdi *MetadataIdentifier) getFilePathKey(params ...string) string { - return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.application) +func (mdi *MetadataIdentifier) GetFilePathKey() string { + return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Application) } diff --git a/metadata/identifier/metadata_identifier_test.go b/metadata/identifier/metadata_identifier_test.go new file mode 100644 index 0000000000..cba3c0dd76 --- /dev/null +++ b/metadata/identifier/metadata_identifier_test.go @@ -0,0 +1,44 @@ +/* + * 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 ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +var metadataId = &MetadataIdentifier{ + Application: "app", + BaseMetadataIdentifier: BaseMetadataIdentifier{ + ServiceInterface: "org.apache.pkg.mockService", + Version: "1.0.0", + Group: "Group", + Side: "provider", + }, +} + +func TestGetFilePathKey(t *testing.T) { + assert.Equal(t, "metadata/1.0.0/Group/provider/app", metadataId.GetFilePathKey()) +} + +func TestGetIdentifierKey(t *testing.T) { + assert.Equal(t, "org.apache.pkg.mockService:1.0.0:Group:provider:app", metadataId.GetIdentifierKey()) +} diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index 373df0130d..07fdfb4220 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -21,18 +21,19 @@ import ( "github.com/apache/dubbo-go/common/constant" ) +// ServiceMetadataIdentifier is inherit baseMetaIdentifier with service params: Revision and Protocol type ServiceMetadataIdentifier struct { - revision string - protocol string + 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) +func (mdi *ServiceMetadataIdentifier) GetIdentifierKey() 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) +func (mdi *ServiceMetadataIdentifier) GetFilePathKey() string { + return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Protocol, constant.KEY_REVISON_PREFIX+mdi.Revision) } diff --git a/metadata/identifier/service_metadata_identifier_test.go b/metadata/identifier/service_metadata_identifier_test.go new file mode 100644 index 0000000000..d7ef44a4bb --- /dev/null +++ b/metadata/identifier/service_metadata_identifier_test.go @@ -0,0 +1,45 @@ +/* + * 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 ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +var serviceMetadataId = &ServiceMetadataIdentifier{ + Revision: "1.0", + Protocol: "dubbo", + BaseMetadataIdentifier: BaseMetadataIdentifier{ + ServiceInterface: "org.apache.pkg.mockService", + Version: "1.0.0", + Group: "Group", + Side: "provider", + }, +} + +func TestServiceGetFilePathKey(t *testing.T) { + assert.Equal(t, "metadata/1.0.0/Group/provider/dubbo/revision1.0", serviceMetadataId.GetFilePathKey()) +} + +func TestServiceGetIdentifierKey(t *testing.T) { + assert.Equal(t, "org.apache.pkg.mockService:1.0.0:Group:provider:dubbo:revision1.0", serviceMetadataId.GetIdentifierKey()) +} diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index fd3a290b41..84f036038a 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -1,16 +1,34 @@ +/* + * 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 +// SubscriberMetadataIdentifier is inherit baseMetaIdentifier with service params: Revision type SubscriberMetadataIdentifier struct { - revision string + Revision string BaseMetadataIdentifier } // getIdentifierKey... -func (mdi *SubscriberMetadataIdentifier) getIdentifierKey(params ...string) string { - return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.revision) +func (mdi *SubscriberMetadataIdentifier) GetIdentifierKey() string { + return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Revision) } // getIdentifierKey... -func (mdi *SubscriberMetadataIdentifier) getFilePathKey(params ...string) string { - return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.revision) +func (mdi *SubscriberMetadataIdentifier) GetFilePathKey() string { + return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Revision) } diff --git a/metadata/identifier/subscribe_metadata_identifier_test.go b/metadata/identifier/subscribe_metadata_identifier_test.go new file mode 100644 index 0000000000..9c9ef70641 --- /dev/null +++ b/metadata/identifier/subscribe_metadata_identifier_test.go @@ -0,0 +1,44 @@ +/* + * 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 ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +var subscribeMetadataId = &SubscriberMetadataIdentifier{ + Revision: "1.0", + BaseMetadataIdentifier: BaseMetadataIdentifier{ + ServiceInterface: "org.apache.pkg.mockService", + Version: "1.0.0", + Group: "Group", + Side: "provider", + }, +} + +func TestSubscribeGetFilePathKey(t *testing.T) { + assert.Equal(t, "metadata/1.0.0/Group/provider/1.0", subscribeMetadataId.GetFilePathKey()) +} + +func TestSubscribeGetIdentifierKey(t *testing.T) { + assert.Equal(t, "org.apache.pkg.mockService:1.0.0:Group:provider:1.0", subscribeMetadataId.GetIdentifierKey()) +} diff --git a/metadata/service_exporter/configurable/exporter_test.go b/metadata/service_exporter/configurable/exporter_test.go index 4056a00874..532ba5d259 100644 --- a/metadata/service_exporter/configurable/exporter_test.go +++ b/metadata/service_exporter/configurable/exporter_test.go @@ -18,7 +18,6 @@ package configurable import ( - "fmt" _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" "github.com/apache/dubbo-go/config" _ "github.com/apache/dubbo-go/filter/filter_impl" @@ -53,5 +52,7 @@ func TestConfigurableExporter(t *testing.T) { assert.Equal(t, false, exported.IsExported()) assert.NoError(t, exported.Export()) assert.Equal(t, true, exported.IsExported()) - fmt.Println(exported.GetExportedURLs()) + assert.Regexp(t, "dubbo://:20000/MetadataService*", exported.GetExportedURLs()[0].String()) + exported.Unexport() + assert.Equal(t, false, exported.IsExported()) } From b3dddc88442753dbb9416cd2638ce100df1d420b Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 18:41:45 +0800 Subject: [PATCH 014/209] Mod: move service name mapping --- metadata/namemapping/dynamic/service_name_mapping.go | 4 ++-- metadata/{ => namemapping}/service_name_mapping.go | 2 +- .../service_exporter/configurable/exporter_test.go | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) rename metadata/{ => namemapping}/service_name_mapping.go (98%) diff --git a/metadata/namemapping/dynamic/service_name_mapping.go b/metadata/namemapping/dynamic/service_name_mapping.go index e93c256fe0..b50a73c820 100644 --- a/metadata/namemapping/dynamic/service_name_mapping.go +++ b/metadata/namemapping/dynamic/service_name_mapping.go @@ -18,6 +18,7 @@ package dynamic import ( + "github.com/apache/dubbo-go/metadata/namemapping" "strconv" "time" ) @@ -31,7 +32,6 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/config_center" - "github.com/apache/dubbo-go/metadata" ) const ( @@ -77,6 +77,6 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str } // NewServiceNameMapping will create an instance of DynamicConfigurationServiceNameMapping -func NewServiceNameMapping(dc config_center.DynamicConfiguration) metadata.ServiceNameMapping { +func NewServiceNameMapping(dc config_center.DynamicConfiguration) namemapping.ServiceNameMapping { return &DynamicConfigurationServiceNameMapping{dc: dc} } diff --git a/metadata/service_name_mapping.go b/metadata/namemapping/service_name_mapping.go similarity index 98% rename from metadata/service_name_mapping.go rename to metadata/namemapping/service_name_mapping.go index c14e8ce2e7..451a60d2cf 100644 --- a/metadata/service_name_mapping.go +++ b/metadata/namemapping/service_name_mapping.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package metadata +package namemapping import ( gxset "github.com/dubbogo/gost/container/set" diff --git a/metadata/service_exporter/configurable/exporter_test.go b/metadata/service_exporter/configurable/exporter_test.go index 532ba5d259..0975f07213 100644 --- a/metadata/service_exporter/configurable/exporter_test.go +++ b/metadata/service_exporter/configurable/exporter_test.go @@ -17,6 +17,14 @@ package configurable +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + import ( _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" "github.com/apache/dubbo-go/config" @@ -24,8 +32,6 @@ import ( "github.com/apache/dubbo-go/metadata/service/inmemory" "github.com/apache/dubbo-go/protocol/dubbo" _ "github.com/apache/dubbo-go/protocol/dubbo" - "github.com/stretchr/testify/assert" - "testing" ) func TestConfigurableExporter(t *testing.T) { From 863dd0fb2dd3c7ee633281148346769224175ee7 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 19:04:45 +0800 Subject: [PATCH 015/209] Mod:make ut run --- config/service_config.go | 1 + config/service_config_test.go | 3 +++ metadata/service/inmemory/service_test.go | 16 +++++++++------- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/config/service_config.go b/config/service_config.go index de263d8c51..53e6526da4 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -328,6 +328,7 @@ func MockInitProviderWithSingleRegistry() { Weight: 200, }, }, + exported: new(atomic.Bool), }, }, Protocols: map[string]*ProtocolConfig{ diff --git a/config/service_config_test.go b/config/service_config_test.go index 2b53dc385b..26c558db1b 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -18,6 +18,7 @@ package config import ( + "go.uber.org/atomic" "testing" ) @@ -92,6 +93,7 @@ func doInitProvider() { Weight: 200, }, }, + exported: new(atomic.Bool), }, "MockServiceNoRightProtocol": { InterfaceName: "com.MockService", @@ -116,6 +118,7 @@ func doInitProvider() { Weight: 200, }, }, + exported: new(atomic.Bool), }, }, Protocols: map[string]*ProtocolConfig{ diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go index 93e31b523f..d68990b3fd 100644 --- a/metadata/service/inmemory/service_test.go +++ b/metadata/service/inmemory/service_test.go @@ -69,27 +69,29 @@ func TestMetadataService(t *testing.T) { "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ "side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", protocol, serviceName, group, version, beanName)) mts.ExportURL(u) - sets := mts.GetExportedURLs(serviceName, group, version, protocol) + sets, _ := mts.GetExportedURLs(serviceName, group, version, protocol) assert.Equal(t, 1, sets.Size()) mts.SubscribeURL(u) mts.SubscribeURL(u) - sets2 := mts.GetSubscribedURLs() + sets2, _ := mts.GetSubscribedURLs() assert.Equal(t, 1, sets2.Size()) mts.UnexportURL(u) - sets11 := mts.GetExportedURLs(serviceName, group, version, protocol) + sets11, _ := mts.GetExportedURLs(serviceName, group, version, protocol) assert.Equal(t, 0, sets11.Size()) mts.UnsubscribeURL(u) - sets22 := mts.GetSubscribedURLs() + sets22, _ := mts.GetSubscribedURLs() assert.Equal(t, 0, sets22.Size()) userProvider := &UserProvider{} - common.ServiceMap.Register(protocol, userProvider) + common.ServiceMap.Register(serviceName, protocol, userProvider) mts.PublishServiceDefinition(u) expected := `{"CanonicalName":"com.ikurento.user.UserProvider","CodeSource":"","Methods":[{"Name":"GetUser","ParameterTypes":["slice"],"ReturnType":"ptr","Parameters":null}],"Types":null}` - assert.Equal(t, mts.GetServiceDefinition(serviceName, group, version), expected) + def1, _ := mts.GetServiceDefinition(serviceName, group, version) + assert.Equal(t, def1, expected) serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) - assert.Equal(t, mts.GetServiceDefinitionByServiceKey(serviceKey), expected) + def2, _ := mts.GetServiceDefinitionByServiceKey(serviceKey) + assert.Equal(t, def2, expected) } From 74d6dd95a6dbe8d85f3ed243210d33fe2a1029c1 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 19:42:33 +0800 Subject: [PATCH 016/209] Mod:format --- common/rpc_service.go | 2 +- config/base_config_test.go | 36 ------------------- config/instance/metedata_report.go | 2 +- config/service_config_test.go | 5 ++- config_center/zookeeper/impl_test.go | 2 +- .../dynamic/service_name_mapping.go | 2 +- 6 files changed, 8 insertions(+), 41 deletions(-) diff --git a/common/rpc_service.go b/common/rpc_service.go index 3bb3dfe322..3a25d32239 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -133,7 +133,7 @@ func (s *Service) Method() map[string]*MethodType { return s.methods } -// Method ... +// Name will return service name func (s *Service) Name() string { return s.name } diff --git a/config/base_config_test.go b/config/base_config_test.go index e06b68a9dc..60eccfb183 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -53,15 +53,6 @@ func Test_refresh(t *testing.T) { Owner: "dubbo", Environment: "test"}, Registries: map[string]*RegistryConfig{ - //"shanghai_reg1": { - // id: "shanghai_reg1", - // Protocol: "mock", - // TimeoutStr: "2s", - // group: "shanghai_idc", - // Address: "127.0.0.1:2181", - // Username: "user1", - // Password: "pwd1", - //}, "shanghai_reg2": { Protocol: "mock", TimeoutStr: "2s", @@ -156,15 +147,6 @@ func Test_appExternal_refresh(t *testing.T) { Owner: "dubbo", Environment: "test"}, Registries: map[string]*RegistryConfig{ - //"shanghai_reg1": { - // id: "shanghai_reg1", - // Protocol: "mock", - // TimeoutStr: "2s", - // group: "shanghai_idc", - // Address: "127.0.0.1:2181", - // Username: "user1", - // Password: "pwd1", - //}, "shanghai_reg2": { Protocol: "mock", TimeoutStr: "2s", @@ -251,15 +233,6 @@ func Test_appExternalWithoutId_refresh(t *testing.T) { Owner: "dubbo", Environment: "test"}, Registries: map[string]*RegistryConfig{ - //"shanghai_reg1": { - // id: "shanghai_reg1", - // Protocol: "mock", - // TimeoutStr: "2s", - // group: "shanghai_idc", - // Address: "127.0.0.1:2181", - // Username: "user1", - // Password: "pwd1", - //}, "shanghai_reg2": { Protocol: "mock", TimeoutStr: "2s", @@ -408,15 +381,6 @@ func Test_refreshProvider(t *testing.T) { Owner: "dubbo", Environment: "test"}, Registries: map[string]*RegistryConfig{ - //"shanghai_reg1": { - // id: "shanghai_reg1", - // Protocol: "mock", - // TimeoutStr: "2s", - // group: "shanghai_idc", - // Address: "127.0.0.1:2181", - // Username: "user1", - // Password: "pwd1", - //}, "shanghai_reg2": { Protocol: "mock", TimeoutStr: "2s", diff --git a/config/instance/metedata_report.go b/config/instance/metedata_report.go index 6adc7e8a68..9cf435bc9d 100644 --- a/config/instance/metedata_report.go +++ b/config/instance/metedata_report.go @@ -18,13 +18,13 @@ package instance import ( - "github.com/apache/dubbo-go/metadata/report" "sync" ) import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/metadata/report" ) var ( diff --git a/config/service_config_test.go b/config/service_config_test.go index 26c558db1b..fb3b4a7dc2 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -18,10 +18,13 @@ package config import ( - "go.uber.org/atomic" "testing" ) +import ( + "go.uber.org/atomic" +) + import ( "github.com/apache/dubbo-go/common/extension" ) diff --git a/config_center/zookeeper/impl_test.go b/config_center/zookeeper/impl_test.go index b8c2cf49d1..30389122a3 100644 --- a/config_center/zookeeper/impl_test.go +++ b/config_center/zookeeper/impl_test.go @@ -159,7 +159,7 @@ func Test_RemoveListener(t *testing.T) { func TestZookeeperDynamicConfiguration_PublishConfig(t *testing.T) { value := "Test Data" - customGroup := "Custom group" + customGroup := "Custom Group" key := "myKey" ts, zk := initZkData(config_center.DEFAULT_GROUP, t) defer ts.Stop() diff --git a/metadata/namemapping/dynamic/service_name_mapping.go b/metadata/namemapping/dynamic/service_name_mapping.go index b50a73c820..85e94a89c7 100644 --- a/metadata/namemapping/dynamic/service_name_mapping.go +++ b/metadata/namemapping/dynamic/service_name_mapping.go @@ -18,7 +18,6 @@ package dynamic import ( - "github.com/apache/dubbo-go/metadata/namemapping" "strconv" "time" ) @@ -32,6 +31,7 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/config_center" + "github.com/apache/dubbo-go/metadata/namemapping" ) const ( From dc405a7874544c4306d57417436ef45165e6b07b Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Thu, 9 Apr 2020 19:50:10 +0800 Subject: [PATCH 017/209] Add:liscense --- config/metadata_report_config_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/config/metadata_report_config_test.go b/config/metadata_report_config_test.go index d6b08d5fb0..635feecc2d 100644 --- a/config/metadata_report_config_test.go +++ b/config/metadata_report_config_test.go @@ -1,3 +1,20 @@ +/* + * 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 config import "testing" From 2622827133ffa776a624e9b4c062d1211696f4e5 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 10 Apr 2020 17:58:44 +0800 Subject: [PATCH 018/209] move global dispatcher to extension package --- common/extension/event_dispatcher.go | 61 +++++++++++++++++++ .../dispatcher/direct_event_dispatcher.go | 3 +- common/observer/event_dispatcher.go | 42 ------------- config/config_loader.go | 3 +- .../ServiceInstancesChangedListener.go | 4 -- 5 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 common/extension/event_dispatcher.go diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go new file mode 100644 index 0000000000..3f7fcee17c --- /dev/null +++ b/common/extension/event_dispatcher.go @@ -0,0 +1,61 @@ +/* + * 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/common/logger" + "github.com/apache/dubbo-go/common/observer" +) + +var globalEventDispatcher observer.EventDispatcher + +var initEventListeners []observer.EventListener + +var ( + dispatchers = make(map[string]func() observer.EventDispatcher, 8) +) + +// SetEventDispatcher by name +func SetEventDispatcher(name string, v func() observer.EventDispatcher) { + dispatchers[name] = v +} + +// SetAndInitGlobalDispatcher +func SetAndInitGlobalDispatcher(name string) { + if len(name) == 0 { + name = "direct" + } + if globalEventDispatcher != nil { + logger.Warnf("EventDispatcher already init. It will be replaced") + } + if dp, ok := dispatchers[name]; !ok || dp == nil { + panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") + } + globalEventDispatcher = dispatchers[name]() + globalEventDispatcher.AddEventListeners(initEventListeners) +} + +// GetGlobalDispatcher +func GetGlobalDispatcher() observer.EventDispatcher { + return globalEventDispatcher +} + +// AddEventListener it will be added in global event dispatcher +func AddEventListener(listener observer.EventListener) { + initEventListeners = append(initEventListeners, listener) +} diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index b539ef92d5..2b7567b47e 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -22,12 +22,13 @@ import ( ) import ( + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" ) func init() { - observer.SetEventDispatcher("direct", NewDirectEventDispatcher) + extension.SetEventDispatcher("direct", NewDirectEventDispatcher) } // DirectEventDispatcher is align with DirectEventDispatcher interface in Java. diff --git a/common/observer/event_dispatcher.go b/common/observer/event_dispatcher.go index 8513818041..17745e68c0 100644 --- a/common/observer/event_dispatcher.go +++ b/common/observer/event_dispatcher.go @@ -17,14 +17,6 @@ package observer -import ( - "github.com/apache/dubbo-go/common/logger" -) - -var globalEventDispatcher EventDispatcher - -var allEventListeners []EventListener - // EventDispatcher is align with EventDispatcher interface in Java. // it's the top abstraction // Align with 2.7.5 @@ -33,37 +25,3 @@ type EventDispatcher interface { // Dispatch event Dispatch(event Event) } - -var ( - dispatchers = make(map[string]func() EventDispatcher, 8) -) - -// SetEventDispatcher by name -func SetEventDispatcher(name string, v func() EventDispatcher) { - dispatchers[name] = v -} - -// SetAndInitGlobalDispatcher -func SetAndInitGlobalDispatcher(name string) { - if len(name) == 0 { - name = "direct" - } - if globalEventDispatcher != nil { - logger.Warnf("EventDispatcher already init. It will be replaced") - } - if dp, ok := dispatchers[name]; !ok || dp == nil { - panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") - } - globalEventDispatcher = dispatchers[name]() - globalEventDispatcher.AddEventListeners(allEventListeners) -} - -// GetGlobalDispatcher -func GetGlobalDispatcher() EventDispatcher { - return globalEventDispatcher -} - -// AddEventListener it will be added in global event dispatcher -func AddEventListener(listener EventListener) { - allEventListeners = append(allEventListeners, listener) -} diff --git a/config/config_loader.go b/config/config_loader.go index b2ae9d2cc3..50b6043ed6 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -33,7 +33,6 @@ import ( "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/common/observer" _ "github.com/apache/dubbo-go/common/observer/dispatcher" ) @@ -102,7 +101,7 @@ func Load() { eventDispatcherType = providerConfig.eventDispatcherType } // init EventDispatcher should before everything - observer.SetAndInitGlobalDispatcher(eventDispatcherType) + extension.SetAndInitGlobalDispatcher(eventDispatcherType) // reference config if consumerConfig == nil { diff --git a/registry/listener/ServiceInstancesChangedListener.go b/registry/listener/ServiceInstancesChangedListener.go index 3e3a5283de..0ad66a4b10 100644 --- a/registry/listener/ServiceInstancesChangedListener.go +++ b/registry/listener/ServiceInstancesChangedListener.go @@ -26,10 +26,6 @@ import ( "github.com/apache/dubbo-go/common/observer/event" ) -func init() { - observer.AddEventListener(&ServiceInstancesChangedListener{}) -} - // TODO (implement ConditionalEventListener) type ServiceInstancesChangedListener struct { observer.EventListener From ef06c7229d0b62e993976154c9065ee36d77eb59 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Fri, 10 Apr 2020 19:01:18 +0800 Subject: [PATCH 019/209] Mod:dir rename --- common/extension/metadata_report_factory.go | 8 ++++---- .../{report_factory => report/factory}/report_factory.go | 2 +- .../exporter}/configurable/exporter.go | 3 +-- .../exporter}/configurable/exporter_test.go | 3 ++- .../{service_exporter => service/exporter}/exporter.go | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) rename metadata/{report_factory => report/factory}/report_factory.go (97%) rename metadata/{service_exporter => service/exporter}/configurable/exporter.go (97%) rename metadata/{service_exporter => service/exporter}/configurable/exporter_test.go (94%) rename metadata/{service_exporter => service/exporter}/exporter.go (97%) diff --git a/common/extension/metadata_report_factory.go b/common/extension/metadata_report_factory.go index 7a113c4606..89dab04099 100644 --- a/common/extension/metadata_report_factory.go +++ b/common/extension/metadata_report_factory.go @@ -18,20 +18,20 @@ package extension import ( - "github.com/apache/dubbo-go/metadata/report_factory" + "github.com/apache/dubbo-go/metadata/report/factory" ) var ( - metaDataReportFactories = make(map[string]func() report_factory.MetadataReportFactory, 8) + metaDataReportFactories = make(map[string]func() factory.MetadataReportFactory, 8) ) // SetMetadataReportFactory ... -func SetMetadataReportFactory(name string, v func() report_factory.MetadataReportFactory) { +func SetMetadataReportFactory(name string, v func() factory.MetadataReportFactory) { metaDataReportFactories[name] = v } // GetMetadataReportFactory ... -func GetMetadataReportFactory(name string) report_factory.MetadataReportFactory { +func GetMetadataReportFactory(name string) factory.MetadataReportFactory { if metaDataReportFactories[name] == nil { panic("metadata report for " + name + " is not existing, make sure you have import the package.") } diff --git a/metadata/report_factory/report_factory.go b/metadata/report/factory/report_factory.go similarity index 97% rename from metadata/report_factory/report_factory.go rename to metadata/report/factory/report_factory.go index b74334d6a9..2774fcc31a 100644 --- a/metadata/report_factory/report_factory.go +++ b/metadata/report/factory/report_factory.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package report_factory +package factory import ( "github.com/apache/dubbo-go/common" diff --git a/metadata/service_exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go similarity index 97% rename from metadata/service_exporter/configurable/exporter.go rename to metadata/service/exporter/configurable/exporter.go index 8033e16420..a8d73c2a2c 100644 --- a/metadata/service_exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -28,7 +28,6 @@ import ( "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/metadata/service" - "github.com/apache/dubbo-go/metadata/service_exporter" ) // MetadataServiceExporter is the ConfigurableMetadataServiceExporter which implement MetadataServiceExporter interface @@ -39,7 +38,7 @@ type MetadataServiceExporter struct { } // NewMetadataServiceExporter will return a service_exporter.MetadataServiceExporter with the specified metadata service -func NewMetadataServiceExporter(metadataService service.MetadataService) service_exporter.MetadataServiceExporter { +func NewMetadataServiceExporter(metadataService service.MetadataService) service.MetadataServiceExporter { return &MetadataServiceExporter{ metadataService: metadataService, } diff --git a/metadata/service_exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go similarity index 94% rename from metadata/service_exporter/configurable/exporter_test.go rename to metadata/service/exporter/configurable/exporter_test.go index 0975f07213..e67bf07a39 100644 --- a/metadata/service_exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -18,6 +18,7 @@ package configurable import ( + "github.com/apache/dubbo-go/metadata/service" "testing" ) @@ -54,7 +55,7 @@ func TestConfigurableExporter(t *testing.T) { }}) config.MockInitProviderWithSingleRegistry() metadataService := inmemory.NewMetadataService() - exported := NewMetadataServiceExporter(metadataService) + exported := service.NewMetadataServiceExporter(metadataService) assert.Equal(t, false, exported.IsExported()) assert.NoError(t, exported.Export()) assert.Equal(t, true, exported.IsExported()) diff --git a/metadata/service_exporter/exporter.go b/metadata/service/exporter/exporter.go similarity index 97% rename from metadata/service_exporter/exporter.go rename to metadata/service/exporter/exporter.go index 2ccf17f4dd..3c71820579 100644 --- a/metadata/service_exporter/exporter.go +++ b/metadata/service/exporter/exporter.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package service_exporter +package exporter import ( "github.com/apache/dubbo-go/common" From b30bea64add5a48814975e95f6cd382918305e91 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 11 Apr 2020 11:41:04 +0800 Subject: [PATCH 020/209] Merge remote-tracking branch 'upstream/feature/dubbo-2.7.5' into align-2.7.5 # Conflicts: # common/observer/event_listener.go # registry/event.go # registry/service_discovery.go --- common/constant/key.go | 1 + common/observer/event.go | 18 ++++++------- registry/event.go | 49 +++++++++++++---------------------- registry/event_listener.go | 26 +++++++++++++++++++ registry/service_discovery.go | 10 ++----- 5 files changed, 56 insertions(+), 48 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index 1479af2305..16986c7421 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -40,6 +40,7 @@ const ( TOKEN_KEY = "token" LOCAL_ADDR = "local-addr" REMOTE_ADDR = "remote-addr" + PATH_SEPARATOR = "/" DUBBO_KEY = "dubbo" RELEASE_KEY = "release" ANYHOST_KEY = "anyhost" diff --git a/common/observer/event.go b/common/observer/event.go index d63d7836bb..8c3362feee 100644 --- a/common/observer/event.go +++ b/common/observer/event.go @@ -36,31 +36,31 @@ type Event interface { GetTimestamp() time.Time } -// baseEvent is the base implementation of Event +// BaseEvent is the base implementation of Event // You should never use it directly type BaseEvent struct { - source interface{} - timestamp time.Time + Source interface{} + Timestamp time.Time } // GetSource return the source func (b *BaseEvent) GetSource() interface{} { - return b.source + return b.Source } -// GetTimestamp return the timestamp when the event is created +// GetTimestamp return the Timestamp when the event is created func (b *BaseEvent) GetTimestamp() time.Time { - return b.timestamp + return b.Timestamp } // String return a human readable string representing this event func (b *BaseEvent) String() string { - return fmt.Sprintf("baseEvent[source = %#v]", b.source) + return fmt.Sprintf("BaseEvent[source = %#v]", b.Source) } func newBaseEvent(source interface{}) *BaseEvent { return &BaseEvent{ - source: source, - timestamp: time.Now(), + Source: source, + Timestamp: time.Now(), } } diff --git a/registry/event.go b/registry/event.go index 3a7d60695c..94ada0cc8b 100644 --- a/registry/event.go +++ b/registry/event.go @@ -19,6 +19,7 @@ package registry import ( "fmt" + "github.com/apache/dubbo-go/common/observer" "math/rand" "time" ) @@ -47,40 +48,26 @@ func (e ServiceEvent) String() string { return fmt.Sprintf("ServiceEvent{Action{%s}, Path{%s}}", e.Action, e.Service) } -// Event is align with Event interface in Java. -// it's the top abstraction -// Align with 2.7.5 -type Event interface { - fmt.Stringer - GetSource() interface{} - GetTimestamp() time.Time +// ServiceInstancesChangedEvent represents service instances make some changing +type ServiceInstancesChangedEvent struct { + observer.BaseEvent + ServiceName string + Instances []ServiceInstance } -// baseEvent is the base implementation of Event -// You should never use it directly -type baseEvent struct { - source interface{} - timestamp time.Time +// String return the description of the event +func (s *ServiceInstancesChangedEvent) String() string { + return fmt.Sprintf("ServiceInstancesChangedEvent[source=%s]", s.ServiceName) } -// GetSource return the source -func (b *baseEvent) GetSource() interface{} { - return b.source -} - -// GetTimestamp return the timestamp when the event is created -func (b *baseEvent) GetTimestamp() time.Time { - return b.timestamp -} - -// String return a human readable string representing this event -func (b *baseEvent) String() string { - return fmt.Sprintf("baseEvent[source = %#v]", b.source) -} - -func newBaseEvent(source interface{}) *baseEvent { - return &baseEvent{ - source: source, - timestamp: time.Now(), +// NewServiceInstancesChangedEvent will create the ServiceInstanceChangedEvent instance +func NewServiceInstancesChangedEvent(serviceName string, instances []ServiceInstance) *ServiceInstancesChangedEvent { + return &ServiceInstancesChangedEvent{ + BaseEvent: observer.BaseEvent{ + Source: serviceName, + Timestamp: time.Now(), + }, + ServiceName: serviceName, + Instances: instances, } } diff --git a/registry/event_listener.go b/registry/event_listener.go index e112325cab..0aaa081a44 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -16,3 +16,29 @@ */ package registry + +import ( + "reflect" +) + +import ( + "github.com/apache/dubbo-go/common/observer" +) + +// TODO (implement ConditionalEventListener) +type ServiceInstancesChangedListener struct { + ServiceName string + observer.EventListener +} + +func (sicl *ServiceInstancesChangedListener) OnEvent(e observer.Event) error { + return nil +} + +func (sicl *ServiceInstancesChangedListener) GetPriority() int { + return -1 +} + +func (sicl *ServiceInstancesChangedListener) GetEventType() reflect.Type { + return reflect.TypeOf(&ServiceInstancesChangedEvent{}) +} diff --git a/registry/service_discovery.go b/registry/service_discovery.go index b7731d6b09..a8228a4abe 100644 --- a/registry/service_discovery.go +++ b/registry/service_discovery.go @@ -26,12 +26,6 @@ import ( gxpage "github.com/dubbogo/gost/page" ) -import ( - "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/common/observer/event" - eventlistener "github.com/apache/dubbo-go/registry/listener" -) - const DefaultPageSize = 100 type ServiceDiscovery interface { @@ -79,7 +73,7 @@ type ServiceDiscovery interface { // ----------------- event ---------------------- // AddListener adds a new ServiceInstancesChangedListener // see addServiceInstancesChangedListener in Java - AddListener(listener *eventlistener.ServiceInstancesChangedListener) error + AddListener(listener *ServiceInstancesChangedListener) error // DispatchEventByServiceName dispatches the ServiceInstancesChangedEvent to service instance whose name is serviceName DispatchEventByServiceName(serviceName string) error @@ -88,5 +82,5 @@ type ServiceDiscovery interface { DispatchEventForInstances(serviceName string, instances []ServiceInstance) error // DispatchEvent dispatches the event - DispatchEvent(event *event.ServiceInstancesChangedEvent) error + DispatchEvent(event *ServiceInstancesChangedEvent) error } From eca56280d97d2021891c66577bda8b5030dac5b7 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 11 Apr 2020 12:56:42 +0800 Subject: [PATCH 021/209] fix imports --- registry/event.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/event.go b/registry/event.go index 94ada0cc8b..6f647185cc 100644 --- a/registry/event.go +++ b/registry/event.go @@ -19,13 +19,13 @@ package registry import ( "fmt" - "github.com/apache/dubbo-go/common/observer" "math/rand" "time" ) import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/remoting" ) From a8871fda60aafa8021abdb16121d80870e09f44a Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 11 Apr 2020 15:22:34 +0800 Subject: [PATCH 022/209] modify and add licenses --- common/extension/event_dispatcher.go | 7 ++++--- config/metadata_report_config_test.go | 17 +++++++++++++++++ .../identifier/subscribe_metadata_identifier.go | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go index 3f7fcee17c..2d33528259 100644 --- a/common/extension/event_dispatcher.go +++ b/common/extension/event_dispatcher.go @@ -22,9 +22,10 @@ import ( "github.com/apache/dubbo-go/common/observer" ) -var globalEventDispatcher observer.EventDispatcher - -var initEventListeners []observer.EventListener +var ( + globalEventDispatcher observer.EventDispatcher + initEventListeners []observer.EventListener +) var ( dispatchers = make(map[string]func() observer.EventDispatcher, 8) diff --git a/config/metadata_report_config_test.go b/config/metadata_report_config_test.go index d6b08d5fb0..635feecc2d 100644 --- a/config/metadata_report_config_test.go +++ b/config/metadata_report_config_test.go @@ -1,3 +1,20 @@ +/* + * 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 config import "testing" diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index fd3a290b41..321a216a3e 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -1,3 +1,20 @@ +/* + * 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 SubscriberMetadataIdentifier struct { From 5d380d04f3aba8eb708c5e39273c04a8e29d990f Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sat, 11 Apr 2020 15:57:26 +0800 Subject: [PATCH 023/209] Mod:import pkg rename --- metadata/service/exporter/configurable/exporter.go | 3 ++- metadata/service/exporter/configurable/exporter_test.go | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index a8d73c2a2c..c3338c9621 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -28,6 +28,7 @@ import ( "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/metadata/service/exporter" ) // MetadataServiceExporter is the ConfigurableMetadataServiceExporter which implement MetadataServiceExporter interface @@ -38,7 +39,7 @@ type MetadataServiceExporter struct { } // NewMetadataServiceExporter will return a service_exporter.MetadataServiceExporter with the specified metadata service -func NewMetadataServiceExporter(metadataService service.MetadataService) service.MetadataServiceExporter { +func NewMetadataServiceExporter(metadataService service.MetadataService) exporter.MetadataServiceExporter { return &MetadataServiceExporter{ metadataService: metadataService, } diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index e67bf07a39..0975f07213 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -18,7 +18,6 @@ package configurable import ( - "github.com/apache/dubbo-go/metadata/service" "testing" ) @@ -55,7 +54,7 @@ func TestConfigurableExporter(t *testing.T) { }}) config.MockInitProviderWithSingleRegistry() metadataService := inmemory.NewMetadataService() - exported := service.NewMetadataServiceExporter(metadataService) + exported := NewMetadataServiceExporter(metadataService) assert.Equal(t, false, exported.IsExported()) assert.NoError(t, exported.Export()) assert.Equal(t, true, exported.IsExported()) From 6707dfb5863c6b011fbd273929d68611a090ba68 Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 13 Apr 2020 20:31:06 +0800 Subject: [PATCH 024/209] Fix format --- registry/nacos/service_discovery.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 8ef72c1b11..7d3406cac2 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -280,6 +280,6 @@ func newNacosServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error } return &nacosServiceDiscovery{ nacosBaseRegistry: base, - group: url.GetParam(constant.NACOS_GROUP, defaultGroup), + group: url.GetParam(constant.NACOS_GROUP, defaultGroup), }, nil } From f09c99193af5f703d5ea4687a08758e7158c705d Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 15 Apr 2020 22:35:48 +0800 Subject: [PATCH 025/209] Add extensiong for metadata service --- common/extension/service_name_mapping.go | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 common/extension/service_name_mapping.go diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go new file mode 100644 index 0000000000..05cf2de96b --- /dev/null +++ b/common/extension/service_name_mapping.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 extension + +import ( + "github.com/apache/dubbo-go/metadata" +) + +var( + nameMappings = make(map[string]func()metadata.ServiceNameMapping) +) + +func SetServiceNameMapping(name string, creator func()metadata.ServiceNameMapping) { + // TODO(@邓大明) +} + +func GetServiceNameMapping(name string) metadata.ServiceNameMapping { + // TODO(@邓大明) + return nil +} From f5800271965b013854b258a1e361252c69fad46e Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Fri, 17 Apr 2020 11:28:02 +0800 Subject: [PATCH 026/209] Mod:rw problem --- config/config_loader.go | 6 +- config/config_loader_test.go | 55 +++++++++++++++++- config/service_config.go | 57 ++----------------- .../exporter/configurable/exporter_test.go | 56 +++++++++++++++++- metadata/service/service.go | 13 ++++- 5 files changed, 128 insertions(+), 59 deletions(-) diff --git a/config/config_loader.go b/config/config_loader.go index 3476384606..f8d340e702 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -239,12 +239,12 @@ func GetApplicationConfig() *ApplicationConfig { // GetProviderConfig find the provider config // if not found, create new one -func GetProviderConfig() ProviderConfig { +func GetProviderConfig() *ProviderConfig { if providerConfig == nil { logger.Warnf("providerConfig is nil!") - return ProviderConfig{} + return &ProviderConfig{} } - return *providerConfig + return providerConfig } // GetConsumerConfig find the consumer config diff --git a/config/config_loader_test.go b/config/config_loader_test.go index c4cb3efe4b..6527015373 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -18,6 +18,7 @@ package config import ( + "go.uber.org/atomic" "path/filepath" "testing" ) @@ -90,7 +91,7 @@ func TestLoad(t *testing.T) { func TestLoadWithSingleReg(t *testing.T) { doInitConsumerWithSingleRegistry() - MockInitProviderWithSingleRegistry() + mockInitProviderWithSingleRegistry() ms := &MockService{} SetConsumerService(ms) @@ -233,3 +234,55 @@ func TestConfigLoaderWithConfigCenterSingleRegistry(t *testing.T) { assert.Equal(t, "mock://127.0.0.1:2182", consumerConfig.Registries[constant.DEFAULT_KEY].Address) } + +// mockInitProviderWithSingleRegistry will init a mocked providerConfig +func mockInitProviderWithSingleRegistry() { + providerConfig = &ProviderConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registry: &RegistryConfig{ + Address: "mock://127.0.0.1:2181", + Username: "user1", + Password: "pwd1", + }, + Registries: map[string]*RegistryConfig{}, + Services: map[string]*ServiceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: "3", + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + Name: "GetUser", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + { + Name: "GetUser1", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + }, + exported: new(atomic.Bool), + }, + }, + Protocols: map[string]*ProtocolConfig{ + "mock": { + Name: "mock", + Ip: "127.0.0.1", + Port: "20000", + }, + }, + } +} diff --git a/config/service_config.go b/config/service_config.go index 53e6526da4..8a548dfe0f 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -109,6 +109,11 @@ func NewServiceConfig(id string, context context.Context) *ServiceConfig { } } +// InitExported will set exported as false atom bool +func (c *ServiceConfig) InitExported() { + c.exported = atomic.NewBool(false) +} + // IsExport will return whether the service config is exported or not func (c *ServiceConfig) IsExport() bool { return c.exported.Load() @@ -288,55 +293,3 @@ func (c *ServiceConfig) GetExportedUrls() []*common.URL { } return nil } - -// MockInitProviderWithSingleRegistry will init a mocked providerConfig -func MockInitProviderWithSingleRegistry() { - providerConfig = &ProviderConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, - Registry: &RegistryConfig{ - Address: "mock://127.0.0.1:2181", - Username: "user1", - Password: "pwd1", - }, - Registries: map[string]*RegistryConfig{}, - Services: map[string]*ServiceConfig{ - "MockService": { - InterfaceName: "com.MockService", - Protocol: "mock", - Cluster: "failover", - Loadbalance: "random", - Retries: "3", - Group: "huadong_idc", - Version: "1.0.0", - Methods: []*MethodConfig{ - { - Name: "GetUser", - Retries: "2", - Loadbalance: "random", - Weight: 200, - }, - { - Name: "GetUser1", - Retries: "2", - Loadbalance: "random", - Weight: 200, - }, - }, - exported: new(atomic.Bool), - }, - }, - Protocols: map[string]*ProtocolConfig{ - "mock": { - Name: "mock", - Ip: "127.0.0.1", - Port: "20000", - }, - }, - } -} diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index 0975f07213..89e326a822 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -52,7 +52,7 @@ func TestConfigurableExporter(t *testing.T) { MaxMsgLen: 10240000000, SessionName: "server", }}) - config.MockInitProviderWithSingleRegistry() + mockInitProviderWithSingleRegistry() metadataService := inmemory.NewMetadataService() exported := NewMetadataServiceExporter(metadataService) assert.Equal(t, false, exported.IsExported()) @@ -62,3 +62,57 @@ func TestConfigurableExporter(t *testing.T) { exported.Unexport() assert.Equal(t, false, exported.IsExported()) } + +// mockInitProviderWithSingleRegistry will init a mocked providerConfig +func mockInitProviderWithSingleRegistry() { + providerConfig := &config.ProviderConfig{ + ApplicationConfig: &config.ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registry: &config.RegistryConfig{ + Address: "mock://127.0.0.1:2181", + Username: "user1", + Password: "pwd1", + }, + Registries: map[string]*config.RegistryConfig{}, + Services: map[string]*config.ServiceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: "3", + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*config.MethodConfig{ + { + Name: "GetUser", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + { + Name: "GetUser1", + Retries: "2", + Loadbalance: "random", + Weight: 200, + }, + }, + }, + }, + Protocols: map[string]*config.ProtocolConfig{ + "mock": { + Name: "mock", + Ip: "127.0.0.1", + Port: "20000", + }, + }, + } + providerConfig.Services["MockService"].InitExported() + config.SetProviderConfig(*providerConfig) + +} diff --git a/metadata/service/service.go b/metadata/service/service.go index e3c6f21c58..276e3945b8 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -28,18 +28,27 @@ import ( // Metadataservice is used to define meta data related behaviors type MetadataService interface { + // ServiceName will get the service's name in meta service , which is application name ServiceName() (string, error) + // ExportURL will store the exported url in metadata ExportURL(url common.URL) (bool, error) + // UnexportURL will delete the exported url in metadata UnexportURL(url common.URL) error - //RefreshMetadata(exportedRevision string, subscribedRevision string) bool + // SubscribeURL will store the subscribed url in metadata SubscribeURL(url common.URL) (bool, error) + // UnsubscribeURL will delete the subscribed url in metadata UnsubscribeURL(url common.URL) error + // PublishServiceDefinition will generate the target url's code info PublishServiceDefinition(url common.URL) error - + // GetExportedURLs will get the target exported url in metadata GetExportedURLs(serviceInterface string, group string, version string, protocol string) (sets.Set, error) + // GetExportedURLs will get the target subscribed url in metadata GetSubscribedURLs() (sets.Set, error) + // GetServiceDefinition will get the target service info store in metadata GetServiceDefinition(interfaceName string, group string, version string) (string, error) + // GetServiceDefinition will get the target service info store in metadata by service key GetServiceDefinitionByServiceKey(serviceKey string) (string, error) + // Version will return the metadata service version Version() string common.RPCService } From ace7899027ddc123dc7c5dd9c5bde3e83cc09557 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Fri, 17 Apr 2020 11:33:28 +0800 Subject: [PATCH 027/209] Mod:rw problem --- metadata/definition/definition.go | 5 +++-- metadata/identifier/base_metadata_identifier.go | 4 ++-- metadata/service/exporter/configurable/exporter.go | 5 ++--- metadata/service/service.go | 5 ----- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 81b9e58c82..8d4a584ee5 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -23,6 +23,7 @@ import ( import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" ) // ServiceDefinition is the describer of service definition @@ -77,11 +78,11 @@ func ServiceDescriperBuild(serviceName string, group string, version string) str buf := &bytes.Buffer{} if group != "" { buf.WriteString(group) - buf.WriteString("/") + buf.WriteString(constant.PATH_SEPARATOR) } buf.WriteString(serviceName) if version != "" && version != "0.0.0" { - buf.WriteString(":") + buf.WriteString(constant.KEY_SEPARATOR) buf.WriteString(version) } return buf.String() diff --git a/metadata/identifier/base_metadata_identifier.go b/metadata/identifier/base_metadata_identifier.go index 0cd8b075ff..64290c668f 100644 --- a/metadata/identifier/base_metadata_identifier.go +++ b/metadata/identifier/base_metadata_identifier.go @@ -67,7 +67,7 @@ func (mdi *BaseMetadataIdentifier) getFilePathKey(params ...string) string { withPathSeparator(mdi.Version) + withPathSeparator(mdi.Group) + withPathSeparator(mdi.Side) + - joinParams("/", params) + joinParams(constant.PATH_SEPARATOR, params) } @@ -88,7 +88,7 @@ func serviceToPath(serviceInterface string) string { //withPathSeparator... func withPathSeparator(path string) string { if len(path) != 0 { - path = "/" + path + path = constant.PATH_SEPARATOR + path } return path } diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index c3338c9621..fd3527df5c 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -62,11 +62,10 @@ func (exporter *MetadataServiceExporter) Export() error { err := exporter.serviceConfig.Export() logger.Infof("The MetadataService exports urls : %v ", exporter.serviceConfig.GetExportedUrls()) return err - } else { - logger.Warnf("The MetadataService has been exported : %v ", exporter.serviceConfig.GetExportedUrls()) - return nil } + logger.Warnf("The MetadataService has been exported : %v ", exporter.serviceConfig.GetExportedUrls()) + return nil } // Unexport will unexport the metadataService diff --git a/metadata/service/service.go b/metadata/service/service.go index 276e3945b8..21e50335e2 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -61,8 +61,3 @@ type BaseMetadataService struct { func (mts *BaseMetadataService) ServiceName() (string, error) { return config.GetApplicationConfig().Name, nil } - -// RefreshMetadata is used for event listener's calling, to refresh metadata -//func (mts *BaseMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { -// return true -//} From 4521e09441f5b6ee5604973edc0995a46c844201 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Fri, 17 Apr 2020 16:56:14 +0800 Subject: [PATCH 028/209] Mod:rw problem --- config/config_loader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config_loader.go b/config/config_loader.go index c4fc32b9fa..6666409dd3 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -251,12 +251,12 @@ func GetApplicationConfig() *ApplicationConfig { // GetProviderConfig find the provider config // if not found, create new one -func GetProviderConfig() *ProviderConfig { +func GetProviderConfig() ProviderConfig { if providerConfig == nil { logger.Warnf("providerConfig is nil!") - return &ProviderConfig{} + return ProviderConfig{} } - return providerConfig + return *providerConfig } // GetConsumerConfig find the consumer config From 66aa1a05fd984f2a0b4dc309735c9d89964292db Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Fri, 17 Apr 2020 18:49:29 +0800 Subject: [PATCH 029/209] Mod:rw problem --- config/config_loader_test.go | 2 +- config/service_config.go | 3 +++ metadata/identifier/metadata_identifier.go | 4 ++-- metadata/identifier/service_metadata_identifier.go | 4 ++-- metadata/identifier/subscribe_metadata_identifier.go | 4 ++-- metadata/report/factory/report_factory.go | 1 + metadata/report/report.go | 2 +- metadata/service/exporter/configurable/exporter.go | 2 -- metadata/service/exporter/configurable/exporter_test.go | 2 +- metadata/service/exporter/exporter.go | 1 + metadata/service/inmemory/service.go | 8 ++++---- 11 files changed, 18 insertions(+), 15 deletions(-) diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 6527015373..63951d7009 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -242,7 +242,7 @@ func mockInitProviderWithSingleRegistry() { Organization: "dubbo_org", Name: "dubbo", Module: "module", - Version: "2.6.0", + Version: "1.0.0", Owner: "dubbo", Environment: "test"}, Registry: &RegistryConfig{ diff --git a/config/service_config.go b/config/service_config.go index 8a548dfe0f..258de856e6 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -78,6 +78,7 @@ type ServiceConfig struct { cacheProtocol protocol.Protocol cacheMutex sync.Mutex exporters []protocol.Exporter + exportersLock sync.Mutex } // Prefix ... @@ -203,6 +204,8 @@ func (c *ServiceConfig) Unexport() { if c.unexported.Load() { return } + c.exportersLock.Lock() + defer c.exportersLock.Unlock() for _, exporter := range c.exporters { exporter.Unexport() } diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go index b39d60eef8..f8591b7131 100644 --- a/metadata/identifier/metadata_identifier.go +++ b/metadata/identifier/metadata_identifier.go @@ -23,12 +23,12 @@ type MetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey... +// getIdentifierKey will return string format as service:Version:Group:Side:Application func (mdi *MetadataIdentifier) GetIdentifierKey() string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Application) } -// getIdentifierKey... +// getFilePathKey will return string format as metadata/path/Version/Group/Side/Application func (mdi *MetadataIdentifier) GetFilePathKey() string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Application) } diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index 07fdfb4220..c29b1e2f3c 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -28,12 +28,12 @@ type ServiceMetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey... +// getIdentifierKey will return string format as service:Version:Group:Side:Protocol:"revision"+Revision func (mdi *ServiceMetadataIdentifier) GetIdentifierKey() string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Protocol, constant.KEY_REVISON_PREFIX+mdi.Revision) } -// getIdentifierKey... +// getFilePathKey will return string format as 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) } diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index 84f036038a..f507032557 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -23,12 +23,12 @@ type SubscriberMetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey... +// getIdentifierKey will return string format as service:Version:Group:Side:Revision func (mdi *SubscriberMetadataIdentifier) GetIdentifierKey() string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Revision) } -// getIdentifierKey... +// getFilePathKey will return string format as metadata/path/Version/Group/Side/Revision func (mdi *SubscriberMetadataIdentifier) GetFilePathKey() string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Revision) } diff --git a/metadata/report/factory/report_factory.go b/metadata/report/factory/report_factory.go index 2774fcc31a..8769ebdd2f 100644 --- a/metadata/report/factory/report_factory.go +++ b/metadata/report/factory/report_factory.go @@ -26,6 +26,7 @@ var ( MetadataReportInstance report.MetadataReport ) +// MetadataReportFactory interface will create metadata report type MetadataReportFactory interface { CreateMetadataReport(*common.URL) report.MetadataReport } diff --git a/metadata/report/report.go b/metadata/report/report.go index 6b2efb2408..81227e0c76 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -26,7 +26,7 @@ import ( // MetadataReport is an interface of remote metadata report type MetadataReport interface { StoreProviderMetadata(*identifier.MetadataIdentifier, *definition.ServiceDefinition) - StoreConsumeretadata(*identifier.MetadataIdentifier, map[string]string) + StoreConsumerMetadata(*identifier.MetadataIdentifier, map[string]string) SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, *common.URL) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index fd3527df5c..1e05013c01 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -71,8 +71,6 @@ func (exporter *MetadataServiceExporter) Export() error { // Unexport will unexport the metadataService func (exporter *MetadataServiceExporter) Unexport() { if exporter.IsExported() { - exporter.lock.Lock() - defer exporter.lock.Unlock() exporter.serviceConfig.Unexport() } } diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index 89e326a822..f563f2df31 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -70,7 +70,7 @@ func mockInitProviderWithSingleRegistry() { Organization: "dubbo_org", Name: "dubbo", Module: "module", - Version: "2.6.0", + Version: "1.0.0", Owner: "dubbo", Environment: "test"}, Registry: &config.RegistryConfig{ diff --git a/metadata/service/exporter/exporter.go b/metadata/service/exporter/exporter.go index 3c71820579..cfdef3a0e7 100644 --- a/metadata/service/exporter/exporter.go +++ b/metadata/service/exporter/exporter.go @@ -21,6 +21,7 @@ import ( "github.com/apache/dubbo-go/common" ) +// MetadataServiceExporter will export & unexport the metadata service, get exported url, and return is exported or not type MetadataServiceExporter interface { Export() error Unexport() diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index d31e8d862d..5c2ff2dc73 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -47,10 +47,10 @@ type MetadataService struct { // NewMetadataService: initiate a metadata service func NewMetadataService() *MetadataService { return &MetadataService{ - exportedServiceURLs: new(sync.Map), - subscribedServiceURLs: new(sync.Map), - serviceDefinitions: new(sync.Map), - lock: new(sync.RWMutex), + exportedServiceURLs: &sync.Map{}, + subscribedServiceURLs: &sync.Map{}, + serviceDefinitions: &sync.Map{}, + lock: &sync.RWMutex{}, } } From ad995d83fb12d1f87c4ccc49fa19afa1dd1b8910 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Mon, 20 Apr 2020 14:06:17 +0800 Subject: [PATCH 030/209] Add:add for resolve rw --- config/service_config.go | 5 +++-- metadata/identifier/metadata_identifier.go | 4 ++-- .../identifier/service_metadata_identifier.go | 4 ++-- .../identifier/subscribe_metadata_identifier.go | 4 ++-- .../dynamic/service_name_mapping.go | 4 ++-- .../dynamic/service_name_mapping_test.go | 0 .../memory/service_name_mapping.go | 0 .../service_name_mapping.go | 2 +- .../exporter/configurable/exporter_test.go | 1 - metadata/service/inmemory/service_test.go | 15 +++++++++------ 10 files changed, 21 insertions(+), 18 deletions(-) rename metadata/{namemapping => mapping}/dynamic/service_name_mapping.go (97%) rename metadata/{namemapping => mapping}/dynamic/service_name_mapping_test.go (100%) rename metadata/{namemapping => mapping}/memory/service_name_mapping.go (100%) rename metadata/{namemapping => mapping}/service_name_mapping.go (98%) diff --git a/config/service_config.go b/config/service_config.go index 258de856e6..9bc86d6001 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -75,10 +75,11 @@ type ServiceConfig struct { unexported *atomic.Bool exported *atomic.Bool rpcService common.RPCService - cacheProtocol protocol.Protocol cacheMutex sync.Mutex - exporters []protocol.Exporter + cacheProtocol protocol.Protocol + exportersLock sync.Mutex + exporters []protocol.Exporter } // Prefix ... diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go index f8591b7131..18b330ae08 100644 --- a/metadata/identifier/metadata_identifier.go +++ b/metadata/identifier/metadata_identifier.go @@ -23,12 +23,12 @@ type MetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey will return string format as service:Version:Group:Side:Application +// GetIdentifierKey will return string format as 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 will return string format as metadata/path/Version/Group/Side/Application func (mdi *MetadataIdentifier) GetFilePathKey() string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Application) } diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index c29b1e2f3c..92c15704db 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -28,12 +28,12 @@ type ServiceMetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey will return string format as service:Version:Group:Side:Protocol:"revision"+Revision +// GetIdentifierKey will return string format as 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 will return string format as 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) } diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index f507032557..e599fc9e0d 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -23,12 +23,12 @@ type SubscriberMetadataIdentifier struct { BaseMetadataIdentifier } -// getIdentifierKey will return string format as service:Version:Group:Side:Revision +// GetIdentifierKey will return string format as 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 will return string format as metadata/path/Version/Group/Side/Revision func (mdi *SubscriberMetadataIdentifier) GetFilePathKey() string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.Revision) } diff --git a/metadata/namemapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go similarity index 97% rename from metadata/namemapping/dynamic/service_name_mapping.go rename to metadata/mapping/dynamic/service_name_mapping.go index 85e94a89c7..4cfac8f828 100644 --- a/metadata/namemapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -31,7 +31,7 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/config_center" - "github.com/apache/dubbo-go/metadata/namemapping" + "github.com/apache/dubbo-go/metadata/mapping" ) const ( @@ -77,6 +77,6 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str } // NewServiceNameMapping will create an instance of DynamicConfigurationServiceNameMapping -func NewServiceNameMapping(dc config_center.DynamicConfiguration) namemapping.ServiceNameMapping { +func NewServiceNameMapping(dc config_center.DynamicConfiguration) mapping.ServiceNameMapping { return &DynamicConfigurationServiceNameMapping{dc: dc} } diff --git a/metadata/namemapping/dynamic/service_name_mapping_test.go b/metadata/mapping/dynamic/service_name_mapping_test.go similarity index 100% rename from metadata/namemapping/dynamic/service_name_mapping_test.go rename to metadata/mapping/dynamic/service_name_mapping_test.go diff --git a/metadata/namemapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go similarity index 100% rename from metadata/namemapping/memory/service_name_mapping.go rename to metadata/mapping/memory/service_name_mapping.go diff --git a/metadata/namemapping/service_name_mapping.go b/metadata/mapping/service_name_mapping.go similarity index 98% rename from metadata/namemapping/service_name_mapping.go rename to metadata/mapping/service_name_mapping.go index 451a60d2cf..6caed9f0b4 100644 --- a/metadata/namemapping/service_name_mapping.go +++ b/metadata/mapping/service_name_mapping.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package namemapping +package mapping import ( gxset "github.com/dubbogo/gost/container/set" diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index f563f2df31..220ef71dac 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -114,5 +114,4 @@ func mockInitProviderWithSingleRegistry() { } providerConfig.Services["MockService"].InitExported() config.SetProviderConfig(*providerConfig) - } diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go index d68990b3fd..7d701cd6b9 100644 --- a/metadata/service/inmemory/service_test.go +++ b/metadata/service/inmemory/service_test.go @@ -63,11 +63,12 @@ func TestMetadataService(t *testing.T) { version := "0.0.1" protocol := "dubbo" beanName := "UserProvider" - u, _ := common.NewURL(fmt.Sprintf("%v://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+ - "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ - "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&"+ - "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ - "side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", protocol, serviceName, group, version, beanName)) + u, _ := common.NewURL(fmt.Sprintf(`%v://127.0.0.1:20000/com.ikurento.user.UserProvider? + anyhost=true&application=BDTService&category=providers&default.timeout=10000& + dubbo=dubbo-provider-golang-1.0.0&environment=dev&interface=%v&ip=192.168.56.1& + methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447& + revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v& + version=%v&bean.name=%v`, protocol, serviceName, group, version, beanName)) mts.ExportURL(u) sets, _ := mts.GetExportedURLs(serviceName, group, version, protocol) assert.Equal(t, 1, sets.Size()) @@ -88,7 +89,9 @@ func TestMetadataService(t *testing.T) { userProvider := &UserProvider{} common.ServiceMap.Register(serviceName, protocol, userProvider) mts.PublishServiceDefinition(u) - expected := `{"CanonicalName":"com.ikurento.user.UserProvider","CodeSource":"","Methods":[{"Name":"GetUser","ParameterTypes":["slice"],"ReturnType":"ptr","Parameters":null}],"Types":null}` + expected := `{"CanonicalName":"com.ikurento.user.UserProvider","CodeSource":"", + "Methods":[{"Name":"GetUser","ParameterTypes":["slice"], + "ReturnType":"ptr","Parameters":null}],"Types":null}` def1, _ := mts.GetServiceDefinition(serviceName, group, version) assert.Equal(t, def1, expected) serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) From 5067daebad06fb4dd078a399240d82db73070eb2 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Tue, 21 Apr 2020 16:55:49 +0800 Subject: [PATCH 031/209] Mod:treeset to skiplist --- go.mod | 4 +- go.sum | 8 +-- metadata/service/inmemory/service.go | 79 ++++++++++++----------- metadata/service/inmemory/service_test.go | 63 ++++++++++++------ metadata/service/service.go | 6 +- 5 files changed, 92 insertions(+), 68 deletions(-) diff --git a/go.mod b/go.mod index 337fa3996c..fe1891ea6e 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,10 @@ module github.com/apache/dubbo-go require ( - github.com/Workiva/go-datastructures v1.0.50 + github.com/Workiva/go-datastructures v1.0.52 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect github.com/apache/dubbo-go-hessian2 v1.4.0 - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible @@ -17,7 +16,6 @@ require ( github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.8.0 github.com/emicklei/go-restful/v3 v3.0.0 - github.com/emirpasic/gods v1.12.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 diff --git a/go.sum b/go.sum index 2e628c263d..73c3da87a0 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc h1:LkkwnbY+S8Wmw github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= -github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= +github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= @@ -122,8 +122,6 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.0.0 h1:Duxxa4x0WIHW3bYEDmoAPNjmy8Rbqn+utcF74dlF/G8= github.com/emicklei/go-restful/v3 v3.0.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1dNoi6Zs1+Ybvk= github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk= github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM= @@ -384,8 +382,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb h1:lbmvw8r9W55w+aQgWn35W1nuleRIECMoqUrmwAOAvoI= -github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 5c2ff2dc73..c59949401f 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -22,9 +22,8 @@ import ( ) import ( - "github.com/emirpasic/gods/sets" - "github.com/emirpasic/gods/sets/treeset" - "github.com/emirpasic/gods/utils" + cm "github.com/Workiva/go-datastructures/common" + "github.com/Workiva/go-datastructures/slice/skip" ) import ( @@ -54,14 +53,17 @@ func NewMetadataService() *MetadataService { } } -// urlComparator is defined as utils.Comparator for treeset to compare the URL -func urlComparator(a, b interface{}) int { - url1 := a.(*common.URL) - url2 := b.(*common.URL) +// comparator is defined as Comparator for skip list to compare the URL +type comparator common.URL + +// Compare is defined as Comparator for skip list to compare the URL +func (c comparator) Compare(comp cm.Comparator) int { + a := common.URL(c).String() + b := common.URL(comp.(comparator)).String() switch { - case url1.String() > url2.String(): + case a > b: return 1 - case url1.String() < url2.String(): + case a < b: return -1 default: return 0 @@ -75,9 +77,10 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { loaded bool ) logger.Debug(url.ServiceKey()) - if urlSet, loaded = targetMap.LoadOrStore(url.ServiceKey(), treeset.NewWith(urlComparator)); loaded { + if urlSet, loaded = targetMap.LoadOrStore(url.ServiceKey(), skip.New(uint64(0))); loaded { mts.lock.RLock() - if urlSet.(*treeset.Set).Contains(url) { + wantedUrl := urlSet.(*skip.SkipList).Get(comparator(*url)) + if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.RUnlock() return false } @@ -85,11 +88,12 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { } mts.lock.Lock() //double chk - if urlSet.(*treeset.Set).Contains(url) { + wantedUrl := urlSet.(*skip.SkipList).Get(comparator(*url)) + if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.Unlock() return false } - urlSet.(*treeset.Set).Add(url) + urlSet.(*skip.SkipList).Insert(comparator(*url)) mts.lock.Unlock() return true } @@ -98,64 +102,65 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { if value, loaded := targetMap.Load(url.ServiceKey()); loaded { mts.lock.Lock() - value.(*treeset.Set).Remove(url) + value.(*skip.SkipList).Delete(comparator(*url)) mts.lock.Unlock() mts.lock.RLock() defer mts.lock.RUnlock() - if value.(*treeset.Set).Empty() { + if value.(*skip.SkipList).Len() == 0 { targetMap.Delete(url.ServiceKey()) } } } // getAllService can return all the exportedUrlString except for metadataService -func (mts *MetadataService) getAllService(services *sync.Map) sets.Set { - sets := treeset.NewWith(utils.StringComparator) +func (mts *MetadataService) getAllService(services *sync.Map) *skip.SkipList { + skipList := skip.New(uint64(0)) services.Range(func(key, value interface{}) bool { - urls := value.(*treeset.Set) - urls.Each(func(index int, value interface{}) { - url := value.(*common.URL) + urls := value.(*skip.SkipList) + for i := uint64(0); i < urls.Len(); i++ { + url := common.URL(urls.ByPosition(i).(comparator)) if url.GetParam(constant.INTERFACE_KEY, url.Path) != "MetadataService" { - sets.Add(url.String()) + skipList.Insert(comparator(url)) } - }) + } return true }) - return sets + return skipList } // getSpecifiedService can return specified service url by serviceKey -func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) sets.Set { - targetSets := treeset.NewWith(utils.StringComparator) - serviceSet, loaded := services.Load(serviceKey) +func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) *skip.SkipList { + skipList := skip.New(uint64(0)) + serviceList, loaded := services.Load(serviceKey) if loaded { - serviceSet.(*treeset.Set).Each(func(index int, value interface{}) { - url := value.(*common.URL) + urls := serviceList.(*skip.SkipList) + for i := uint64(0); i < urls.Len(); i++ { + url := common.URL(urls.ByPosition(i).(comparator)) if len(protocol) == 0 || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { - targetSets.Add(value.(*common.URL).String()) + skipList.Insert(comparator(url)) } - }) + } } - return targetSets + return skipList } -// ExportURL can store the in memory treeset +// ExportURL can store the in memory func (mts *MetadataService) ExportURL(url common.URL) (bool, error) { return mts.addURL(mts.exportedServiceURLs, &url), nil } -// UnexportURL can remove the url store in memory treeset +// UnexportURL can remove the url store in memory func (mts *MetadataService) UnexportURL(url common.URL) error { mts.removeURL(mts.exportedServiceURLs, &url) return nil } -// SubscribeURL can store the in memory treeset +// SubscribeURL can store the in memory func (mts *MetadataService) SubscribeURL(url common.URL) (bool, error) { return mts.addURL(mts.subscribedServiceURLs, &url), nil } -// UnsubscribeURL can remove the url store in memory treeset +// UnsubscribeURL can remove the url store in memory func (mts *MetadataService) UnsubscribeURL(url common.URL) error { mts.removeURL(mts.subscribedServiceURLs, &url) return nil @@ -189,7 +194,7 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs get all exported urls -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (sets.Set, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { if serviceInterface == constant.ANY_VALUE { return mts.getAllService(mts.exportedServiceURLs), nil } else { @@ -199,7 +204,7 @@ func (mts *MetadataService) GetExportedURLs(serviceInterface string, group strin } // GetSubscribedURLs get all subscribedUrl -func (mts *MetadataService) GetSubscribedURLs() (sets.Set, error) { +func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { return mts.getAllService(mts.subscribedServiceURLs), nil } diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go index 7d701cd6b9..9e593db282 100644 --- a/metadata/service/inmemory/service_test.go +++ b/metadata/service/inmemory/service_test.go @@ -63,38 +63,63 @@ func TestMetadataService(t *testing.T) { version := "0.0.1" protocol := "dubbo" beanName := "UserProvider" - u, _ := common.NewURL(fmt.Sprintf(`%v://127.0.0.1:20000/com.ikurento.user.UserProvider? - anyhost=true&application=BDTService&category=providers&default.timeout=10000& - dubbo=dubbo-provider-golang-1.0.0&environment=dev&interface=%v&ip=192.168.56.1& - methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447& - revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v& - version=%v&bean.name=%v`, protocol, serviceName, group, version, beanName)) + + u2, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider2?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, serviceName, group, version, beanName)) + assert.NoError(t, err) + mts.ExportURL(u2) + + u3, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider3?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, serviceName, group, version, beanName)) + assert.NoError(t, err) + mts.ExportURL(u3) + + u, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider1?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, serviceName, group, version, beanName)) + assert.NoError(t, err) mts.ExportURL(u) - sets, _ := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, 1, sets.Size()) + list, _ := mts.GetExportedURLs(serviceName, group, version, protocol) + assert.Equal(t, uint64(3), list.Len()) + iter := list.IterAtPosition(0) + for iter.Next() { + comparator := iter.Value() + fmt.Println(comparator) + } mts.SubscribeURL(u) mts.SubscribeURL(u) - sets2, _ := mts.GetSubscribedURLs() - assert.Equal(t, 1, sets2.Size()) + list2, _ := mts.GetSubscribedURLs() + assert.Equal(t, uint64(1), list2.Len()) mts.UnexportURL(u) - sets11, _ := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, 0, sets11.Size()) + list3, _ := mts.GetExportedURLs(serviceName, group, version, protocol) + assert.Equal(t, uint64(2), list3.Len()) mts.UnsubscribeURL(u) - sets22, _ := mts.GetSubscribedURLs() - assert.Equal(t, 0, sets22.Size()) + list4, _ := mts.GetSubscribedURLs() + assert.Equal(t, uint64(0), list4.Len()) userProvider := &UserProvider{} common.ServiceMap.Register(serviceName, protocol, userProvider) mts.PublishServiceDefinition(u) - expected := `{"CanonicalName":"com.ikurento.user.UserProvider","CodeSource":"", - "Methods":[{"Name":"GetUser","ParameterTypes":["slice"], - "ReturnType":"ptr","Parameters":null}],"Types":null}` + expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," + + "\"Methods\":[{\"Name\":\"GetUser\",\"ParameterTypes\":[\"slice\"],\"ReturnType\":\"ptr\"," + + "\"Parameters\":null}],\"Types\":null}" def1, _ := mts.GetServiceDefinition(serviceName, group, version) - assert.Equal(t, def1, expected) + assert.Equal(t, expected, def1) serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) def2, _ := mts.GetServiceDefinitionByServiceKey(serviceKey) - assert.Equal(t, def2, expected) + assert.Equal(t, expected, def2) } diff --git a/metadata/service/service.go b/metadata/service/service.go index 21e50335e2..8ff63b5059 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -18,7 +18,7 @@ package service import ( - "github.com/emirpasic/gods/sets" + "github.com/Workiva/go-datastructures/slice/skip" ) import ( @@ -41,9 +41,9 @@ type MetadataService interface { // PublishServiceDefinition will generate the target url's code info PublishServiceDefinition(url common.URL) error // GetExportedURLs will get the target exported url in metadata - GetExportedURLs(serviceInterface string, group string, version string, protocol string) (sets.Set, error) + GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) // GetExportedURLs will get the target subscribed url in metadata - GetSubscribedURLs() (sets.Set, error) + GetSubscribedURLs() (*skip.SkipList, error) // GetServiceDefinition will get the target service info store in metadata GetServiceDefinition(interfaceName string, group string, version string) (string, error) // GetServiceDefinition will get the target service info store in metadata by service key From f595f501512728da090c093b7102c1cbcd97a2b7 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Tue, 21 Apr 2020 18:02:38 +0800 Subject: [PATCH 032/209] Mod:resolve conflict --- config/config_loader_test.go | 2 +- config/service_config.go | 16 +++++++---- .../service/exporter/configurable/exporter.go | 28 +++++++++++-------- metadata/service/service.go | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 63951d7009..0192b4c8a0 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -18,13 +18,13 @@ package config import ( - "go.uber.org/atomic" "path/filepath" "testing" ) import ( "github.com/stretchr/testify/assert" + "go.uber.org/atomic" ) import ( diff --git a/config/service_config.go b/config/service_config.go index 9bc86d6001..9cf60c8fb3 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -205,12 +205,16 @@ func (c *ServiceConfig) Unexport() { if c.unexported.Load() { return } - c.exportersLock.Lock() - defer c.exportersLock.Unlock() - for _, exporter := range c.exporters { - exporter.Unexport() - } - c.exporters = nil + + func() { + c.exportersLock.Lock() + defer c.exportersLock.Unlock() + for _, exporter := range c.exporters { + exporter.Unexport() + } + c.exporters = nil + }() + c.exported.Store(false) c.unexported.Store(true) } diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index 1e05013c01..3d12e0ecd4 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -48,22 +48,28 @@ func NewMetadataServiceExporter(metadataService service.MetadataService) exporte // Export will export the metadataService func (exporter *MetadataServiceExporter) Export() error { if !exporter.IsExported() { - exporter.lock.Lock() - defer exporter.lock.Unlock() - exporter.serviceConfig = config.NewServiceConfig("MetadataService", context.Background()) - exporter.serviceConfig.Protocol = constant.DEFAULT_PROTOCOL - exporter.serviceConfig.Protocols = map[string]*config.ProtocolConfig{ + + serviceConfig := config.NewServiceConfig("MetadataService", context.Background()) + serviceConfig.Protocol = constant.DEFAULT_PROTOCOL + serviceConfig.Protocols = map[string]*config.ProtocolConfig{ constant.DEFAULT_PROTOCOL: generateMetadataProtocol(), } - exporter.serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME - exporter.serviceConfig.Group = config.GetApplicationConfig().Name - exporter.serviceConfig.Version = exporter.metadataService.Version() - exporter.serviceConfig.Implement(exporter.metadataService) - err := exporter.serviceConfig.Export() + serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME + serviceConfig.Group = config.GetApplicationConfig().Name + serviceConfig.Version = exporter.metadataService.Version() + + var err error + func() { + exporter.lock.Lock() + defer exporter.lock.Unlock() + exporter.serviceConfig = serviceConfig + exporter.serviceConfig.Implement(exporter.metadataService) + err = exporter.serviceConfig.Export() + }() + logger.Infof("The MetadataService exports urls : %v ", exporter.serviceConfig.GetExportedUrls()) return err } - logger.Warnf("The MetadataService has been exported : %v ", exporter.serviceConfig.GetExportedUrls()) return nil } diff --git a/metadata/service/service.go b/metadata/service/service.go index 8ff63b5059..bc526c5411 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -28,6 +28,7 @@ import ( // Metadataservice is used to define meta data related behaviors type MetadataService interface { + common.RPCService // ServiceName will get the service's name in meta service , which is application name ServiceName() (string, error) // ExportURL will store the exported url in metadata @@ -50,7 +51,6 @@ type MetadataService interface { GetServiceDefinitionByServiceKey(serviceKey string) (string, error) // Version will return the metadata service version Version() string - common.RPCService } // BaseMetadataService is used for the common logic for struct who will implement interface MetadataService From 2ac672f9f9007550dfd5f2d446ea21b451ccffe0 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 21 Apr 2020 18:44:36 +0800 Subject: [PATCH 033/209] event_publishing_service_discovery.go init --- .../event_publishing_service_discovery.go | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 registry/common/event_publishing_service_discovery.go diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go new file mode 100644 index 0000000000..b595700ad0 --- /dev/null +++ b/registry/common/event_publishing_service_discovery.go @@ -0,0 +1,90 @@ +/* + * 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 common + +import ( + gxset "github.com/dubbogo/gost/container/set" + gxpage "github.com/dubbogo/gost/page" +) + +import ( + "github.com/apache/dubbo-go/registry" +) + +type EventPublishingServiceDiscovery struct { +} + +func (epsd *EventPublishingServiceDiscovery) String() string { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) Destroy() error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceInstance) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceInstance) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.ServiceInstance) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetDefaultPageSize() int { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetServices() *gxset.HashSet { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) DispatchEventByServiceName(serviceName string) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + panic("implement me") +} + +func (epsd *EventPublishingServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + panic("implement me") +} From 5b104517d2e23472eb504a99698ed7da1f4b4c8e Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 13 Apr 2020 22:03:54 +0800 Subject: [PATCH 034/209] implement GetConfigKeysByGroup --- config_center/nacos/impl.go | 25 +++++++++++++++++++++---- config_center/nacos/impl_test.go | 30 +++++++++++++++++++++++++++++- go.mod | 16 +++------------- go.sum | 3 +++ 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/config_center/nacos/impl.go b/config_center/nacos/impl.go index 007b8be142..0b8aceb23c 100644 --- a/config_center/nacos/impl.go +++ b/config_center/nacos/impl.go @@ -36,7 +36,10 @@ import ( "github.com/apache/dubbo-go/config_center/parser" ) -const nacosClientName = "nacos config_center" +const ( + nacosClientName = "nacos config_center" + maxKeysNum = 9999 +) type nacosDynamicConfiguration struct { url *common.URL @@ -108,9 +111,23 @@ func (n *nacosDynamicConfiguration) PublishConfig(key string, group string, valu // GetConfigKeysByGroup will return all keys with the group func (n *nacosDynamicConfiguration) GetConfigKeysByGroup(group string) (*gxset.HashSet, error) { - // TODO (the golang client of nacos does not support batch API) - // we should build a issue and then think about how to resolve this problem - return nil, perrors.New("unsupport operation, wait for implement") + group = n.resolvedGroup(group) + page, err := (*n.client.Client()).SearchConfig(vo.SearchConfigParm{ + Search: "accurate", + Group: group, + PageNo: 1, + // actually it's impossible for user to create 9999 application under one group + PageSize: maxKeysNum, + }) + + result := gxset.NewSet() + if err != nil { + return result, perrors.WithMessage(err, "can not find the client config") + } + for _, itm := range page.PageItems { + result.Add(itm.Content) + } + return result, nil } // GetRule Get router rule diff --git a/config_center/nacos/impl_test.go b/config_center/nacos/impl_test.go index 4032c91cda..b74c155d92 100644 --- a/config_center/nacos/impl_test.go +++ b/config_center/nacos/impl_test.go @@ -88,6 +88,34 @@ func Test_GetConfig(t *testing.T) { assert.NoError(t, err) } +func TestNacosDynamicConfiguration_GetConfigKeysByGroup(t *testing.T) { + data := ` +{ + "PageItems": [ + { + "Content": "application" + } + ] +} +` + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(data)) + })) + + nacosURL := strings.ReplaceAll(ts.URL, "http", "registry") + regurl, _ := common.NewURL(nacosURL) + nacosConfiguration, err := newNacosDynamicConfiguration(®url) + assert.NoError(t, err) + + nacosConfiguration.SetParser(&parser.DefaultConfigurationParser{}) + + configs, err := nacosConfiguration.GetConfigKeysByGroup("dubbo") + assert.Nil(t, err) + assert.Equal(t, 1, configs.Size()) + assert.True(t, configs.Contains("application")) + +} + func TestNacosDynamicConfiguration_PublishConfig(t *testing.T) { nacos, err := initNacosData(t) assert.Nil(t, err) @@ -109,7 +137,7 @@ func Test_AddListener(t *testing.T) { } func Test_RemoveListener(t *testing.T) { - //TODO not supported in current go_nacos_sdk version + // TODO not supported in current go_nacos_sdk version } type mockDataListener struct { diff --git a/go.mod b/go.mod index fe1891ea6e..40e4aeaaa9 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/apache/dubbo-go require ( github.com/Workiva/go-datastructures v1.0.52 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 - github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect github.com/apache/dubbo-go-hessian2 v1.4.0 - github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible github.com/coreos/go-semver v0.3.0 // indirect @@ -16,8 +14,6 @@ require ( github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.8.0 github.com/emicklei/go-restful/v3 v3.0.0 - github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect - github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 @@ -29,32 +25,26 @@ require ( github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 github.com/hashicorp/consul v1.5.3 github.com/hashicorp/consul/api v1.1.0 - github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 - github.com/jonboulle/clockwork v0.1.0 // indirect - github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect - github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect - github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect github.com/magiconair/properties v1.8.1 github.com/mitchellh/mapstructure v1.1.2 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd - github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c + github.com/nacos-group/nacos-sdk-go v0.3.0 github.com/opentracing/opentracing-go v1.1.0 - github.com/pkg/errors v0.8.1 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.1.0 github.com/satori/go.uuid v1.2.0 github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect github.com/soheilhy/cmux v0.1.4 // indirect github.com/stretchr/testify v1.5.1 - github.com/tebeka/strftime v0.1.3 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect - github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/etcd v3.3.13+incompatible go.uber.org/atomic v1.4.0 go.uber.org/zap v1.10.0 + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect google.golang.org/grpc v1.22.1 gopkg.in/yaml.v2 v2.2.2 k8s.io/api v0.0.0-20190325185214-7544f9db76f6 diff --git a/go.sum b/go.sum index 73c3da87a0..6d15442900 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apache/dubbo-go-hessian2 v1.4.0 h1:Cb9FQVTy3G93dnDr7P93U8DeKFYpDTJjQp44JG5TafA= github.com/apache/dubbo-go-hessian2 v1.4.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= @@ -384,6 +385,7 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= +github.com/nacos-group/nacos-sdk-go v0.3.0/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0= @@ -417,6 +419,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= From c8920d398545aae758e5c5459749b91dd07725a8 Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 21 Apr 2020 23:05:50 +0800 Subject: [PATCH 035/209] Fix travis --- go.sum | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go.sum b/go.sum index 6d15442900..ff5a38a1b5 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apache/dubbo-go-hessian2 v1.4.0 h1:Cb9FQVTy3G93dnDr7P93U8DeKFYpDTJjQp44JG5TafA= @@ -385,6 +386,7 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= +github.com/nacos-group/nacos-sdk-go v0.3.0 h1:2v2QmihtyX6ZUXAN+ya+5h2pedn7R5M+WJwSJPFsuMY= github.com/nacos-group/nacos-sdk-go v0.3.0/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= @@ -419,6 +421,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= From ae7d706e293915d75102cf70bfb7c9e2aff138e4 Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Fri, 24 Apr 2020 22:03:53 +0800 Subject: [PATCH 036/209] support service discovery registry --- common/constant/key.go | 14 +- common/extension/service_discovery.go | 2 +- .../service_instance_selector_factory.go | 40 ++ common/extension/service_name_mapping.go | 10 +- go.mod | 1 + registry/event_listener.go | 15 +- .../random_service_instance_selector.go | 51 ++ .../random_service_instance_selector_test.go | 50 ++ .../instance/service_instance_selector.go | 27 + .../proxy/metadata_service_proxy_factory.go | 31 + registry/service/proxy/service_proxy.go | 29 + .../service/service_discovery_registry.go | 574 ++++++++++++++++++ .../service_discovery_registry_test.go | 49 ++ .../rest/rest_subscribed_urls_synthesizer.go | 59 ++ .../rest_subscribed_urls_synthesizer_test.go | 62 ++ .../subscribed_urls_synthesizer.go | 28 + .../subscribed_urls_synthesizer_factory.go | 30 + 17 files changed, 1062 insertions(+), 10 deletions(-) create mode 100644 common/extension/service_instance_selector_factory.go create mode 100644 registry/service/instance/random/random_service_instance_selector.go create mode 100644 registry/service/instance/random/random_service_instance_selector_test.go create mode 100644 registry/service/instance/service_instance_selector.go create mode 100644 registry/service/proxy/metadata_service_proxy_factory.go create mode 100644 registry/service/proxy/service_proxy.go create mode 100644 registry/service/service_discovery_registry.go create mode 100644 registry/service/service_discovery_registry_test.go create mode 100644 registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go create mode 100644 registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go create mode 100644 registry/service/synthesizer/subscribed_urls_synthesizer.go create mode 100644 registry/service/synthesizer/subscribed_urls_synthesizer_factory.go diff --git a/common/constant/key.go b/common/constant/key.go index da21a3a9e1..a2f8938757 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -79,6 +79,7 @@ const ( EXECUTE_REJECTED_EXECUTION_HANDLER_KEY = "execute.limit.rejected.handler" PROVIDER_SHUTDOWN_FILTER = "pshutdown" CONSUMER_SHUTDOWN_FILTER = "cshutdown" + PID_KEY = "pid" ) const ( @@ -255,5 +256,16 @@ const ( // service discovery const ( - NACOS_GROUP = "nacos.group" + NACOS_GROUP = "nacos.group" + SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" + PROVIDER_BY = "provided-by" + EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" + SERVICE_INSTANCE_SELECTOR = "service-instance-selector" + METADATA_STORAGE_TYPE_PROPERTY_NAME = "dubbo.metadata.storage-type" + DEFAULT_METADATA_STORAGE_TYPE = "local" + SERVICE_INSTANCE_ENDPOINTS = "dubbo.endpoints" + METADATA_SERVICE_PREFIX = "dubbo.metadata-service." + METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" + METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" + SERVICE_NAME_MAPPING_KEY = "service-name-mapping" ) diff --git a/common/extension/service_discovery.go b/common/extension/service_discovery.go index 25b80cf335..488d94ebf1 100644 --- a/common/extension/service_discovery.go +++ b/common/extension/service_discovery.go @@ -18,11 +18,11 @@ package extension import ( + "github.com/apache/dubbo-go/registry" perrors "github.com/pkg/errors" ) import ( "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/registry" ) var ( diff --git a/common/extension/service_instance_selector_factory.go b/common/extension/service_instance_selector_factory.go new file mode 100644 index 0000000000..1dd1ac6c99 --- /dev/null +++ b/common/extension/service_instance_selector_factory.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 extension + +import ( + "github.com/apache/dubbo-go/registry/service/instance" + perrors "github.com/pkg/errors" +) + +var ( + serviceInstanceSelectorMappings = make(map[string]func() instance.ServiceInstanceSelector) +) + +func SetServiceInstanceSelector(name string, f func() instance.ServiceInstanceSelector) { + serviceInstanceSelectorMappings[name] = f +} + +func GetServiceInstanceSelector(name string) (instance.ServiceInstanceSelector, error) { + serviceInstanceSelector, ok := serviceInstanceSelectorMappings[name] + if !ok { + return nil, perrors.New("Could not find service instance selector with" + + "name:" + name) + } + return serviceInstanceSelector(), nil +} diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 05cf2de96b..1598430752 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -18,18 +18,18 @@ package extension import ( - "github.com/apache/dubbo-go/metadata" + "github.com/apache/dubbo-go/metadata/mapping" ) -var( - nameMappings = make(map[string]func()metadata.ServiceNameMapping) +var ( + nameMappings = make(map[string]func() mapping.ServiceNameMapping) ) -func SetServiceNameMapping(name string, creator func()metadata.ServiceNameMapping) { +func SetServiceNameMapping(name string, creator func() mapping.ServiceNameMapping) { // TODO(@邓大明) } -func GetServiceNameMapping(name string) metadata.ServiceNameMapping { +func GetServiceNameMapping(name string) mapping.ServiceNameMapping { // TODO(@邓大明) return nil } diff --git a/go.mod b/go.mod index fe1891ea6e..8a599aa55f 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 github.com/google/btree v1.0.0 // indirect + github.com/gotestyourself/gotestyourself v2.2.0+incompatible github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect diff --git a/registry/event_listener.go b/registry/event_listener.go index 0aaa081a44..23da690e55 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -25,13 +25,14 @@ import ( "github.com/apache/dubbo-go/common/observer" ) -// TODO (implement ConditionalEventListener) type ServiceInstancesChangedListener struct { ServiceName string - observer.EventListener + observer.ConditionalEventListener + ChangedNotify ChangedNotify } -func (sicl *ServiceInstancesChangedListener) OnEvent(e observer.Event) error { +func (sicl *ServiceInstancesChangedListener) OnEvent(e ServiceInstancesChangedEvent) error { + sicl.ChangedNotify.Notify(e) return nil } @@ -42,3 +43,11 @@ func (sicl *ServiceInstancesChangedListener) GetPriority() int { func (sicl *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) } + +func (sicl *ServiceInstancesChangedListener) Accept(e ServiceInstancesChangedEvent) bool { + return e.ServiceName == sicl.ServiceName +} + +type ChangedNotify interface { + Notify(e ServiceInstancesChangedEvent) +} diff --git a/registry/service/instance/random/random_service_instance_selector.go b/registry/service/instance/random/random_service_instance_selector.go new file mode 100644 index 0000000000..47f84c76c8 --- /dev/null +++ b/registry/service/instance/random/random_service_instance_selector.go @@ -0,0 +1,51 @@ +/* + * 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 random + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/registry" + "github.com/apache/dubbo-go/registry/service/instance" + "math/rand" + "time" +) + +func init() { + extension.SetServiceInstanceSelector("random", NewRandomServiceInstanceSelector) +} + +type RandomServiceInstanceSelector struct { +} + +func NewRandomServiceInstanceSelector() instance.ServiceInstanceSelector { + return &RandomServiceInstanceSelector{} +} + +func (r *RandomServiceInstanceSelector) Select(url common.URL, serviceInstances []registry.ServiceInstance) registry.ServiceInstance { + if len(serviceInstances) == 0 { + return nil + } + if len(serviceInstances) == 1 { + return serviceInstances[0] + } + rand.Seed(time.Now().UnixNano()) + index := rand.Intn(len(serviceInstances)) + return serviceInstances[index] + +} diff --git a/registry/service/instance/random/random_service_instance_selector_test.go b/registry/service/instance/random/random_service_instance_selector_test.go new file mode 100644 index 0000000000..ed4b7838fc --- /dev/null +++ b/registry/service/instance/random/random_service_instance_selector_test.go @@ -0,0 +1,50 @@ +/* + * 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 random + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/registry" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestRandomServiceInstanceSelector_Select(t *testing.T) { + selector := NewRandomServiceInstanceSelector() + serviceInstances := []registry.ServiceInstance{ + ®istry.DefaultServiceInstance{ + Id: "1", + ServiceName: "test1", + Host: "127.0.0.1:80", + Port: 0, + Enable: false, + Healthy: false, + Metadata: nil, + }, + ®istry.DefaultServiceInstance{ + Id: "2", + ServiceName: "test2", + Host: "127.0.0.1:80", + Port: 0, + Enable: false, + Healthy: false, + Metadata: nil, + }, + } + assert.NotNil(t, selector.Select(common.URL{}, serviceInstances)) +} diff --git a/registry/service/instance/service_instance_selector.go b/registry/service/instance/service_instance_selector.go new file mode 100644 index 0000000000..acacde5617 --- /dev/null +++ b/registry/service/instance/service_instance_selector.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 instance + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/registry" +) + +type ServiceInstanceSelector interface { + Select(url common.URL, serviceInstances []registry.ServiceInstance) registry.ServiceInstance +} diff --git a/registry/service/proxy/metadata_service_proxy_factory.go b/registry/service/proxy/metadata_service_proxy_factory.go new file mode 100644 index 0000000000..7e8d891bf3 --- /dev/null +++ b/registry/service/proxy/metadata_service_proxy_factory.go @@ -0,0 +1,31 @@ +/* + * 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 proxy + +var ( + serviceProxy = make(map[string]func() BaseMetadataServiceProxy) +) + +func SetMetadataServiceProxy(name string, creator func() BaseMetadataServiceProxy) { + //TODO +} + +func GetMetadataServiceProxy(name string) BaseMetadataServiceProxy { + //TODO + return nil +} diff --git a/registry/service/proxy/service_proxy.go b/registry/service/proxy/service_proxy.go new file mode 100644 index 0000000000..7a14201fdd --- /dev/null +++ b/registry/service/proxy/service_proxy.go @@ -0,0 +1,29 @@ +/* + * 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 proxy + +import ( + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" +) + +type BaseMetadataServiceProxy interface { + GetProxy(serviceInstance registry.ServiceInstance) service.MetadataService + + CreateProxy(serviceInstance registry.ServiceInstance) service.MetadataService +} diff --git a/registry/service/service_discovery_registry.go b/registry/service/service_discovery_registry.go new file mode 100644 index 0000000000..c946b9890f --- /dev/null +++ b/registry/service/service_discovery_registry.go @@ -0,0 +1,574 @@ +/* + * 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 service + +import ( + "bytes" + "encoding/json" + cm "github.com/Workiva/go-datastructures/common" + "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/metadata/mapping" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/metadata/service/inmemory" + "github.com/apache/dubbo-go/registry" + "github.com/apache/dubbo-go/registry/service/proxy" + "github.com/apache/dubbo-go/registry/service/synthesizer" + "github.com/apache/dubbo-go/remoting" + gxset "github.com/dubbogo/gost/container/set" + "strconv" + "strings" + "sync" +) + +const ( + SERVICE_REGISTRY_PROTOCOL = "service-discovery-registry" +) + +func init() { + extension.SetRegistry(SERVICE_REGISTRY_PROTOCOL, newServiceDiscoveryRegistry) +} + +type serviceDiscoveryRegistry struct { + lock sync.RWMutex + url *common.URL + serviceDiscovery registry.ServiceDiscovery + subscribedServices *gxset.HashSet + serviceNameMapping mapping.ServiceNameMapping + metaDataService service.MetadataService + registeredListeners *gxset.HashSet + subscribedURLsSynthesizers []synthesizer.SubscribedURLsSynthesizer + serviceRevisionExportedURLsCache map[string]map[string][]common.URL +} + +func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { + serviceDiscovery, err := creatServiceDiscovery(url) + if err != nil { + return nil, err + } + subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) + subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() + serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) + //TODO it's need to get implement by factory + metaDataService := inmemory.NewMetadataService() + return &serviceDiscoveryRegistry{ + url: url, + serviceDiscovery: serviceDiscovery, + subscribedServices: subscribedServices, + subscribedURLsSynthesizers: subscribedURLsSynthesizers, + registeredListeners: gxset.NewSet(), + serviceRevisionExportedURLsCache: make(map[string]map[string][]common.URL), + serviceNameMapping: serviceNameMapping, + metaDataService: metaDataService, + }, nil +} + +func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { + return extension.GetServiceDiscovery(url.Protocol, url) +} + +func parseServices(literalServices string) *gxset.HashSet { + set := gxset.NewSet() + if len(literalServices) == 0 { + return set + } + var splitServices = strings.Split(literalServices, ",") + for _, s := range splitServices { + if len(s) != 0 { + set.Add(s) + } + } + return set +} + +func (s *serviceDiscoveryRegistry) GetServiceDiscovery() registry.ServiceDiscovery { + return s.serviceDiscovery +} + +func (s *serviceDiscoveryRegistry) GetUrl() common.URL { + return *s.url +} + +func (s *serviceDiscoveryRegistry) IsAvailable() bool { + return true +} + +func (s *serviceDiscoveryRegistry) Destroy() { + err := s.serviceDiscovery.Destroy() + if err != nil { + logger.Errorf("destroy serviceDiscovery catch error:%s", err.Error()) + } +} + +func (s *serviceDiscoveryRegistry) Register(url common.URL) error { + if !shouldRegister(url) { + return nil + } + ok, err := s.metaDataService.ExportURL(url) + if err != nil { + logger.Errorf("The URL[%s] registry catch error:%s!", url.String(), err.Error()) + return err + } + if ok { + logger.Infof("The URL[%s] registry successfully!", url.String()) + } else { + logger.Warnf("The URL[%s] has been registry!", url.String()) + } + return nil +} + +func shouldRegister(url common.URL) bool { + side := url.GetParam(constant.SIDE_KEY, "") + if side == constant.PROVIDER_PROTOCOL { + return true + } + logger.Debugf("The URL should not be register.", url.String()) + return false +} + +func (s *serviceDiscoveryRegistry) Subscribe(url *common.URL, notify registry.NotifyListener) { + if !shouldSubscribe(*url) { + return + } + _, err := s.metaDataService.SubscribeURL(*url) + if err != nil { + logger.Errorf("subscribe url[%s] catch error:%s", url.String(), err.Error()) + return + } + services := s.getServices(*url) + if services.Empty() { + logger.Errorf("Should has at least one way to know which services this interface belongs to, "+ + "subscription url:%s", url.String()) + return + } + for _, srv := range services.Values() { + serviceName := srv.(string) + serviceInstances := s.serviceDiscovery.GetInstances(serviceName) + s.subscribe(url, notify, serviceName, serviceInstances) + listener := ®istry.ServiceInstancesChangedListener{ + ServiceName: serviceName, + ChangedNotify: &InstanceChangeNotify{ + notify: notify, + serviceDiscoveryRegistry: s, + }, + } + s.registerServiceInstancesChangedListener(*url, listener) + } + +} +func (s *serviceDiscoveryRegistry) registerServiceInstancesChangedListener(url common.URL, listener *registry.ServiceInstancesChangedListener) { + listenerId := listener.ServiceName + ":" + getUrlKey(url) + if !s.subscribedServices.Contains(listenerId) { + err := s.serviceDiscovery.AddListener(listener) + if err != nil { + logger.Errorf("add listener[%s] catch error,url:%s err:%s", listenerId, url.String(), err.Error()) + } + } + +} + +func getUrlKey(url common.URL) string { + var bf bytes.Buffer + if len(url.Protocol) != 0 { + bf.WriteString(url.Protocol) + bf.WriteString("://") + } + if len(url.Location) != 0 { + bf.WriteString(url.Location) + bf.WriteString(":") + bf.WriteString(url.Port) + } + if len(url.Path) != 0 { + bf.WriteString("/") + bf.WriteString(url.Path) + } + bf.WriteString("?") + appendParam(bf, constant.VERSION_KEY, url) + appendParam(bf, constant.GROUP_KEY, url) + appendParam(bf, constant.NACOS_PROTOCOL_KEY, url) + return bf.String() +} + +func appendParam(buffer bytes.Buffer, paramKey string, url common.URL) { + buffer.WriteString(paramKey) + buffer.WriteString("=") + buffer.WriteString(url.GetParam(paramKey, "")) +} + +func (s *serviceDiscoveryRegistry) subscribe(url *common.URL, notify registry.NotifyListener, + serviceName string, serviceInstances []registry.ServiceInstance) { + if len(serviceInstances) == 0 { + logger.Warnf("here is no instance in service[name : %s]", serviceName) + return + } + var subscribedURLs []common.URL + subscribedURLs = append(subscribedURLs, s.getExportedUrls(*url, serviceInstances)...) + if len(subscribedURLs) == 0 { + subscribedURLs = s.synthesizeSubscribedURLs(url, serviceInstances) + } + //TODO make sure it's workable + for _, url := range subscribedURLs { + notify.Notify(®istry.ServiceEvent{ + Action: remoting.EventTypeAdd, + Service: url, + }) + } + +} + +func (s *serviceDiscoveryRegistry) synthesizeSubscribedURLs(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL { + var urls []common.URL + for _, syn := range s.subscribedURLsSynthesizers { + if syn.Support(subscribedURL) { + urls = append(urls, syn.Synthesize(subscribedURL, serviceInstances)...) + } + } + return urls +} +func shouldSubscribe(url common.URL) bool { + return !shouldRegister(url) +} + +func (s *serviceDiscoveryRegistry) getServices(url common.URL) *gxset.HashSet { + services := gxset.NewSet() + serviceNames := url.GetParam(constant.PROVIDER_BY, "") + if len(serviceNames) != 0 { + services = parseServices(serviceNames) + } + if services.Empty() { + services = s.findMappedServices(url) + if services.Empty() { + return s.subscribedServices + } + } + return services +} + +func (s *serviceDiscoveryRegistry) findMappedServices(url common.URL) *gxset.HashSet { + serviceInterface := url.GetParam(constant.INTERFACE_KEY, url.Path) + group := url.GetParam(constant.GROUP_KEY, "") + version := url.GetParam(constant.VERSION_KEY, "") + protocol := url.Protocol + serviceNames, err := s.serviceNameMapping.Get(serviceInterface, group, version, protocol) + if err != nil { + logger.Errorf("get serviceInterface:[%s] group:[%s] version:[%s] protocol:[%s] from "+ + "serviceNameMap error:%s", err.Error()) + return gxset.NewSet() + } + return serviceNames +} + +func (s *serviceDiscoveryRegistry) getExportedUrls(subscribedURL common.URL, serviceInstances []registry.ServiceInstance) []common.URL { + filterInstances := make([]registry.ServiceInstance, len(serviceInstances), len(serviceInstances)) + for _, s := range serviceInstances { + if !s.IsEnable() || !s.IsHealthy() { + continue + } + metaData := s.GetMetadata() + _, ok1 := metaData[constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME] + _, ok2 := metaData[constant.METADATA_SERVICE_URLS_PROPERTY_NAME] + if !ok1 && !ok2 { + continue + } + filterInstances = append(filterInstances, s) + } + if len(filterInstances) == 0 { + return []common.URL{} + } + s.prepareServiceRevisionExportedURLs(filterInstances) + subscribedURLs := s.cloneExportedURLs(subscribedURL, filterInstances) + return subscribedURLs +} + +// comparator is defined as Comparator for skip list to compare the URL +type comparator common.URL + +// Compare is defined as Comparator for skip list to compare the URL +func (c comparator) Compare(comp cm.Comparator) int { + a := common.URL(c).String() + b := common.URL(comp.(comparator)).String() + switch { + case a > b: + return 1 + case a < b: + return -1 + default: + return 0 + } +} + +func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registry.ServiceInstance) []common.URL { + var urls []common.URL + metadataStorageType := getExportedStoreType(serviceInstance) + metadataProxy := proxy.GetMetadataServiceProxy(metadataStorageType) + if metadataProxy == nil { + return urls + } + metadataService := metadataProxy.GetProxy(serviceInstance) + if metadataService == nil { + return urls + } + result, err := metadataService.GetExportedURLs("*", "", "", "") + if err != nil { + logger.Errorf("get exported urls catch error:%s,instance:%+v", err.Error(), serviceInstance) + return urls + } + if result == nil { + logger.Errorf("get empty exported urls,instance:%+v", serviceInstance) + return urls + } + for i := uint64(0); i < result.Len(); i++ { + urls = append(urls, common.URL(result.ByPosition(i).(comparator))) + } + return urls +} + +func (s *serviceDiscoveryRegistry) prepareServiceRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { + s.lock.Lock() + // 1. expunge stale + s.expungeStaleRevisionExportedURLs(serviceInstances) + // 2. Initialize + s.initRevisionExportedURLs(serviceInstances) + s.lock.Unlock() +} + +func (s *serviceDiscoveryRegistry) expungeStaleRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { + serviceName := serviceInstances[0].GetServiceName() + revisionExportedURLsMap, exist := s.serviceRevisionExportedURLsCache[serviceName] + if !exist { + return + } + existRevision := gxset.NewSet() + for k := range revisionExportedURLsMap { + existRevision.Add(k) + } + currentRevision := gxset.NewSet() + for _, s := range serviceInstances { + rv := getExportedServicesRevision(s) + if len(rv) != 0 { + currentRevision.Add(rv) + } + } + // staleRevisions = existedRevisions(copy) - currentRevisions + staleRevision := gxset.NewSet(existRevision.Values()...) + staleRevision.Remove(currentRevision.Values()...) + // remove exported URLs if staled + for _, s := range staleRevision.Values() { + delete(revisionExportedURLsMap, s.(string)) + } +} + +func (s *serviceDiscoveryRegistry) initRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { + // initialize the revision exported URLs that the selected service instance exported + s.initSelectedRevisionExportedURLs(serviceInstances) + // initialize the revision exported URLs that other service instances exported + for _, serviceInstance := range serviceInstances { + s.initRevisionExportedURLsByInst(serviceInstance) + } +} + +func (s *serviceDiscoveryRegistry) initSelectedRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { + for range serviceInstances { + selectServiceInstance := s.selectServiceInstance(serviceInstances) + revisionExportedURLs := s.initRevisionExportedURLsByInst(selectServiceInstance) + if len(revisionExportedURLs) != 0 { + // If the result is valid,break + break + } + } +} + +func (s *serviceDiscoveryRegistry) selectServiceInstance(serviceInstances []registry.ServiceInstance) registry.ServiceInstance { + size := len(serviceInstances) + if size == 0 { + return nil + } + if size == 1 { + return serviceInstances[0] + } + selectorName := s.url.GetParam(constant.SERVICE_INSTANCE_SELECTOR, "random") + selector, err := extension.GetServiceInstanceSelector(selectorName) + if err != nil { + logger.Errorf("get service instance selector cathe error:%s", err.Error()) + return nil + } + return selector.Select(*s.url, serviceInstances) +} + +func (s *serviceDiscoveryRegistry) initRevisionExportedURLsByInst(serviceInstance registry.ServiceInstance) []common.URL { + if serviceInstance == nil { + return []common.URL{} + } + serviceName := serviceInstance.GetServiceName() + revision := getExportedServicesRevision(serviceInstance) + revisionExportedURLsMap := s.serviceRevisionExportedURLsCache[serviceName] + revisionExportedURLs := revisionExportedURLsMap[revision] + firstGet := false + if revisionExportedURLs == nil || len(revisionExportedURLs) == 0 { + if len(revisionExportedURLsMap) > 0 { + // The case is that current ServiceInstance with the different revision + logger.Warnf("The ServiceInstance[id: %s, host : %s , port : %s] has different revision : %s"+ + ", please make sure the service [name : %s] is changing or not.", serviceInstance.GetId(), + serviceInstance.GetHost(), serviceInstance.GetPort(), revision, serviceInstance.GetServiceName()) + } else { + firstGet = true + } + revisionExportedURLs = s.getExportedUrlsByInst(serviceInstance) + if revisionExportedURLs != nil { + revisionExportedURLsMap[revision] = revisionExportedURLs + logger.Debugf("Get the exported URLs[size : %s, first : %s] from the target service "+ + "instance [id: %s , service : %s , host : %s , port : %s , revision : %s]", + len(revisionExportedURLs), firstGet, serviceInstance.GetId(), serviceInstance.GetServiceName(), + serviceInstance.GetHost(), serviceInstance.GetPort(), revision) + } + } else { + //Else, The cache is hit + logger.Debugf("Get the exported URLs[size : %s] from cache, the instance"+ + "[id: %s , service : %s , host : %s , port : %s , revision : %s]", len(revisionExportedURLs), firstGet, + serviceInstance.GetId(), serviceInstance.GetServiceName(), serviceInstance.GetHost(), + serviceInstance.GetPort(), revision) + } + return revisionExportedURLs +} + +func getExportedServicesRevision(serviceInstance registry.ServiceInstance) string { + metaData := serviceInstance.GetMetadata() + return metaData[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] +} + +func getExportedStoreType(serviceInstance registry.ServiceInstance) string { + metaData := serviceInstance.GetMetadata() + result, ok := metaData[constant.METADATA_STORAGE_TYPE_PROPERTY_NAME] + if !ok { + return constant.DEFAULT_METADATA_STORAGE_TYPE + } + return result +} + +func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsances []registry.ServiceInstance) []common.URL { + if serviceInsances == nil || len(serviceInsances) == 0 { + return []common.URL{} + } + var clonedExportedURLs []common.URL + removeParamSet := gxset.NewSet() + removeParamSet.Add(constant.PID_KEY) + removeParamSet.Add(constant.TIMESTAMP_KEY) + for _, serviceInstance := range serviceInsances { + templateExportURLs := s.getTemplateExportedURLs(url, serviceInstance) + host := serviceInstance.GetHost() + for _, u := range templateExportURLs { + u.RemoveParams(removeParamSet) + port := strconv.Itoa(getProtocolPort(serviceInstance, u.Protocol)) + if u.Location != host || u.Port != port { + u.Port = port //reset port + u.Location = host //reset host + } + clonedExportedURLs = append(clonedExportedURLs, u) + } + } + return clonedExportedURLs + +} + +type endpoint struct { + Port int `json:"port"` + Protocol string `json:"protocol"` +} + +func getProtocolPort(serviceInstance registry.ServiceInstance, protocol string) int { + md := serviceInstance.GetMetadata() + rawEndpoints := md[constant.SERVICE_INSTANCE_ENDPOINTS] + if len(rawEndpoints) == 0 { + return -1 + } + var endpoints []endpoint + err := json.Unmarshal([]byte(rawEndpoints), &endpoints) + if err != nil { + logger.Errorf("json umarshal rawEndpoints[%s] catch error:%s", rawEndpoints, err.Error()) + return -1 + } + for _, e := range endpoints { + if e.Protocol == protocol { + return e.Port + } + } + return -1 +} +func (s *serviceDiscoveryRegistry) getTemplateExportedURLs(url common.URL, serviceInstance registry.ServiceInstance) []common.URL { + exportedURLs := s.getRevisionExportedURLs(serviceInstance) + if len(exportedURLs) == 0 { + return []common.URL{} + } + return filterSubscribedURLs(url, exportedURLs) +} + +func (s *serviceDiscoveryRegistry) getRevisionExportedURLs(serviceInstance registry.ServiceInstance) []common.URL { + if serviceInstance == nil { + return []common.URL{} + } + serviceName := serviceInstance.GetServiceName() + revision := getExportedServicesRevision(serviceInstance) + s.lock.RLock() + revisionExportedURLsMap, exist := s.serviceRevisionExportedURLsCache[serviceName] + if !exist { + return []common.URL{} + } + exportedURLs, exist := revisionExportedURLsMap[revision] + if !exist { + return []common.URL{} + } + s.lock.RUnlock() + // Get a copy from source in order to prevent the caller trying to change the cached data + cloneExportedURLs := make([]common.URL, len(exportedURLs)) + copy(cloneExportedURLs, exportedURLs) + return cloneExportedURLs +} + +func filterSubscribedURLs(subscribedURL common.URL, exportedURLs []common.URL) []common.URL { + var filterExportedURLs []common.URL + for _, url := range exportedURLs { + if url.GetParam(constant.INTERFACE_KEY, url.Path) != subscribedURL.GetParam(constant.INTERFACE_KEY, url.Path) { + break + } + if url.GetParam(constant.VERSION_KEY, "") != subscribedURL.GetParam(constant.VERSION_KEY, "") { + break + } + if url.GetParam(constant.GROUP_KEY, "") != subscribedURL.GetParam(constant.GROUP_KEY, "") { + break + } + if len(subscribedURL.Protocol) != 0 { + if subscribedURL.Protocol != url.Protocol { + break + } + } + filterExportedURLs = append(filterExportedURLs, url) + } + return filterExportedURLs +} + +type InstanceChangeNotify struct { + notify registry.NotifyListener + serviceDiscoveryRegistry *serviceDiscoveryRegistry +} + +func (icn *InstanceChangeNotify) Notify(event registry.ServiceInstancesChangedEvent) { + sdr := icn.serviceDiscoveryRegistry + sdr.subscribe(sdr.url, icn.notify, event.ServiceName, event.Instances) +} diff --git a/registry/service/service_discovery_registry_test.go b/registry/service/service_discovery_registry_test.go new file mode 100644 index 0000000000..41b681d991 --- /dev/null +++ b/registry/service/service_discovery_registry_test.go @@ -0,0 +1,49 @@ +/* + * 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 service + +import ( + "testing" +) + +var ( + SERVICE_INTERFACE = "org.apache.dubbo.metadata.MetadataService" + GROUP = "dubbo-provider" + VERSION = "1.0.0" +) + +func TestServiceDiscoveryRegistry_Register(t *testing.T) { + //registryURL,_:=common.NewURL("in-memory://localhost:12345", + // common.WithParamsValue("registry-type","service"), + // common.WithParamsValue("subscribed-services","a, b , c,d,e ,")) + //url,_:=common.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + + // "?&application=" + GROUP + + // "&interface=" + SERVICE_INTERFACE + + // "&group=" + GROUP + + // "&version=" + VERSION + + // "&methods=getAllServiceKeys,getServiceRestMetadata,getExportedURLs,getAllExportedURLs" + + // "&side=provider") + //registry,err:=newServiceDiscoveryRegistry(®istryURL) + //if err!=nil{ + // logger.Errorf("create service discovery registry catch error:%s",err.Error()) + //} + //assert.Nil(t,err) + //assert.NotNil(t,registry) + //registry.Register(url) + +} diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go new file mode 100644 index 0000000000..7d3de7a3cd --- /dev/null +++ b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go @@ -0,0 +1,59 @@ +/* + * 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 rest + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/registry" + "github.com/apache/dubbo-go/registry/service/synthesizer" + "strings" +) + +func init() { + synthesizer.AddSynthesizer(NewRestSubscribedURLsSynthesizer()) +} + +type RestSubscribedURLsSynthesizer struct { +} + +func (r RestSubscribedURLsSynthesizer) Support(subscribedURL *common.URL) bool { + if "rest" == subscribedURL.Protocol { + return true + } + return false +} + +func (r RestSubscribedURLsSynthesizer) Synthesize(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL { + urls := make([]common.URL, len(serviceInstances), len(serviceInstances)) + for _, s := range serviceInstances { + splitHost := strings.Split(s.GetHost(), ":") + url := common.NewURLWithOptions(common.WithProtocol(subscribedURL.Protocol), common.WithIp(splitHost[0]), + common.WithPort(splitHost[1]), common.WithPath(subscribedURL.GetParam(constant.INTERFACE_KEY, subscribedURL.Path)), + common.WithParamsValue(constant.SIDE_KEY, constant.PROVIDER_PROTOCOL), + common.WithParamsValue(constant.APPLICATION_KEY, s.GetServiceName()), + common.WithParamsValue(constant.REGISTRY_KEY, "true"), + ) + urls = append(urls, *url) + } + return urls +} + +func NewRestSubscribedURLsSynthesizer() RestSubscribedURLsSynthesizer { + return RestSubscribedURLsSynthesizer{} +} diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go new file mode 100644 index 0000000000..1e8c1172bd --- /dev/null +++ b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go @@ -0,0 +1,62 @@ +/* + * 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 rest + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/registry" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestRestSubscribedURLsSynthesizer_Synthesize(t *testing.T) { + syn := RestSubscribedURLsSynthesizer{} + subUrl, _ := common.NewURL("rest://127.0.0.1:20000/org.apache.dubbo-go.mockService") + instances := []registry.ServiceInstance{ + ®istry.DefaultServiceInstance{ + Id: "test1", + ServiceName: "test1", + Host: "127.0.0.1:80", + Port: 80, + Enable: false, + Healthy: false, + Metadata: nil, + }, + ®istry.DefaultServiceInstance{ + Id: "test2", + ServiceName: "test2", + Host: "127.0.0.2:8081", + Port: 8081, + Enable: false, + Healthy: false, + Metadata: nil, + }, + } + + var expectUrls []common.URL + u1, _ := common.NewURL("rest://127.0.0.1:80/org.apache.dubbo-go.mockService", common.WithParamsValue(constant.SIDE_KEY, + constant.PROVIDER_PROTOCOL), common.WithParamsValue(constant.APPLICATION_KEY, "test1"), + common.WithParamsValue(constant.REGISTRY_KEY, "true")) + u2, _ := common.NewURL("rest://127.0.0.2:8081/org.apache.dubbo-go.mockService", common.WithParamsValue(constant.SIDE_KEY, + constant.PROVIDER_PROTOCOL), common.WithParamsValue(constant.APPLICATION_KEY, "test2"), + common.WithParamsValue(constant.REGISTRY_KEY, "true")) + expectUrls = append(expectUrls, u1, u2) + result := syn.Synthesize(&subUrl, instances) + assert.Equal(t, expectUrls, result) +} diff --git a/registry/service/synthesizer/subscribed_urls_synthesizer.go b/registry/service/synthesizer/subscribed_urls_synthesizer.go new file mode 100644 index 0000000000..f2d5b99f1c --- /dev/null +++ b/registry/service/synthesizer/subscribed_urls_synthesizer.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 synthesizer + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/registry" +) + +type SubscribedURLsSynthesizer interface { + Support(subscribedURL *common.URL) bool + Synthesize(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL +} diff --git a/registry/service/synthesizer/subscribed_urls_synthesizer_factory.go b/registry/service/synthesizer/subscribed_urls_synthesizer_factory.go new file mode 100644 index 0000000000..f8c76f6e84 --- /dev/null +++ b/registry/service/synthesizer/subscribed_urls_synthesizer_factory.go @@ -0,0 +1,30 @@ +/* + * 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 synthesizer + +var ( + synthesizers []SubscribedURLsSynthesizer +) + +func AddSynthesizer(synthesizer SubscribedURLsSynthesizer) { + synthesizers = append(synthesizers, synthesizer) +} + +func GetAllSynthesizer() []SubscribedURLsSynthesizer { + return synthesizers +} From 802239208db998d7de51d4d7fb0c4d45a8aebed0 Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Fri, 24 Apr 2020 23:30:38 +0800 Subject: [PATCH 037/209] fix synthesizer bug --- registry/service/service_discovery_registry.go | 2 +- .../rest/rest_subscribed_urls_synthesizer.go | 8 +++++--- .../rest_subscribed_urls_synthesizer_test.go | 17 ++++++++++++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/registry/service/service_discovery_registry.go b/registry/service/service_discovery_registry.go index c946b9890f..b3c9e6a632 100644 --- a/registry/service/service_discovery_registry.go +++ b/registry/service/service_discovery_registry.go @@ -276,7 +276,7 @@ func (s *serviceDiscoveryRegistry) findMappedServices(url common.URL) *gxset.Has } func (s *serviceDiscoveryRegistry) getExportedUrls(subscribedURL common.URL, serviceInstances []registry.ServiceInstance) []common.URL { - filterInstances := make([]registry.ServiceInstance, len(serviceInstances), len(serviceInstances)) + var filterInstances []registry.ServiceInstance for _, s := range serviceInstances { if !s.IsEnable() || !s.IsHealthy() { continue diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go index 7d3de7a3cd..a7e7a5bc30 100644 --- a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go +++ b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go @@ -22,6 +22,7 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/service/synthesizer" + "net/url" "strings" ) @@ -41,15 +42,16 @@ func (r RestSubscribedURLsSynthesizer) Support(subscribedURL *common.URL) bool { func (r RestSubscribedURLsSynthesizer) Synthesize(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL { urls := make([]common.URL, len(serviceInstances), len(serviceInstances)) - for _, s := range serviceInstances { + for i, s := range serviceInstances { splitHost := strings.Split(s.GetHost(), ":") - url := common.NewURLWithOptions(common.WithProtocol(subscribedURL.Protocol), common.WithIp(splitHost[0]), + u := common.NewURLWithOptions(common.WithProtocol(subscribedURL.Protocol), common.WithIp(splitHost[0]), common.WithPort(splitHost[1]), common.WithPath(subscribedURL.GetParam(constant.INTERFACE_KEY, subscribedURL.Path)), + common.WithParams(url.Values{}), common.WithParamsValue(constant.SIDE_KEY, constant.PROVIDER_PROTOCOL), common.WithParamsValue(constant.APPLICATION_KEY, s.GetServiceName()), common.WithParamsValue(constant.REGISTRY_KEY, "true"), ) - urls = append(urls, *url) + urls[i] = *u } return urls } diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go index 1e8c1172bd..8ad1b50227 100644 --- a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go +++ b/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go @@ -22,6 +22,7 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" "github.com/stretchr/testify/assert" + "net/url" "testing" ) @@ -50,13 +51,19 @@ func TestRestSubscribedURLsSynthesizer_Synthesize(t *testing.T) { } var expectUrls []common.URL - u1, _ := common.NewURL("rest://127.0.0.1:80/org.apache.dubbo-go.mockService", common.WithParamsValue(constant.SIDE_KEY, - constant.PROVIDER_PROTOCOL), common.WithParamsValue(constant.APPLICATION_KEY, "test1"), + u1 := common.NewURLWithOptions(common.WithProtocol("rest"), common.WithIp("127.0.0.1"), + common.WithPort("80"), common.WithPath("org.apache.dubbo-go.mockService"), + common.WithParams(url.Values{}), + common.WithParamsValue(constant.SIDE_KEY, constant.PROVIDER_PROTOCOL), + common.WithParamsValue(constant.APPLICATION_KEY, "test1"), common.WithParamsValue(constant.REGISTRY_KEY, "true")) - u2, _ := common.NewURL("rest://127.0.0.2:8081/org.apache.dubbo-go.mockService", common.WithParamsValue(constant.SIDE_KEY, - constant.PROVIDER_PROTOCOL), common.WithParamsValue(constant.APPLICATION_KEY, "test2"), + u2 := common.NewURLWithOptions(common.WithProtocol("rest"), common.WithIp("127.0.0.2"), + common.WithPort("8081"), common.WithPath("org.apache.dubbo-go.mockService"), + common.WithParams(url.Values{}), + common.WithParamsValue(constant.SIDE_KEY, constant.PROVIDER_PROTOCOL), + common.WithParamsValue(constant.APPLICATION_KEY, "test2"), common.WithParamsValue(constant.REGISTRY_KEY, "true")) - expectUrls = append(expectUrls, u1, u2) + expectUrls = append(expectUrls, *u1, *u2) result := syn.Synthesize(&subUrl, instances) assert.Equal(t, expectUrls, result) } From 839e0ddfa0dc6c7e80f30883e580e811ab83e678 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 28 Apr 2020 21:24:55 +0800 Subject: [PATCH 038/209] add EventPublishingServiceDiscovery constructor --- registry/common/event_publishing_service_discovery.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go index b595700ad0..8c6881f65a 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/common/event_publishing_service_discovery.go @@ -26,7 +26,15 @@ import ( "github.com/apache/dubbo-go/registry" ) +// EventPublishingServiceDiscovery will enhance Service Discovery +// Publish some event about service discovery type EventPublishingServiceDiscovery struct { + serviceDiscovery *registry.ServiceDiscovery +} + +// NewEventPublishingServiceDiscovery is a constructor +func NewEventPublishingServiceDiscovery(serviceDiscovery *registry.ServiceDiscovery) *EventPublishingServiceDiscovery { + return &EventPublishingServiceDiscovery{serviceDiscovery: serviceDiscovery} } func (epsd *EventPublishingServiceDiscovery) String() string { From 530f563498bcbb9b568cf86393c7bf85df2eb775 Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 28 Apr 2020 22:23:47 +0800 Subject: [PATCH 039/209] Implement event dispatcher --- .../dispatcher/mock_event_dispatcher.go | 58 +++++++++++++++++++ go.mod | 2 +- go.sum | 2 + registry/nacos/service_discovery.go | 2 +- registry/nacos/service_discovery_test.go | 17 ++++-- 5 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 common/observer/dispatcher/mock_event_dispatcher.go diff --git a/common/observer/dispatcher/mock_event_dispatcher.go b/common/observer/dispatcher/mock_event_dispatcher.go new file mode 100644 index 0000000000..45cdaa71a2 --- /dev/null +++ b/common/observer/dispatcher/mock_event_dispatcher.go @@ -0,0 +1,58 @@ +/* + * 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 dispatcher + +import ( + "github.com/apache/dubbo-go/common/observer" +) + +// MockEventDispatcher will do nothing. +// It is only used by tests +// Now the implementation doing nothing, +// But you can modify this if needed +type MockEventDispatcher struct { +} + +// AddEventListener do nothing +func (m MockEventDispatcher) AddEventListener(listener observer.EventListener) { +} + +// AddEventListeners do nothing +func (m MockEventDispatcher) AddEventListeners(listenersSlice []observer.EventListener) { +} + +// RemoveEventListener do nothing +func (m MockEventDispatcher) RemoveEventListener(listener observer.EventListener) { +} + +// RemoveEventListeners do nothing +func (m MockEventDispatcher) RemoveEventListeners(listenersSlice []observer.EventListener) { +} + +// GetAllEventListeners return empty list +func (m MockEventDispatcher) GetAllEventListeners() []observer.EventListener { + return make([]observer.EventListener, 0) +} + +// RemoveAllEventListeners do nothing +func (m MockEventDispatcher) RemoveAllEventListeners() { +} + +// Dispatch do nothing +func (m MockEventDispatcher) Dispatch(event observer.Event) { +} diff --git a/go.mod b/go.mod index 40e4aeaaa9..1c3c52d579 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/magiconair/properties v1.8.1 github.com/mitchellh/mapstructure v1.1.2 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd - github.com/nacos-group/nacos-sdk-go v0.3.0 + github.com/nacos-group/nacos-sdk-go v0.3.1 github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.1.0 diff --git a/go.sum b/go.sum index ff5a38a1b5..22370ceea8 100644 --- a/go.sum +++ b/go.sum @@ -388,6 +388,8 @@ github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3A github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nacos-group/nacos-sdk-go v0.3.0 h1:2v2QmihtyX6ZUXAN+ya+5h2pedn7R5M+WJwSJPFsuMY= github.com/nacos-group/nacos-sdk-go v0.3.0/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= +github.com/nacos-group/nacos-sdk-go v0.3.1 h1:MI7bNDAN5m9UFcRRUTSPfJi4dCQo+TYG85qVB1rCHeg= +github.com/nacos-group/nacos-sdk-go v0.3.1/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0= diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 7d3406cac2..fbd84ac44d 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -237,7 +237,7 @@ func (n *nacosServiceDiscovery) DispatchEventForInstances(serviceName string, in // DispatchEvent will dispatch the event func (n *nacosServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { - // TODO(waiting for event dispatcher, another task) + extension.GetGlobalDispatcher().Dispatch(event) return nil } diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index a756e86693..0ac46cb9a2 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -30,19 +30,28 @@ 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/observer" + "github.com/apache/dubbo-go/common/observer/dispatcher" "github.com/apache/dubbo-go/registry" ) func TestNacosServiceDiscovery_Destroy(t *testing.T) { - serviceDiscovry, err := extension.GetServiceDiscovery(constant.NACOS_KEY, mockUrl()) + serviceDiscovery, err := extension.GetServiceDiscovery(constant.NACOS_KEY, mockUrl()) assert.Nil(t, err) - assert.NotNil(t, serviceDiscovry) - err = serviceDiscovry.Destroy() + assert.NotNil(t, serviceDiscovery) + err = serviceDiscovery.Destroy() assert.Nil(t, err) - assert.Nil(t, serviceDiscovry.(*nacosServiceDiscovery).namingClient) + assert.Nil(t, serviceDiscovery.(*nacosServiceDiscovery).namingClient) } func TestNacosServiceDiscovery_CRUD(t *testing.T) { + + extension.SetEventDispatcher("mock", func() observer.EventDispatcher { + return &dispatcher.MockEventDispatcher{} + }) + + extension.SetAndInitGlobalDispatcher("mock") + serviceName := "service-name" id := "id" host := "host" From 682f4059dbf77edc8cbd0b718cdd350b3f805dee Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 1 May 2020 22:39:47 +0800 Subject: [PATCH 040/209] Add dynamic --- .../mapping/dynamic/service_name_mapping.go | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 4cfac8f828..5e40692905 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -19,6 +19,7 @@ package dynamic import ( "strconv" + "sync" "time" ) @@ -28,7 +29,9 @@ import ( ) import ( + env "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/config" "github.com/apache/dubbo-go/config_center" "github.com/apache/dubbo-go/metadata/mapping" @@ -37,9 +40,16 @@ import ( const ( defaultGroup = config_center.DEFAULT_GROUP slash = "/" + name = "dynamic" ) +func init() { + extension.SetServiceNameMapping(name, GetServiceNameMappingInstance) + extension.SetServiceNameMapping(constant.DEFAULT_KEY, GetServiceNameMappingInstance) +} + // DynamicConfigurationServiceNameMapping is the implementation based on config center +// It could be thought as singleton pattern. type DynamicConfigurationServiceNameMapping struct { dc config_center.DynamicConfiguration } @@ -76,7 +86,22 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str return defaultGroup + slash + serviceInterface } -// NewServiceNameMapping will create an instance of DynamicConfigurationServiceNameMapping -func NewServiceNameMapping(dc config_center.DynamicConfiguration) mapping.ServiceNameMapping { +var ( + instance *DynamicConfigurationServiceNameMapping + initOnce sync.Once +) + +// newServiceNameMapping will create an instance of DynamicConfigurationServiceNameMapping +func newServiceNameMapping(dc config_center.DynamicConfiguration) *DynamicConfigurationServiceNameMapping { return &DynamicConfigurationServiceNameMapping{dc: dc} } + +// GetServiceNameMappingInstance will return the instance. +// If the instance is not initiated, it will create one +func GetServiceNameMappingInstance() mapping.ServiceNameMapping { + initOnce.Do(func() { + dc := env.GetEnvInstance().GetDynamicConfiguration() + instance = newServiceNameMapping(dc) + }) + return instance +} From a5da721ad47a9bbd213c2179be414ddea27e9887 Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 1 May 2020 22:42:33 +0800 Subject: [PATCH 041/209] rename service => service discovery --- common/extension/service_instance_selector_factory.go | 2 +- .../instance/random/random_service_instance_selector.go | 2 +- .../random/random_service_instance_selector_test.go | 0 .../instance/service_instance_selector.go | 0 .../proxy/metadata_service_proxy_factory.go | 0 .../{service => servicediscovery}/proxy/service_proxy.go | 0 .../service_discovery_registry.go | 6 +++--- .../service_discovery_registry_test.go | 2 +- .../synthesizer/rest/rest_subscribed_urls_synthesizer.go | 2 +- .../rest/rest_subscribed_urls_synthesizer_test.go | 0 .../synthesizer/subscribed_urls_synthesizer.go | 0 .../synthesizer/subscribed_urls_synthesizer_factory.go | 0 12 files changed, 7 insertions(+), 7 deletions(-) rename registry/{service => servicediscovery}/instance/random/random_service_instance_selector.go (96%) rename registry/{service => servicediscovery}/instance/random/random_service_instance_selector_test.go (100%) rename registry/{service => servicediscovery}/instance/service_instance_selector.go (100%) rename registry/{service => servicediscovery}/proxy/metadata_service_proxy_factory.go (100%) rename registry/{service => servicediscovery}/proxy/service_proxy.go (100%) rename registry/{service => servicediscovery}/service_discovery_registry.go (99%) rename registry/{service => servicediscovery}/service_discovery_registry_test.go (98%) rename registry/{service => servicediscovery}/synthesizer/rest/rest_subscribed_urls_synthesizer.go (96%) rename registry/{service => servicediscovery}/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go (100%) rename registry/{service => servicediscovery}/synthesizer/subscribed_urls_synthesizer.go (100%) rename registry/{service => servicediscovery}/synthesizer/subscribed_urls_synthesizer_factory.go (100%) diff --git a/common/extension/service_instance_selector_factory.go b/common/extension/service_instance_selector_factory.go index 1dd1ac6c99..d767e0a7dc 100644 --- a/common/extension/service_instance_selector_factory.go +++ b/common/extension/service_instance_selector_factory.go @@ -18,7 +18,7 @@ package extension import ( - "github.com/apache/dubbo-go/registry/service/instance" + "github.com/apache/dubbo-go/registry/servicediscovery/instance" perrors "github.com/pkg/errors" ) diff --git a/registry/service/instance/random/random_service_instance_selector.go b/registry/servicediscovery/instance/random/random_service_instance_selector.go similarity index 96% rename from registry/service/instance/random/random_service_instance_selector.go rename to registry/servicediscovery/instance/random/random_service_instance_selector.go index 47f84c76c8..1efbbc3fcb 100644 --- a/registry/service/instance/random/random_service_instance_selector.go +++ b/registry/servicediscovery/instance/random/random_service_instance_selector.go @@ -21,7 +21,7 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/registry" - "github.com/apache/dubbo-go/registry/service/instance" + "github.com/apache/dubbo-go/registry/servicediscovery/instance" "math/rand" "time" ) diff --git a/registry/service/instance/random/random_service_instance_selector_test.go b/registry/servicediscovery/instance/random/random_service_instance_selector_test.go similarity index 100% rename from registry/service/instance/random/random_service_instance_selector_test.go rename to registry/servicediscovery/instance/random/random_service_instance_selector_test.go diff --git a/registry/service/instance/service_instance_selector.go b/registry/servicediscovery/instance/service_instance_selector.go similarity index 100% rename from registry/service/instance/service_instance_selector.go rename to registry/servicediscovery/instance/service_instance_selector.go diff --git a/registry/service/proxy/metadata_service_proxy_factory.go b/registry/servicediscovery/proxy/metadata_service_proxy_factory.go similarity index 100% rename from registry/service/proxy/metadata_service_proxy_factory.go rename to registry/servicediscovery/proxy/metadata_service_proxy_factory.go diff --git a/registry/service/proxy/service_proxy.go b/registry/servicediscovery/proxy/service_proxy.go similarity index 100% rename from registry/service/proxy/service_proxy.go rename to registry/servicediscovery/proxy/service_proxy.go diff --git a/registry/service/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go similarity index 99% rename from registry/service/service_discovery_registry.go rename to registry/servicediscovery/service_discovery_registry.go index b3c9e6a632..7256416c1e 100644 --- a/registry/service/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package service +package servicediscovery import ( "bytes" @@ -29,8 +29,8 @@ import ( "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/inmemory" "github.com/apache/dubbo-go/registry" - "github.com/apache/dubbo-go/registry/service/proxy" - "github.com/apache/dubbo-go/registry/service/synthesizer" + "github.com/apache/dubbo-go/registry/servicediscovery/proxy" + "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" gxset "github.com/dubbogo/gost/container/set" "strconv" diff --git a/registry/service/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go similarity index 98% rename from registry/service/service_discovery_registry_test.go rename to registry/servicediscovery/service_discovery_registry_test.go index 41b681d991..90a8c0e257 100644 --- a/registry/service/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package service +package servicediscovery import ( "testing" diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go similarity index 96% rename from registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go rename to registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go index a7e7a5bc30..e09dfd6be7 100644 --- a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer.go +++ b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go @@ -21,7 +21,7 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" - "github.com/apache/dubbo-go/registry/service/synthesizer" + "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "net/url" "strings" ) diff --git a/registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go similarity index 100% rename from registry/service/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go rename to registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go diff --git a/registry/service/synthesizer/subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go similarity index 100% rename from registry/service/synthesizer/subscribed_urls_synthesizer.go rename to registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go diff --git a/registry/service/synthesizer/subscribed_urls_synthesizer_factory.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go similarity index 100% rename from registry/service/synthesizer/subscribed_urls_synthesizer_factory.go rename to registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go From 569e2b684310d6e69fe86ef134bd28ba13a42c01 Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Fri, 1 May 2020 23:59:39 +0800 Subject: [PATCH 042/209] =?UTF-8?q?1=E3=80=81add=20comments=202=E3=80=81fo?= =?UTF-8?q?rmat=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/extension/service_discovery.go | 3 +- .../service_instance_selector_factory.go | 5 ++- go.sum | 6 --- registry/event_listener.go | 5 +++ .../random_service_instance_selector.go | 8 +++- .../random_service_instance_selector_test.go | 10 ++++- .../instance/service_instance_selector.go | 1 + .../service_discovery_registry.go | 38 +++++++++++++------ .../rest/rest_subscribed_urls_synthesizer.go | 8 +++- .../rest_subscribed_urls_synthesizer_test.go | 12 ++++-- .../subscribed_urls_synthesizer.go | 2 + 11 files changed, 69 insertions(+), 29 deletions(-) diff --git a/common/extension/service_discovery.go b/common/extension/service_discovery.go index 488d94ebf1..ac2fe67291 100644 --- a/common/extension/service_discovery.go +++ b/common/extension/service_discovery.go @@ -18,11 +18,12 @@ package extension import ( - "github.com/apache/dubbo-go/registry" perrors "github.com/pkg/errors" ) + import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/registry" ) var ( diff --git a/common/extension/service_instance_selector_factory.go b/common/extension/service_instance_selector_factory.go index d767e0a7dc..3ba3db46e6 100644 --- a/common/extension/service_instance_selector_factory.go +++ b/common/extension/service_instance_selector_factory.go @@ -18,10 +18,13 @@ package extension import ( - "github.com/apache/dubbo-go/registry/servicediscovery/instance" perrors "github.com/pkg/errors" ) +import ( + "github.com/apache/dubbo-go/registry/servicediscovery/instance" +) + var ( serviceInstanceSelectorMappings = make(map[string]func() instance.ServiceInstanceSelector) ) diff --git a/go.sum b/go.sum index 326b4e6897..9bcb1fe457 100644 --- a/go.sum +++ b/go.sum @@ -35,11 +35,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apache/dubbo-go-hessian2 v1.5.0 h1:fzulDG5G7nX0ccgKdiN9XipJ7tZ4WXKgmk4stdlDS6s= github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -53,7 +50,6 @@ github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL6 github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -389,8 +385,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nacos-group/nacos-sdk-go v0.3.1 h1:MI7bNDAN5m9UFcRRUTSPfJi4dCQo+TYG85qVB1rCHeg= github.com/nacos-group/nacos-sdk-go v0.3.1/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= diff --git a/registry/event_listener.go b/registry/event_listener.go index 23da690e55..34fd81de74 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -25,25 +25,30 @@ import ( "github.com/apache/dubbo-go/common/observer" ) +//The Service Discovery Changed Event Listener type ServiceInstancesChangedListener struct { ServiceName string observer.ConditionalEventListener ChangedNotify ChangedNotify } +//On ServiceInstancesChangedEvent the service instances change event func (sicl *ServiceInstancesChangedListener) OnEvent(e ServiceInstancesChangedEvent) error { sicl.ChangedNotify.Notify(e) return nil } +//get listener priority func (sicl *ServiceInstancesChangedListener) GetPriority() int { return -1 } +//get event type func (sicl *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) } +//If service name matches,return true or false func (sicl *ServiceInstancesChangedListener) Accept(e ServiceInstancesChangedEvent) bool { return e.ServiceName == sicl.ServiceName } diff --git a/registry/servicediscovery/instance/random/random_service_instance_selector.go b/registry/servicediscovery/instance/random/random_service_instance_selector.go index 1efbbc3fcb..3f8f30dc8e 100644 --- a/registry/servicediscovery/instance/random/random_service_instance_selector.go +++ b/registry/servicediscovery/instance/random/random_service_instance_selector.go @@ -17,19 +17,23 @@ package random +import ( + "math/rand" + "time" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/servicediscovery/instance" - "math/rand" - "time" ) func init() { extension.SetServiceInstanceSelector("random", NewRandomServiceInstanceSelector) } +//the ServiceInstanceSelector implementation based on Random algorithm type RandomServiceInstanceSelector struct { } diff --git a/registry/servicediscovery/instance/random/random_service_instance_selector_test.go b/registry/servicediscovery/instance/random/random_service_instance_selector_test.go index ed4b7838fc..cddeb42c90 100644 --- a/registry/servicediscovery/instance/random/random_service_instance_selector_test.go +++ b/registry/servicediscovery/instance/random/random_service_instance_selector_test.go @@ -17,11 +17,17 @@ package random +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/registry" - "github.com/stretchr/testify/assert" - "testing" ) func TestRandomServiceInstanceSelector_Select(t *testing.T) { diff --git a/registry/servicediscovery/instance/service_instance_selector.go b/registry/servicediscovery/instance/service_instance_selector.go index acacde5617..82fb3458be 100644 --- a/registry/servicediscovery/instance/service_instance_selector.go +++ b/registry/servicediscovery/instance/service_instance_selector.go @@ -23,5 +23,6 @@ import ( ) type ServiceInstanceSelector interface { + //Select an instance of ServiceInstance by the specified ServiceInstance service instances Select(url common.URL, serviceInstances []registry.ServiceInstance) registry.ServiceInstance } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 1734899f8b..8dfa491952 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -20,7 +20,17 @@ package servicediscovery import ( "bytes" "encoding/json" + "strconv" + "strings" + "sync" +) + +import ( cm "github.com/Workiva/go-datastructures/common" + gxset "github.com/dubbogo/gost/container/set" +) + +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" @@ -32,10 +42,6 @@ import ( "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" - gxset "github.com/dubbogo/gost/container/set" - "strconv" - "strings" - "sync" ) const ( @@ -53,14 +59,17 @@ func init() { // 1. when we registry the service, we should create the mapping from service name to application name // 2. when we sub type serviceDiscoveryRegistry struct { - lock sync.RWMutex - url *common.URL - serviceDiscovery registry.ServiceDiscovery - subscribedServices *gxset.HashSet - serviceNameMapping mapping.ServiceNameMapping - metaDataService service.MetadataService - registeredListeners *gxset.HashSet - subscribedURLsSynthesizers []synthesizer.SubscribedURLsSynthesizer + lock sync.RWMutex + url *common.URL + serviceDiscovery registry.ServiceDiscovery + subscribedServices *gxset.HashSet + serviceNameMapping mapping.ServiceNameMapping + metaDataService service.MetadataService + //cache the registered listen + registeredListeners *gxset.HashSet + //all synthesize + subscribedURLsSynthesizers []synthesizer.SubscribedURLsSynthesizer + //cache exported urls, serviceName->revision->[]URL serviceRevisionExportedURLsCache map[string]map[string][]common.URL } @@ -104,18 +113,22 @@ func parseServices(literalServices string) *gxset.HashSet { return set } +//GetServiceDiscovery for get serviceDiscovery of the registry func (s *serviceDiscoveryRegistry) GetServiceDiscovery() registry.ServiceDiscovery { return s.serviceDiscovery } +//GetUrl for get url of the registry func (s *serviceDiscoveryRegistry) GetUrl() common.URL { return *s.url } +//IsAvailable for make sure is't available func (s *serviceDiscoveryRegistry) IsAvailable() bool { return true } +//Destroy for destroy graceful down func (s *serviceDiscoveryRegistry) Destroy() { err := s.serviceDiscovery.Destroy() if err != nil { @@ -149,6 +162,7 @@ func shouldRegister(url common.URL) bool { return false } +//Subscribe for listen the change of services that from the exported url func (s *serviceDiscoveryRegistry) Subscribe(url *common.URL, notify registry.NotifyListener) { if !shouldSubscribe(*url) { return diff --git a/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go index e09dfd6be7..086a26de58 100644 --- a/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go +++ b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer.go @@ -17,19 +17,23 @@ package rest +import ( + "net/url" + "strings" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" - "net/url" - "strings" ) func init() { synthesizer.AddSynthesizer(NewRestSubscribedURLsSynthesizer()) } +//SubscribedURLsSynthesizer implementation for rest protocol type RestSubscribedURLsSynthesizer struct { } diff --git a/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go index 8ad1b50227..b52cc2323d 100644 --- a/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go +++ b/registry/servicediscovery/synthesizer/rest/rest_subscribed_urls_synthesizer_test.go @@ -17,13 +17,19 @@ package rest +import ( + "net/url" + "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/registry" - "github.com/stretchr/testify/assert" - "net/url" - "testing" ) func TestRestSubscribedURLsSynthesizer_Synthesize(t *testing.T) { diff --git a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go index f2d5b99f1c..a7d2f3ee98 100644 --- a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go +++ b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go @@ -23,6 +23,8 @@ import ( ) type SubscribedURLsSynthesizer interface { + //Supports the synthesis of the subscribed url or not Support(subscribedURL *common.URL) bool + //synthesize the subscribed url Synthesize(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL } From 08eb340e8887c45e5b76a48a60cabcf35f422db6 Mon Sep 17 00:00:00 2001 From: flycash Date: Sat, 2 May 2020 21:32:31 +0800 Subject: [PATCH 043/209] Export get BaseConfig --- config/base_config.go | 24 +++++--- config/base_config_test.go | 80 +++++++++++++----------- config/config_loader.go | 104 ++++++++++++++++++++++---------- config/config_loader_test.go | 23 ++++--- config/consumer_config.go | 3 - config/provider_config.go | 2 - config/reference_config_test.go | 32 +++++----- config/remote_config.go | 25 ++++++++ config/service_config_test.go | 16 ++--- registry/nacos/registry.go | 3 +- 10 files changed, 205 insertions(+), 107 deletions(-) create mode 100644 config/remote_config.go diff --git a/config/base_config.go b/config/base_config.go index f58138d2e5..de0f9e7f8e 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -42,7 +42,11 @@ type multiConfiger interface { // BaseConfig is the common configuration for provider and consumer type BaseConfig struct { - ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` + ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` + Remotes map[string]*RemoteConfig `yaml:"remotes" json:"remotes,omitempty"` + // application + ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` + configCenterUrl *common.URL prefix string fatherConfig interface{} @@ -51,6 +55,12 @@ type BaseConfig struct { fileStream *bytes.Buffer } +// GetRemoteConfig will return the remote's config with the name if found +func (c *BaseConfig) GetRemoteConfig(name string) (config *RemoteConfig, ok bool) { + config, ok = c.Remotes[name] + return +} + // startConfigCenter will start the config center. // it will prepare the environment func (c *BaseConfig) startConfigCenter() error { @@ -63,7 +73,7 @@ func (c *BaseConfig) startConfigCenter() error { if c.prepareEnvironment() != nil { return perrors.WithMessagef(err, "start config center error!") } - //c.fresh() + // c.fresh() return err } @@ -101,14 +111,14 @@ func (c *BaseConfig) prepareEnvironment() error { return perrors.WithStack(err) } } - //global config file + // global config file mapContent, err := dynamicConfig.Parser().Parse(content) if err != nil { return perrors.WithStack(err) } config.GetEnvInstance().UpdateExternalConfigMap(mapContent) - //appGroup config file + // appGroup config file if len(appContent) != 0 { appMapConent, err := dynamicConfig.Parser().Parse(appContent) if err != nil { @@ -264,7 +274,7 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC if f.Kind() == reflect.Map { if f.Type().Elem().Kind() == reflect.Ptr { - //initiate config + // initiate config s := reflect.New(f.Type().Elem().Elem()) prefix := s.MethodByName("Prefix").Call(nil)[0].String() for _, pfx := range strings.Split(prefix, "|") { @@ -279,7 +289,7 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } - //iter := f.MapRange() + // iter := f.MapRange() for _, k := range f.MapKeys() { v := f.MapIndex(k) @@ -314,7 +324,7 @@ func (c *BaseConfig) fresh() { } func (c *BaseConfig) freshInternalConfig(config *config.InmemoryConfiguration) { - //reflect to init struct + // reflect to init struct tp := reflect.ValueOf(c.fatherConfig).Elem().Type() initializeStruct(tp, reflect.ValueOf(c.fatherConfig).Elem()) diff --git a/config/base_config_test.go b/config/base_config_test.go index 60eccfb183..9c4b4f903d 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -45,13 +45,15 @@ func Test_refresh(t *testing.T) { father := &ConsumerConfig{ Check: &[]bool{true}[0], - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg2": { Protocol: "mock", @@ -139,13 +141,15 @@ func Test_appExternal_refresh(t *testing.T) { config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ Check: &[]bool{true}[0], - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg2": { Protocol: "mock", @@ -225,13 +229,15 @@ func Test_appExternalWithoutId_refresh(t *testing.T) { config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ Check: &[]bool{true}[0], - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg2": { Protocol: "mock", @@ -310,13 +316,15 @@ func Test_refresh_singleRegistry(t *testing.T) { father := &ConsumerConfig{ Check: &[]bool{true}[0], - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{}, Registry: &RegistryConfig{}, References: map[string]*ReferenceConfig{ @@ -373,13 +381,15 @@ func Test_refreshProvider(t *testing.T) { config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ProviderConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg2": { Protocol: "mock", diff --git a/config/config_loader.go b/config/config_loader.go index 1ed43ededd..8552caef89 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -21,6 +21,7 @@ import ( "fmt" "log" "os" + "sync" "time" ) @@ -37,12 +38,19 @@ import ( ) var ( - consumerConfig *ConsumerConfig - providerConfig *ProviderConfig - metricConfig *MetricConfig - applicationConfig *ApplicationConfig - maxWait = 3 - confRouterFile string + consumerConfig *ConsumerConfig + providerConfig *ProviderConfig + // baseConfig = providerConfig.BaseConfig or consumerConfig + baseConfig *BaseConfig + // baseConfigOnce is used to make sure that we only create it once. + baseConfigOnce sync.Once + + // configAccessMutex is used to make sure that BaseConfig.xxxxConfig will only be created once if needed. + // it should be used combine with double-check to avoid the race condition + configAccessMutex sync.Mutex + + maxWait = 3 + confRouterFile string ) // loaded consumer & provider config from xxx.yml, and log config from xxx.xml @@ -100,12 +108,6 @@ func loadConsumerConfig() { } } - metricConfig = consumerConfig.MetricConfig - applicationConfig = consumerConfig.ApplicationConfig - extension.SetAndInitGlobalDispatcher(consumerConfig.eventDispatcherType) - - extension.SetAndInitGlobalDispatcher(consumerConfig.eventDispatcherType) - checkApplicationName(consumerConfig.ApplicationConfig) if err := configCenterRefreshConsumer(); err != nil { logger.Errorf("[consumer config center refresh] %#v", err) @@ -126,14 +128,14 @@ func loadConsumerConfig() { ref.Implement(rpcService) } - //wait for invoker is available, if wait over default 3s, then panic + // wait for invoker is available, if wait over default 3s, then panic var count int checkok := true for { for _, refconfig := range consumerConfig.References { if (refconfig.Check != nil && *refconfig.Check) || (refconfig.Check == nil && consumerConfig.Check != nil && *consumerConfig.Check) || - (refconfig.Check == nil && consumerConfig.Check == nil) { //default to true + (refconfig.Check == nil && consumerConfig.Check == nil) { // default to true if refconfig.invoker != nil && !refconfig.invoker.IsAvailable() { @@ -178,13 +180,6 @@ func loadProviderConfig() { } } - // so, you should know that the consumer's config will be override - metricConfig = providerConfig.MetricConfig - applicationConfig = providerConfig.ApplicationConfig - extension.SetAndInitGlobalDispatcher(providerConfig.eventDispatcherType) - - extension.SetAndInitGlobalDispatcher(consumerConfig.eventDispatcherType) - checkApplicationName(providerConfig.ApplicationConfig) if err := configCenterRefreshProvider(); err != nil { logger.Errorf("[provider config center refresh] %#v", err) @@ -225,6 +220,9 @@ func Load() { // service config loadProviderConfig() + // common part + extension.SetAndInitGlobalDispatcher(providerConfig.eventDispatcherType) + // init the shutdown callback GracefulShutdownInit() } @@ -241,39 +239,83 @@ func RPCService(service common.RPCService) { // GetMetricConfig find the MetricConfig // if it is nil, create a new one +// we use double-check to reduce race condition +// In general, it will be locked 0 or 1 time. +// So you don't need to worry about the race condition func GetMetricConfig() *MetricConfig { - if metricConfig == nil { - metricConfig = &MetricConfig{} + if GetBaseConfig().MetricConfig == nil { + configAccessMutex.Lock() + defer configAccessMutex.Unlock() + if GetBaseConfig().MetricConfig == nil { + GetBaseConfig().MetricConfig = &MetricConfig{} + } } - return metricConfig + return GetBaseConfig().MetricConfig } // GetApplicationConfig find the application config // if not, we will create one // Usually applicationConfig will be initialized when system start +// we use double-check to reduce race condition +// In general, it will be locked 0 or 1 time. +// So you don't need to worry about the race condition func GetApplicationConfig() *ApplicationConfig { - if applicationConfig == nil { - applicationConfig = &ApplicationConfig{} + if GetBaseConfig().ApplicationConfig == nil { + configAccessMutex.Lock() + defer configAccessMutex.Unlock() + if GetBaseConfig().ApplicationConfig == nil { + GetBaseConfig().ApplicationConfig = &ApplicationConfig{} + } } - return applicationConfig + return GetBaseConfig().ApplicationConfig } // GetProviderConfig find the provider config // if not found, create new one +// we use double-check to reduce race condition +// In general, it will be locked 0 or 1 time. +// So you don't need to worry about the race condition func GetProviderConfig() ProviderConfig { if providerConfig == nil { - logger.Warnf("providerConfig is nil!") - return ProviderConfig{} + logger.Warnf("providerConfig is nil! we will try to create one") + configAccessMutex.Lock() + defer configAccessMutex.Unlock() + if providerConfig == nil { + logger.Warnf("creating empty provider config. You should see this log only once.") + providerConfig = &ProviderConfig{} + } } return *providerConfig } // GetConsumerConfig find the consumer config // if not found, create new one +// we use double-check to reduce race condition +// In general, it will be locked 0 or 1 time. +// So you don't need to worry about the race condition func GetConsumerConfig() ConsumerConfig { if consumerConfig == nil { - logger.Warnf("consumerConfig is nil!") - return ConsumerConfig{} + logger.Warnf("consumerConfig is nil! we will try to create one") + configAccessMutex.Lock() + defer configAccessMutex.Unlock() + if consumerConfig == nil { + logger.Warnf("creating empty consumer config. You should see this log only once.") + consumerConfig = &ConsumerConfig{} + } } return *consumerConfig } + +func GetBaseConfig() *BaseConfig { + if baseConfig == nil { + baseConfigOnce.Do(func() { + baseConfig = &BaseConfig{ + MetricConfig: &MetricConfig{}, + ConfigCenterConfig: &ConfigCenterConfig{}, + Remotes: make(map[string]*RemoteConfig, 0), + ApplicationConfig: &ApplicationConfig{}, + } + }) + } + return baseConfig +} diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 0192b4c8a0..f653f5e759 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -235,16 +235,25 @@ func TestConfigLoaderWithConfigCenterSingleRegistry(t *testing.T) { } +func TestGetBaseConfig(t *testing.T) { + bc := GetBaseConfig() + assert.NotNil(t, bc) + _, found := bc.GetRemoteConfig("mock") + assert.False(t, found) +} + // mockInitProviderWithSingleRegistry will init a mocked providerConfig func mockInitProviderWithSingleRegistry() { providerConfig = &ProviderConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "1.0.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "1.0.0", + Owner: "dubbo", + Environment: "test"}, + }, Registry: &RegistryConfig{ Address: "mock://127.0.0.1:2181", Username: "user1", diff --git a/config/consumer_config.go b/config/consumer_config.go index debcd79fa2..76476511fb 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -42,9 +42,6 @@ import ( type ConsumerConfig struct { BaseConfig `yaml:",inline"` Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - // application - ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` - // client Connect_Timeout string `default:"100ms" yaml:"connect_timeout" json:"connect_timeout,omitempty" property:"connect_timeout"` ConnectTimeout time.Duration diff --git a/config/provider_config.go b/config/provider_config.go index 7956991745..bdb9bd2f96 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -43,8 +43,6 @@ type ProviderConfig struct { ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` // metadata-report MetadataReportConfig *MetadataReportConfig `yaml:"metadata_report" json:"metadata_report,omitempty" property:"metadata_report"` - - ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` diff --git a/config/reference_config_test.go b/config/reference_config_test.go index 7a65e55f09..faaa461a75 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -38,13 +38,15 @@ var regProtocol protocol.Protocol func doInitConsumer() { consumerConfig = &ConsumerConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg1": { Protocol: "mock", @@ -135,13 +137,15 @@ func doInitConsumerAsync() { func doInitConsumerWithSingleRegistry() { consumerConfig = &ConsumerConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registry: &RegistryConfig{ Address: "mock://27.0.0.1:2181", Username: "user1", diff --git a/config/remote_config.go b/config/remote_config.go new file mode 100644 index 0000000000..f126afc90f --- /dev/null +++ b/config/remote_config.go @@ -0,0 +1,25 @@ +/* + * 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 config + +type RemoteConfig struct { + Address string `yaml:"address" json:"address,omitempty"` + Params map[string]string `yaml:"params" json:"address,omitempty"` +} + + diff --git a/config/service_config_test.go b/config/service_config_test.go index 387e3ced7a..eff9735b3d 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -33,13 +33,15 @@ import ( func doInitProvider() { providerConfig = &ProviderConfig{ - ApplicationConfig: &ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "2.6.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: BaseConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + }, Registries: map[string]*RegistryConfig{ "shanghai_reg1": { Protocol: "mock", diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index a436b85064..a8d4916c6e 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -140,7 +140,7 @@ func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) return NewNacosListener(*conf, nr.namingClient) } -//subscribe from registry +// subscribe from registry func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { for { if !nr.IsAvailable() { @@ -179,6 +179,7 @@ func (nr *nacosRegistry) GetUrl() common.URL { } func (nr *nacosRegistry) IsAvailable() bool { + // TODO return true } From bcda4debff9c4bdeeedfd33532d514831313e001 Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Sat, 2 May 2020 22:55:59 +0800 Subject: [PATCH 044/209] fix review comments --- registry/servicediscovery/service_discovery_registry.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 8dfa491952..1cb36f6c73 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -361,17 +361,17 @@ func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registr } func (s *serviceDiscoveryRegistry) prepareServiceRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { - s.lock.Lock() // 1. expunge stale s.expungeStaleRevisionExportedURLs(serviceInstances) // 2. Initialize s.initRevisionExportedURLs(serviceInstances) - s.lock.Unlock() } func (s *serviceDiscoveryRegistry) expungeStaleRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { serviceName := serviceInstances[0].GetServiceName() + s.lock.Lock() revisionExportedURLsMap, exist := s.serviceRevisionExportedURLsCache[serviceName] + s.lock.Unlock() if !exist { return } @@ -382,7 +382,7 @@ func (s *serviceDiscoveryRegistry) expungeStaleRevisionExportedURLs(serviceInsta currentRevision := gxset.NewSet() for _, s := range serviceInstances { rv := getExportedServicesRevision(s) - if len(rv) != 0 { + if len(rv) > 0 { currentRevision.Add(rv) } } @@ -438,7 +438,9 @@ func (s *serviceDiscoveryRegistry) initRevisionExportedURLsByInst(serviceInstanc } serviceName := serviceInstance.GetServiceName() revision := getExportedServicesRevision(serviceInstance) + s.lock.Lock() revisionExportedURLsMap := s.serviceRevisionExportedURLsCache[serviceName] + s.lock.Unlock() revisionExportedURLs := revisionExportedURLsMap[revision] firstGet := false if revisionExportedURLs == nil || len(revisionExportedURLs) == 0 { From 4b8b4d7a27d4e4c62be5b782e16e3d62e5c635b6 Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 4 May 2020 21:21:18 +0800 Subject: [PATCH 045/209] Refactor service-discovery --- cluster/directory/base_directory.go | 14 ---- common/extension/service_discovery.go | 19 +++-- config/base_config.go | 12 ++- config/base_config_test.go | 2 +- config/config_loader.go | 1 + config/provider_config.go | 18 ++--- config/reference_config.go | 2 + config/remote_config.go | 19 ++++- config/remote_config_test.go | 41 ++++++++++ config/router_config.go | 12 ++- config/router_config_test.go | 13 --- config/service_config_test.go | 1 + config/service_discovery_config.go | 30 +++++++ .../exporter/configurable/exporter_test.go | 16 ++-- registry/directory/directory.go | 18 ++--- registry/directory/directory_test.go | 6 +- registry/inmemory/service_discovery.go | 3 +- registry/inmemory/service_discovery_test.go | 2 +- registry/nacos/registry.go | 80 ++++++++++++++++--- registry/nacos/service_discovery.go | 69 ++++++++++++++-- registry/nacos/service_discovery_test.go | 32 +++++--- registry/protocol/protocol_test.go | 9 ++- .../service_discovery_registry.go | 2 +- .../nacos/builder.go | 58 +++----------- remoting/nacos/builder_test.go | 50 ++++++++++++ 25 files changed, 375 insertions(+), 154 deletions(-) create mode 100644 config/remote_config_test.go create mode 100644 config/service_discovery_config.go rename registry/nacos/base_registry.go => remoting/nacos/builder.go (55%) create mode 100644 remoting/nacos/builder_test.go diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index 75d9ef2656..a3e207f302 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -22,7 +22,6 @@ import ( ) import ( - "github.com/dubbogo/gost/container/set" "go.uber.org/atomic" ) @@ -35,8 +34,6 @@ import ( "github.com/apache/dubbo-go/common/logger" ) -var routerURLSet = gxset.NewSet() - // BaseDirectory Abstract implementation of Directory: Invoker list returned from this Directory's list method have been filtered by Routers type BaseDirectory struct { url *common.URL @@ -120,14 +117,3 @@ func (dir *BaseDirectory) Destroy(doDestroy func()) { func (dir *BaseDirectory) IsAvailable() bool { return !dir.destroyed.Load() } - -// GetRouterURLSet Return router URL -func GetRouterURLSet() *gxset.HashSet { - return routerURLSet -} - -// AddRouterURLSet Add router URL -// Router URL will init in config/config_loader.go -func AddRouterURLSet(url *common.URL) { - routerURLSet.Add(url) -} diff --git a/common/extension/service_discovery.go b/common/extension/service_discovery.go index 488d94ebf1..f820721515 100644 --- a/common/extension/service_discovery.go +++ b/common/extension/service_discovery.go @@ -18,28 +18,31 @@ package extension import ( - "github.com/apache/dubbo-go/registry" perrors "github.com/pkg/errors" ) import ( - "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/registry" ) var ( - discoveryCreatorMap = make(map[string]func(url *common.URL) (registry.ServiceDiscovery, error), 4) + discoveryCreatorMap = make(map[string]func(name string) (registry.ServiceDiscovery, error), 4) ) // SetServiceDiscovery will store the creator and name -func SetServiceDiscovery(name string, creator func(url *common.URL) (registry.ServiceDiscovery, error)) { - discoveryCreatorMap[name] = creator +// protocol indicate the implementation, like nacos +// the name like nacos-1... +func SetServiceDiscovery(protocol string, creator func(name string) (registry.ServiceDiscovery, error)) { + discoveryCreatorMap[protocol] = creator } // GetServiceDiscovery will return the registry.ServiceDiscovery +// protocol indicate the implementation, like nacos +// the name like nacos-1... // if not found, or initialize instance failed, it will return error. -func GetServiceDiscovery(name string, url *common.URL) (registry.ServiceDiscovery, error) { - creator, ok := discoveryCreatorMap[name] +func GetServiceDiscovery(protocol string, name string) (registry.ServiceDiscovery, error) { + creator, ok := discoveryCreatorMap[protocol] if !ok { return nil, perrors.New("Could not find the service discovery with name: " + name) } - return creator(url) + return creator(name) } diff --git a/config/base_config.go b/config/base_config.go index de0f9e7f8e..d95ea27ee6 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -42,9 +42,10 @@ type multiConfiger interface { // BaseConfig is the common configuration for provider and consumer type BaseConfig struct { - ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` - Remotes map[string]*RemoteConfig `yaml:"remotes" json:"remotes,omitempty"` - // application + ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` + Remotes map[string]*RemoteConfig `yaml:"remotes" json:"remotes,omitempty"` + ServiceDiscoveries map[string]*ServiceDiscoveryConfig `yaml:"service_discovery" json:"service_discovery,omitempty"` + // application config ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` configCenterUrl *common.URL @@ -55,6 +56,11 @@ type BaseConfig struct { fileStream *bytes.Buffer } +func (c *BaseConfig) GetServiceDiscoveries(name string) (config *ServiceDiscoveryConfig, ok bool) { + config, ok = c.ServiceDiscoveries[name] + return +} + // GetRemoteConfig will return the remote's config with the name if found func (c *BaseConfig) GetRemoteConfig(name string) (config *RemoteConfig, ok bool) { config, ok = c.Remotes[name] diff --git a/config/base_config_test.go b/config/base_config_test.go index 9c4b4f903d..4a4b2b06b9 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -482,7 +482,7 @@ func Test_initializeStruct(t *testing.T) { reflect.ValueOf(consumerConfig).Elem().Set(v.Elem()) assert.Condition(t, func() (success bool) { - return consumerConfig.ApplicationConfig != nil + return consumerConfig.Registry != nil }) assert.Condition(t, func() (success bool) { return consumerConfig.Registries != nil diff --git a/config/config_loader.go b/config/config_loader.go index 8552caef89..0922a7a285 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -314,6 +314,7 @@ func GetBaseConfig() *BaseConfig { ConfigCenterConfig: &ConfigCenterConfig{}, Remotes: make(map[string]*RemoteConfig, 0), ApplicationConfig: &ApplicationConfig{}, + ServiceDiscoveries: make(map[string]*ServiceDiscoveryConfig, 0), } }) } diff --git a/config/provider_config.go b/config/provider_config.go index bdb9bd2f96..81f20e864d 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -42,15 +42,15 @@ type ProviderConfig struct { Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` // metadata-report - MetadataReportConfig *MetadataReportConfig `yaml:"metadata_report" json:"metadata_report,omitempty" property:"metadata_report"` - Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` - Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` - Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"` - ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" ` - FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" ` - ShutdownConfig *ShutdownConfig `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf" ` - ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` + MetadataReportConfig *MetadataReportConfig `yaml:"metadata_report" json:"metadata_report,omitempty" property:"metadata_report"` + Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` + Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` + Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` + Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"` + ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" ` + FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" ` + ShutdownConfig *ShutdownConfig `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf" ` + ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` } // UnmarshalYAML ... diff --git a/config/reference_config.go b/config/reference_config.go index 3710cbc4bc..f343a9a236 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -144,6 +144,8 @@ func (c *ReferenceConfig) Refer(_ interface{}) { regUrl = u } } + + // TODO(decouple from directory, config should not depend on directory module) if regUrl != nil { cluster := extension.GetCluster("registryAware") c.invoker = cluster.Join(directory.NewStaticDirectory(invokers)) diff --git a/config/remote_config.go b/config/remote_config.go index f126afc90f..ed9dab37a4 100644 --- a/config/remote_config.go +++ b/config/remote_config.go @@ -17,9 +17,22 @@ package config +import ( + "time" +) + type RemoteConfig struct { - Address string `yaml:"address" json:"address,omitempty"` - Params map[string]string `yaml:"params" json:"address,omitempty"` + Address string `yaml:"address" json:"address,omitempty"` + Timeout time.Duration `default:"10s" yaml:"timeout" json:"timeout,omitempty"` + Params map[string]string `yaml:"params" json:"address,omitempty"` } - +// GetParam will return the value of the key. If not found, def will be return; +// def => default value +func (rc *RemoteConfig) GetParam(key string, def string) string { + param, ok := rc.Params[key] + if !ok { + return def + } + return param +} diff --git a/config/remote_config_test.go b/config/remote_config_test.go new file mode 100644 index 0000000000..99facb7dda --- /dev/null +++ b/config/remote_config_test.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 config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRemoteConfig_GetParam(t *testing.T) { + rc := &RemoteConfig{ + Params: make(map[string]string, 1), + } + + def := "default value" + key := "key" + value := rc.GetParam(key, def) + assert.Equal(t, def, value) + + actualVal := "actual value" + rc.Params[key] = actualVal + + value = rc.GetParam(key, def) + assert.Equal(t, actualVal, value) +} diff --git a/config/router_config.go b/config/router_config.go index 0670ee9c20..16943d96be 100644 --- a/config/router_config.go +++ b/config/router_config.go @@ -18,16 +18,20 @@ package config import ( + gxset "github.com/dubbogo/gost/container/set" perrors "github.com/pkg/errors" ) import ( - "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/yaml" ) +var ( + routerURLSet = gxset.NewSet() +) + // RouterInit Load config file to init router config func RouterInit(confRouterFile string) error { fileRouterFactories := extension.GetFileRouterFactories() @@ -40,10 +44,14 @@ func RouterInit(confRouterFile string) error { r, e := factory.NewFileRouter(bytes) if e == nil { url := r.URL() - directory.AddRouterURLSet(&url) + routerURLSet.Add(url) return nil } logger.Warnf("router config type %s create fail {%v}\n", k, e) } return perrors.Errorf("no file router exists for parse %s , implement router.FIleRouterFactory please.", confRouterFile) } + +func GetRouterURLSet() *gxset.HashSet { + return routerURLSet +} diff --git a/config/router_config_test.go b/config/router_config_test.go index 2f0a38b2fd..bf189b600f 100644 --- a/config/router_config_test.go +++ b/config/router_config_test.go @@ -27,7 +27,6 @@ import ( ) import ( - "github.com/apache/dubbo-go/cluster/directory" _ "github.com/apache/dubbo-go/cluster/router/condition" ) @@ -53,15 +52,3 @@ func TestString(t *testing.T) { assert.Equal(t, n2[0], "a1") assert.Equal(t, n2[1], "") } - -func TestRouterInit(t *testing.T) { - errPro := RouterInit(errorTestYML) - assert.Error(t, errPro) - - assert.Equal(t, 0, directory.GetRouterURLSet().Size()) - - errPro = RouterInit(testYML) - assert.NoError(t, errPro) - - assert.Equal(t, 1, directory.GetRouterURLSet().Size()) -} diff --git a/config/service_config_test.go b/config/service_config_test.go index eff9735b3d..949566f82a 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -145,6 +145,7 @@ func Test_Export(t *testing.T) { for i := range providerConfig.Services { service := providerConfig.Services[i] service.Implement(&MockService{}) + service.Protocols = providerConfig.Protocols service.Export() } providerConfig = nil diff --git a/config/service_discovery_config.go b/config/service_discovery_config.go new file mode 100644 index 0000000000..343c366ec5 --- /dev/null +++ b/config/service_discovery_config.go @@ -0,0 +1,30 @@ +/* + * 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 config + +// ServiceDiscoveryConfig will be used to create +type ServiceDiscoveryConfig struct { + // Protocol indicate which implementation will be used. + // for example, if the Protocol is nacos, it means that we will use nacosServiceDiscovery + Protocol string + // Group, usually you don't need to config this field. + // you can use this to do some isolation + Group string + // RemoteRef is the reference point to RemoteConfig which will be used to create remotes instances. + RemoteRef string +} diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index 220ef71dac..364169b317 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -66,13 +66,15 @@ func TestConfigurableExporter(t *testing.T) { // mockInitProviderWithSingleRegistry will init a mocked providerConfig func mockInitProviderWithSingleRegistry() { providerConfig := &config.ProviderConfig{ - ApplicationConfig: &config.ApplicationConfig{ - Organization: "dubbo_org", - Name: "dubbo", - Module: "module", - Version: "1.0.0", - Owner: "dubbo", - Environment: "test"}, + BaseConfig: config.BaseConfig{ + ApplicationConfig: &config.ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "1.0.0", + Owner: "dubbo", + Environment: "test"}, + }, Registry: &config.RegistryConfig{ Address: "mock://127.0.0.1:2181", Username: "user1", diff --git a/registry/directory/directory.go b/registry/directory/directory.go index 552aa57061..d689bc6237 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -52,7 +52,7 @@ type RegistryDirectory struct { listenerLock sync.Mutex serviceType string registry registry.Registry - cacheInvokersMap *sync.Map //use sync.map + cacheInvokersMap *sync.Map // use sync.map cacheOriginUrl *common.URL configurators []config_center.Configurator consumerConfigurationListener *consumerConfigurationListener @@ -79,7 +79,7 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry) (cluster. return dir, nil } -//subscribe from registry +// subscribe from registry func (dir *RegistryDirectory) subscribe(url *common.URL) { dir.consumerConfigurationListener.addNotifyListener(dir) dir.referenceConfigurationListener = newReferenceConfigurationListener(dir, url) @@ -105,15 +105,15 @@ func (dir *RegistryDirectory) refreshInvokers(res *registry.ServiceEvent) { url *common.URL oldInvoker protocol.Invoker = nil ) - //judge is override or others + // judge is override or others if res != nil { url = &res.Service - //1.for override url in 2.6.x + // 1.for override url in 2.6.x if url.Protocol == constant.OVERRIDE_PROTOCOL || url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY) == constant.CONFIGURATORS_CATEGORY { dir.configurators = append(dir.configurators, extension.GetDefaultConfigurator(url)) url = nil - } else if url.Protocol == constant.ROUTER_PROTOCOL || //2.for router + } else if url.Protocol == constant.ROUTER_PROTOCOL || // 2.for router url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY) == constant.ROUTER_CATEGORY { url = nil @@ -123,7 +123,7 @@ func (dir *RegistryDirectory) refreshInvokers(res *registry.ServiceEvent) { logger.Infof("selector add service url{%s}", res.Service) var urls []*common.URL - for _, v := range directory.GetRouterURLSet().Values() { + for _, v := range config.GetRouterURLSet().Values() { urls = append(urls, v.(*common.URL)) } @@ -171,7 +171,7 @@ func (dir *RegistryDirectory) toGroupInvokers() []protocol.Invoker { } } if len(groupInvokersMap) == 1 { - //len is 1 it means no group setting ,so do not need cluster again + // len is 1 it means no group setting ,so do not need cluster again for _, invokers := range groupInvokersMap { groupInvokersList = invokers } @@ -211,7 +211,7 @@ func (dir *RegistryDirectory) cacheInvoker(url *common.URL) protocol.Invoker { logger.Error("URL is nil ,pls check if service url is subscribe successfully!") return nil } - //check the url's protocol is equal to the protocol which is configured in reference config or referenceUrl is not care about protocol + // check the url's protocol is equal to the protocol which is configured in reference config or referenceUrl is not care about protocol if url.Protocol == referenceUrl.Protocol || referenceUrl.Protocol == "" { newUrl := common.MergeUrl(url, referenceUrl) dir.overrideUrl(newUrl) @@ -259,7 +259,7 @@ func (dir *RegistryDirectory) IsAvailable() bool { } func (dir *RegistryDirectory) Destroy() { - //TODO:unregister & unsubscribe + // TODO:unregister & unsubscribe dir.BaseDirectory.Destroy(func() { invokers := dir.cacheInvokers dir.cacheInvokers = []protocol.Invoker{} diff --git a/registry/directory/directory_test.go b/registry/directory/directory_test.go index f1d5ce434a..1e3d611bf7 100644 --- a/registry/directory/directory_test.go +++ b/registry/directory/directory_test.go @@ -43,7 +43,11 @@ import ( ) func init() { - config.SetConsumerConfig(config.ConsumerConfig{ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}}) + config.SetConsumerConfig(config.ConsumerConfig{ + BaseConfig: config.BaseConfig{ + ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}, + }, + }) } func TestSubscribe(t *testing.T) { diff --git a/registry/inmemory/service_discovery.go b/registry/inmemory/service_discovery.go index 3dac35cd38..f7c3ef3bb5 100644 --- a/registry/inmemory/service_discovery.go +++ b/registry/inmemory/service_discovery.go @@ -23,7 +23,6 @@ import ( ) import ( - "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/registry" ) @@ -39,7 +38,7 @@ func init() { listeners: make([]*registry.ServiceInstancesChangedListener, 0, 2), } - extension.SetServiceDiscovery(name, func(url *common.URL) (discovery registry.ServiceDiscovery, err error) { + extension.SetServiceDiscovery(name, func(name string) (discovery registry.ServiceDiscovery, err error) { return instance, nil }) } diff --git a/registry/inmemory/service_discovery_test.go b/registry/inmemory/service_discovery_test.go index a934dbabff..fac4699913 100644 --- a/registry/inmemory/service_discovery_test.go +++ b/registry/inmemory/service_discovery_test.go @@ -31,7 +31,7 @@ import ( ) func TestInMemoryServiceDiscovery(t *testing.T) { - discovery, _ := extension.GetServiceDiscovery(name, nil) + discovery, _ := extension.GetServiceDiscovery(name, "in") serviceName := "my-service" err := discovery.Register(®istry.DefaultServiceInstance{ ServiceName: serviceName, diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index a8d4916c6e..61a0fee8f6 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -19,9 +19,14 @@ package nacos import ( "bytes" + "net" "strconv" "strings" "time" + + "github.com/nacos-group/nacos-sdk-go/clients" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" + nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" ) import ( @@ -43,7 +48,7 @@ var ( ) const ( - //RegistryConnDelay registry connection delay + // RegistryConnDelay registry connection delay RegistryConnDelay = 3 ) @@ -53,18 +58,8 @@ func init() { } type nacosRegistry struct { - nacosBaseRegistry -} - -// newNacosRegistry will create an instance -func newNacosRegistry(url *common.URL) (registry.Registry, error) { - base, err := newBaseRegistry(url) - if err != nil { - return nil, perrors.WithStack(err) - } - return &nacosRegistry{ - base, - }, nil + *common.URL + namingClient naming_client.INamingClient } func getCategory(url common.URL) string { @@ -186,3 +181,62 @@ func (nr *nacosRegistry) IsAvailable() bool { func (nr *nacosRegistry) Destroy() { return } + +// newNacosRegistry will create new instance +func newNacosRegistry(url *common.URL) (registry.Registry, error) { + nacosConfig, err := getNacosConfig(url) + if err != nil { + return &nacosRegistry{}, err + } + client, err := clients.CreateNamingClient(nacosConfig) + if err != nil { + return &nacosRegistry{}, err + } + registry := &nacosRegistry{ + URL: url, + namingClient: client, + } + return registry, nil +} + +// getNacosConfig will return the nacos config +// TODO support RemoteRef +func getNacosConfig(url *common.URL) (map[string]interface{}, error) { + if url == nil { + return nil, perrors.New("url is empty!") + } + if len(url.Location) == 0 { + return nil, perrors.New("url.location is empty!") + } + configMap := make(map[string]interface{}, 2) + + addresses := strings.Split(url.Location, ",") + serverConfigs := make([]nacosConstant.ServerConfig, 0, len(addresses)) + for _, addr := range addresses { + ip, portStr, err := net.SplitHostPort(addr) + if err != nil { + return nil, perrors.WithMessagef(err, "split [%s] ", addr) + } + port, _ := strconv.Atoi(portStr) + serverConfigs = append(serverConfigs, nacosConstant.ServerConfig{ + IpAddr: ip, + Port: uint64(port), + }) + } + configMap["serverConfigs"] = serverConfigs + + var clientConfig nacosConstant.ClientConfig + timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) + if err != nil { + return nil, err + } + clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000) + clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs + clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") + clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") + clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") + clientConfig.NotLoadCacheAtStart = true + configMap["clientConfig"] = clientConfig + + return configMap, nil +} diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index fbd84ac44d..e9230195f6 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -18,15 +18,21 @@ package nacos import ( + "fmt" + "sync" + "github.com/dubbogo/gost/container/set" "github.com/dubbogo/gost/page" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" perrors "github.com/pkg/errors" + + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/remoting/nacos" ) 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" @@ -47,8 +53,12 @@ func init() { // There is a problem, the go client for nacos does not support the id field. // we will use the metadata to store the id of ServiceInstance type nacosServiceDiscovery struct { - nacosBaseRegistry group string + // descriptor is a short string about the basic information of this instance + descriptor string + + // namingClient is the Nacos' client + namingClient naming_client.INamingClient } // Destroy will close the service discovery. @@ -271,15 +281,58 @@ func (n *nacosServiceDiscovery) toDeregisterInstance(instance registry.ServiceIn } } -// toDeregisterInstance will create new service discovery instance -func newNacosServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { +func (n *nacosServiceDiscovery) String() string { + return n.descriptor +} + +var ( + // 16 would be enough. We won't use concurrentMap because in most cases, there are not race condition + instanceMap = make(map[string]registry.ServiceDiscovery, 16) + initLock sync.Mutex +) + +// newNacosServiceDiscovery will create new service discovery instance +// use double-check pattern to reduce race condition +func newNacosServiceDiscovery(name string) (registry.ServiceDiscovery, error) { + + instance, ok := instanceMap[name] + if ok { + return instance, nil + } + + initLock.Lock() + defer initLock.Unlock() - base, err := newBaseRegistry(url) + // double check + instance, ok = instanceMap[name] + if ok { + return instance, nil + } + + sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(name) + if !ok || len(sdc.RemoteRef) == 0 { + return nil, perrors.New("could not init the instance because the config is invalid") + } + + remoteConfig, ok := config.GetBaseConfig().GetRemoteConfig(sdc.RemoteRef) + if !ok { + return nil, perrors.New("could not find the remote config for name: " + sdc.RemoteRef) + } + group := sdc.Group + if len(group) == 0 { + group = defaultGroup + } + + client, err := nacos.NewNacosClient(remoteConfig) if err != nil { - return nil, perrors.WithStack(err) + return nil, perrors.WithMessage(err, "create nacos client failed.") } + + descriptor := fmt.Sprintf("nacos-service-discovery[%s]", remoteConfig.Address) + return &nacosServiceDiscovery{ - nacosBaseRegistry: base, - group: url.GetParam(constant.NACOS_GROUP, defaultGroup), + group: group, + namingClient: client, + descriptor: descriptor, }, nil } diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 0ac46cb9a2..b2a4fa53cd 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -18,8 +18,10 @@ package nacos import ( - "strconv" "testing" + "time" + + "github.com/apache/dubbo-go/config" ) import ( @@ -27,7 +29,6 @@ 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/observer" @@ -35,8 +36,13 @@ import ( "github.com/apache/dubbo-go/registry" ) +var ( + testName = "test" +) + func TestNacosServiceDiscovery_Destroy(t *testing.T) { - serviceDiscovery, err := extension.GetServiceDiscovery(constant.NACOS_KEY, mockUrl()) + prepareData() + serviceDiscovery, err := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) assert.Nil(t, err) assert.NotNil(t, serviceDiscovery) err = serviceDiscovery.Destroy() @@ -45,7 +51,7 @@ func TestNacosServiceDiscovery_Destroy(t *testing.T) { } func TestNacosServiceDiscovery_CRUD(t *testing.T) { - + prepareData() extension.SetEventDispatcher("mock", func() observer.EventDispatcher { return &dispatcher.MockEventDispatcher{} }) @@ -68,7 +74,7 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { // clean data - serviceDiscovry, _ := extension.GetServiceDiscovery(constant.NACOS_KEY, mockUrl()) + serviceDiscovry, _ := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) // clean data for local test serviceDiscovry.Unregister(®istry.DefaultServiceInstance{ @@ -121,11 +127,19 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { } func TestNacosServiceDiscovery_GetDefaultPageSize(t *testing.T) { - serviceDiscovry, _ := extension.GetServiceDiscovery(constant.NACOS_KEY, mockUrl()) + prepareData() + serviceDiscovry, _ := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) assert.Equal(t, registry.DefaultPageSize, serviceDiscovry.GetDefaultPageSize()) } -func mockUrl() *common.URL { - regurl, _ := common.NewURL("registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) - return ®url +func prepareData() { + config.GetBaseConfig().ServiceDiscoveries[testName] = &config.ServiceDiscoveryConfig{ + Protocol: "nacos", + RemoteRef: testName, + } + + config.GetBaseConfig().Remotes[testName] = &config.RemoteConfig{ + Address: "console.nacos.io:80", + Timeout: 10 * time.Second, + } } diff --git a/registry/protocol/protocol_test.go b/registry/protocol/protocol_test.go index cee2a6a625..6adc0fc7d7 100644 --- a/registry/protocol/protocol_test.go +++ b/registry/protocol/protocol_test.go @@ -42,7 +42,9 @@ import ( ) func init() { - config.SetProviderConfig(config.ProviderConfig{ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}}) + config.SetProviderConfig(config.ProviderConfig{BaseConfig: config.BaseConfig{ + ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}, + }}) } func referNormal(t *testing.T, regProtocol *registryProtocol) { @@ -66,8 +68,9 @@ func referNormal(t *testing.T, regProtocol *registryProtocol) { func TestRefer(t *testing.T) { config.SetConsumerConfig( - config.ConsumerConfig{ - ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}}) + config.ConsumerConfig{BaseConfig: config.BaseConfig{ + ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}, + }}) regProtocol := newRegistryProtocol() referNormal(t, regProtocol) } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 1734899f8b..c110eb2282 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -87,7 +87,7 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { } func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { - return extension.GetServiceDiscovery(url.Protocol, url) + return extension.GetServiceDiscovery(url.Protocol, "TODO") } func parseServices(literalServices string) *gxset.HashSet { diff --git a/registry/nacos/base_registry.go b/remoting/nacos/builder.go similarity index 55% rename from registry/nacos/base_registry.go rename to remoting/nacos/builder.go index 63f4999675..578fef49ea 100644 --- a/registry/nacos/base_registry.go +++ b/remoting/nacos/builder.go @@ -21,56 +21,23 @@ import ( "net" "strconv" "strings" - "time" -) -import ( "github.com/nacos-group/nacos-sdk-go/clients" "github.com/nacos-group/nacos-sdk-go/clients/naming_client" nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" perrors "github.com/pkg/errors" -) -import ( - "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/config" ) -// baseRegistry is the parent of both interface-level registry -// and service discovery(related to application-level registry) -type nacosBaseRegistry struct { - *common.URL - namingClient naming_client.INamingClient -} - -// newBaseRegistry will create new instance -func newBaseRegistry(url *common.URL) (nacosBaseRegistry, error) { - nacosConfig, err := getNacosConfig(url) - if err != nil { - return nacosBaseRegistry{}, err - } - client, err := clients.CreateNamingClient(nacosConfig) - if err != nil { - return nacosBaseRegistry{}, err - } - registry := nacosBaseRegistry{ - URL: url, - namingClient: client, - } - return registry, nil -} - -// getNacosConfig will return the nacos config -func getNacosConfig(url *common.URL) (map[string]interface{}, error) { - if url == nil { - return nil, perrors.New("url is empty!") - } - if len(url.Location) == 0 { - return nil, perrors.New("url.location is empty!") +func NewNacosClient(rc *config.RemoteConfig) (naming_client.INamingClient, error) { + if len(rc.Address) == 0 { + return nil, perrors.New("nacos address is empty!") } configMap := make(map[string]interface{}, 2) - addresses := strings.Split(url.Location, ",") + addresses := strings.Split(rc.Address, ",") serverConfigs := make([]nacosConstant.ServerConfig, 0, len(addresses)) for _, addr := range addresses { ip, portStr, err := net.SplitHostPort(addr) @@ -86,17 +53,14 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { configMap["serverConfigs"] = serverConfigs var clientConfig nacosConstant.ClientConfig - timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) - if err != nil { - return nil, err - } - clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000) + timeout := rc.Timeout + clientConfig.TimeoutMs = uint64(timeout.Nanoseconds() / constant.MsToNanoRate) clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs - clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") - clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") - clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") + clientConfig.CacheDir = rc.GetParam(constant.NACOS_CACHE_DIR_KEY, "") + clientConfig.LogDir = rc.GetParam(constant.NACOS_LOG_DIR_KEY, "") + clientConfig.Endpoint = rc.GetParam(constant.NACOS_ENDPOINT, "") clientConfig.NotLoadCacheAtStart = true configMap["clientConfig"] = clientConfig - return configMap, nil + return clients.CreateNamingClient(configMap) } diff --git a/remoting/nacos/builder_test.go b/remoting/nacos/builder_test.go new file mode 100644 index 0000000000..bbfadef71b --- /dev/null +++ b/remoting/nacos/builder_test.go @@ -0,0 +1,50 @@ +/* + * 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 nacos + +import ( + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/config" +) + +func TestNewNacosClient(t *testing.T) { + rc := &config.RemoteConfig{} + client, err := NewNacosClient(rc) + + // address is nil + assert.NotNil(t, err) + + rc.Address = "console.nacos.io:80:123" + client, err = NewNacosClient(rc) + // invalid address + assert.NotNil(t, err) + + rc.Address = "console.nacos.io:80" + rc.Timeout = 10 * time.Second + client, err = NewNacosClient(rc) + assert.NotNil(t, client) + assert.Nil(t, err) +} From 62b37872460a257f38c179d9ba9200a05d7a45cd Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 4 May 2020 23:08:00 +0800 Subject: [PATCH 046/209] add interface for unregister and unsubscribe --- registry/base_registry.go | 11 +++++++++++ registry/consul/registry.go | 7 ++++++- registry/consul/registry_test.go | 2 +- registry/mock_registry.go | 11 +++++++++++ registry/nacos/registry.go | 11 +++++++++++ registry/registry.go | 6 ++++++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 3e1bddf233..0b87a54d7d 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -154,6 +154,12 @@ func (r *BaseRegistry) Register(conf common.URL) error { return nil } +// UnRegister +func (r *BaseRegistry) UnRegister(conf common.URL) error { + + return nil +} + // service is for getting service path stored in url func (r *BaseRegistry) service(c common.URL) string { return url.QueryEscape(c.Service()) @@ -358,6 +364,11 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } } +// UnSubscribe : +func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { + +} + // closeRegisters close and remove registry client and reset services map func (r *BaseRegistry) closeRegisters() { logger.Infof("begin to close provider client") diff --git a/registry/consul/registry.go b/registry/consul/registry.go index c5b8510a6c..415bf42860 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -95,7 +95,7 @@ func (r *consulRegistry) register(url common.URL) error { return r.client.Agent().ServiceRegister(service) } -func (r *consulRegistry) Unregister(url common.URL) error { +func (r *consulRegistry) UnRegister(url common.URL) error { var err error role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) @@ -119,6 +119,11 @@ func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.Noti } } +// UnSubscribe : +func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { + +} + func (r *consulRegistry) subscribe(url *common.URL, notifyListener registry.NotifyListener) { for { if !r.IsAvailable() { diff --git a/registry/consul/registry_test.go b/registry/consul/registry_test.go index bb6842cd8f..94718f5ab6 100644 --- a/registry/consul/registry_test.go +++ b/registry/consul/registry_test.go @@ -44,7 +44,7 @@ func (suite *consulRegistryTestSuite) testRegister() { func (suite *consulRegistryTestSuite) testUnregister() { consulProviderRegistry, _ := suite.providerRegistry.(*consulRegistry) - err := consulProviderRegistry.Unregister(suite.providerUrl) + err := consulProviderRegistry.UnRegister(suite.providerUrl) assert.NoError(suite.t, err) } diff --git a/registry/mock_registry.go b/registry/mock_registry.go index 9591928eeb..e661981d0d 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -51,6 +51,12 @@ func (*MockRegistry) Register(url common.URL) error { return nil } +// UnRegister +func (r *MockRegistry) UnRegister(conf common.URL) error { + + return nil +} + // Destroy ... func (r *MockRegistry) Destroy() { if r.destroyed.CAS(false, true) { @@ -106,6 +112,11 @@ func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) }() } +// UnSubscribe : +func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { + +} + type listener struct { count int64 registry *MockRegistry diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index a436b85064..b2caa39459 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -136,6 +136,12 @@ func (nr *nacosRegistry) Register(url common.URL) error { return nil } +// UnRegister +func (nr *nacosRegistry) UnRegister(conf common.URL) error { + + return nil +} + func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) { return NewNacosListener(*conf, nr.namingClient) } @@ -174,6 +180,11 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti } } +// UnSubscribe : +func (nr *nacosRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { + +} + func (nr *nacosRegistry) GetUrl() common.URL { return *nr.URL } diff --git a/registry/registry.go b/registry/registry.go index d673864700..65756202f1 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -34,6 +34,9 @@ type Registry interface { //And it is also used for service consumer calling , register services cared about ,for dubbo's admin monitoring. Register(url common.URL) error + // UnRegister ... + UnRegister(url common.URL) error + //When creating new registry extension,pls select one of the following modes. //Will remove in dubbogo version v1.1.0 //mode1 : return Listener with Next function which can return subscribe service event from registry @@ -43,6 +46,9 @@ type Registry interface { //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). Subscribe(*common.URL, NotifyListener) + + // UnSubscribe ... + UnSubscribe(*common.URL, NotifyListener) } // NotifyListener ... From a784557009b2bf75785ad17ccaaa680ef7c5682e Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 5 May 2020 17:08:04 +0800 Subject: [PATCH 047/209] Add tests --- common/constant/key.go | 9 +- config/base_config.go | 2 +- config/service_discovery_config.go | 6 +- registry/nacos/service_discovery.go | 10 +- registry/nacos/service_discovery_test.go | 29 ++++++ .../service_discovery_registry.go | 91 ++++++++++++------- 6 files changed, 103 insertions(+), 44 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index a2f8938757..6e91750ddd 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -254,9 +254,7 @@ const ( ) // service discovery - const ( - NACOS_GROUP = "nacos.group" SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" PROVIDER_BY = "provided-by" EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" @@ -267,5 +265,10 @@ const ( METADATA_SERVICE_PREFIX = "dubbo.metadata-service." METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" - SERVICE_NAME_MAPPING_KEY = "service-name-mapping" + + // used by URL + // SERVICE_NAME_MAPPING_KEY indicate that which service name mapping instance will be used + SERVICE_NAME_MAPPING_KEY = "name_mapping" + // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used + SERVICE_DISCOVERY_KEY = "service_discovery" ) diff --git a/config/base_config.go b/config/base_config.go index d95ea27ee6..2f51690d30 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -43,7 +43,7 @@ type multiConfiger interface { // BaseConfig is the common configuration for provider and consumer type BaseConfig struct { ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` - Remotes map[string]*RemoteConfig `yaml:"remotes" json:"remotes,omitempty"` + Remotes map[string]*RemoteConfig `yaml:"remote" json:"remote,omitempty"` ServiceDiscoveries map[string]*ServiceDiscoveryConfig `yaml:"service_discovery" json:"service_discovery,omitempty"` // application config ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` diff --git a/config/service_discovery_config.go b/config/service_discovery_config.go index 343c366ec5..d3dc697a9b 100644 --- a/config/service_discovery_config.go +++ b/config/service_discovery_config.go @@ -21,10 +21,10 @@ package config type ServiceDiscoveryConfig struct { // Protocol indicate which implementation will be used. // for example, if the Protocol is nacos, it means that we will use nacosServiceDiscovery - Protocol string + Protocol string `yaml:"protocol" json:"protocol,omitempty"` // Group, usually you don't need to config this field. // you can use this to do some isolation - Group string + Group string `yaml:"group" json:"group,omitempty"` // RemoteRef is the reference point to RemoteConfig which will be used to create remotes instances. - RemoteRef string + RemoteRef string `yaml:"remote_ref" json:"remote_ref,omitempty"` } diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index e9230195f6..be558a815b 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -281,6 +281,7 @@ func (n *nacosServiceDiscovery) toDeregisterInstance(instance registry.ServiceIn } } +// String will return the description of the instance func (n *nacosServiceDiscovery) String() string { return n.descriptor } @@ -291,7 +292,7 @@ var ( initLock sync.Mutex ) -// newNacosServiceDiscovery will create new service discovery instance +// newNacosServiceDiscovery will try to find the instance withe name, if not found, a new one will be created. // use double-check pattern to reduce race condition func newNacosServiceDiscovery(name string) (registry.ServiceDiscovery, error) { @@ -330,9 +331,12 @@ func newNacosServiceDiscovery(name string) (registry.ServiceDiscovery, error) { descriptor := fmt.Sprintf("nacos-service-discovery[%s]", remoteConfig.Address) - return &nacosServiceDiscovery{ + instance = &nacosServiceDiscovery{ group: group, namingClient: client, descriptor: descriptor, - }, nil + } + + instanceMap[name] = instance + return instance, nil } diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index b2a4fa53cd..ca0f24976e 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -40,6 +40,35 @@ var ( testName = "test" ) +func Test_newNacosServiceDiscovery(t *testing.T) { + name := "nacos1" + _, err := newNacosServiceDiscovery(name) + + // the ServiceDiscoveryConfig not found + assert.NotNil(t, err) + + sdc := &config.ServiceDiscoveryConfig{ + Protocol: "nacos", + RemoteRef: "mock", + } + config.GetBaseConfig().ServiceDiscoveries[name] = sdc + + _, err = newNacosServiceDiscovery(name) + + // RemoteConfig not found + assert.NotNil(t, err) + + config.GetBaseConfig().Remotes["mock"] = &config.RemoteConfig{ + Address: "console.nacos.io:80", + Timeout: 10 * time.Second, + } + + res, err := newNacosServiceDiscovery(name) + assert.Nil(t, err) + assert.NotNil(t, res) + +} + func TestNacosServiceDiscovery_Destroy(t *testing.T) { prepareData() serviceDiscovery, err := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 0adbee203b..d32227b4f9 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -23,6 +23,10 @@ import ( "strconv" "strings" "sync" + + perrors "github.com/pkg/errors" + + "github.com/apache/dubbo-go/config" ) import ( @@ -48,16 +52,22 @@ const ( protocolName = "service-discovery" ) +var ( + registryInstance *serviceDiscoveryRegistry + registryInitOnce sync.Once +) + func init() { extension.SetRegistry(protocolName, newServiceDiscoveryRegistry) } // serviceDiscoveryRegistry is the implementation of application-level registry. // It's completely different from other registry implementations +// The serviceDiscoveryRegistry should be singleton // This implementation is based on ServiceDiscovery abstraction and ServiceNameMapping // In order to keep compatible with interface-level registry, // 1. when we registry the service, we should create the mapping from service name to application name -// 2. when we sub +// 2. when we subscribe the service, we should find out related application and then find application's information type serviceDiscoveryRegistry struct { lock sync.RWMutex url *common.URL @@ -65,38 +75,51 @@ type serviceDiscoveryRegistry struct { subscribedServices *gxset.HashSet serviceNameMapping mapping.ServiceNameMapping metaDataService service.MetadataService - //cache the registered listen + // cache the registered listen registeredListeners *gxset.HashSet - //all synthesize + // all synthesize subscribedURLsSynthesizers []synthesizer.SubscribedURLsSynthesizer - //cache exported urls, serviceName->revision->[]URL + // cache exported urls, serviceName->revision->[]URL serviceRevisionExportedURLsCache map[string]map[string][]common.URL } -func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { - serviceDiscovery, err := creatServiceDiscovery(url) - if err != nil { - return nil, err - } - subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) - subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() - serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) - //TODO it's need to get implement by factory - metaDataService := inmemory.NewMetadataService() - return &serviceDiscoveryRegistry{ - url: url, - serviceDiscovery: serviceDiscovery, - subscribedServices: subscribedServices, - subscribedURLsSynthesizers: subscribedURLsSynthesizers, - registeredListeners: gxset.NewSet(), - serviceRevisionExportedURLsCache: make(map[string]map[string][]common.URL), - serviceNameMapping: serviceNameMapping, - metaDataService: metaDataService, - }, nil +// newServiceDiscoveryRegistry will return the instance +// if not found, it will create one +func newServiceDiscoveryRegistry(url *common.URL) (res registry.Registry, err error) { + + registryInitOnce.Do(func() { + serviceDiscovery, err := creatServiceDiscovery(url) + if err != nil { + return + } + subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) + subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() + serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) + // TODO it's need to get implement by factory + metaDataService := inmemory.NewMetadataService() + registryInstance = &serviceDiscoveryRegistry{ + url: url, + serviceDiscovery: serviceDiscovery, + subscribedServices: subscribedServices, + subscribedURLsSynthesizers: subscribedURLsSynthesizers, + registeredListeners: gxset.NewSet(), + serviceRevisionExportedURLsCache: make(map[string]map[string][]common.URL), + serviceNameMapping: serviceNameMapping, + metaDataService: metaDataService, + } + }) + res = registryInstance + return } func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { - return extension.GetServiceDiscovery(url.Protocol, "TODO") + discovery := url.GetParam(constant.SERVICE_DISCOVERY_KEY, constant.DEFAULT_KEY) + sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(discovery) + + if !ok { + return nil, perrors.New("could not find the ServiceDiscoverConfig with name: " + discovery) + } + return extension.GetServiceDiscovery(sdc.Protocol, discovery) } func parseServices(literalServices string) *gxset.HashSet { @@ -113,22 +136,22 @@ func parseServices(literalServices string) *gxset.HashSet { return set } -//GetServiceDiscovery for get serviceDiscovery of the registry +// GetServiceDiscovery for get serviceDiscovery of the registry func (s *serviceDiscoveryRegistry) GetServiceDiscovery() registry.ServiceDiscovery { return s.serviceDiscovery } -//GetUrl for get url of the registry +// GetUrl for get url of the registry func (s *serviceDiscoveryRegistry) GetUrl() common.URL { return *s.url } -//IsAvailable for make sure is't available +// IsAvailable for make sure is't available func (s *serviceDiscoveryRegistry) IsAvailable() bool { return true } -//Destroy for destroy graceful down +// Destroy for destroy graceful down func (s *serviceDiscoveryRegistry) Destroy() { err := s.serviceDiscovery.Destroy() if err != nil { @@ -162,7 +185,7 @@ func shouldRegister(url common.URL) bool { return false } -//Subscribe for listen the change of services that from the exported url +// Subscribe for listen the change of services that from the exported url func (s *serviceDiscoveryRegistry) Subscribe(url *common.URL, notify registry.NotifyListener) { if !shouldSubscribe(*url) { return @@ -243,7 +266,7 @@ func (s *serviceDiscoveryRegistry) subscribe(url *common.URL, notify registry.No if len(subscribedURLs) == 0 { subscribedURLs = s.synthesizeSubscribedURLs(url, serviceInstances) } - //TODO make sure it's workable + // TODO make sure it's workable for _, url := range subscribedURLs { notify.Notify(®istry.ServiceEvent{ Action: remoting.EventTypeAdd, @@ -461,7 +484,7 @@ func (s *serviceDiscoveryRegistry) initRevisionExportedURLsByInst(serviceInstanc serviceInstance.GetHost(), serviceInstance.GetPort(), revision) } } else { - //Else, The cache is hit + // Else, The cache is hit logger.Debugf("Get the exported URLs[size : %s] from cache, the instance"+ "[id: %s , service : %s , host : %s , port : %s , revision : %s]", len(revisionExportedURLs), firstGet, serviceInstance.GetId(), serviceInstance.GetServiceName(), serviceInstance.GetHost(), @@ -499,8 +522,8 @@ func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsa u.RemoveParams(removeParamSet) port := strconv.Itoa(getProtocolPort(serviceInstance, u.Protocol)) if u.Location != host || u.Port != port { - u.Port = port //reset port - u.Location = host //reset host + u.Port = port // reset port + u.Location = host // reset host } clonedExportedURLs = append(clonedExportedURLs, u) } From 266e0b6ad2b1b69960782fba635dbc9c4dfd6a08 Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 15 Apr 2020 22:35:48 +0800 Subject: [PATCH 048/209] Add extensiong for metadata service --- common/extension/service_name_mapping.go | 17 ++-- .../mapping/dynamic/service_name_mapping.go | 34 +++----- .../dynamic/service_name_mapping_test.go | 2 +- .../mapping/memory/service_name_mapping.go | 22 ++++++ registry/nacos/service_discovery.go | 79 +++---------------- 5 files changed, 54 insertions(+), 100 deletions(-) diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 1598430752..795595905d 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -18,18 +18,21 @@ package extension import ( - "github.com/apache/dubbo-go/metadata/mapping" + "github.com/apache/dubbo-go/metadata" ) var ( - nameMappings = make(map[string]func() mapping.ServiceNameMapping) + nameMappings = make(map[string]func() metadata.ServiceNameMapping) ) -func SetServiceNameMapping(name string, creator func() mapping.ServiceNameMapping) { - // TODO(@邓大明) +func SetServiceNameMapping(name string, creator func() metadata.ServiceNameMapping) { + nameMappings[name] = creator } -func GetServiceNameMapping(name string) mapping.ServiceNameMapping { - // TODO(@邓大明) - return nil +func GetServiceNameMapping(name string) metadata.ServiceNameMapping { + creator, ok := nameMappings[name] + if !ok { + panic("Can not find the target service name mapping: " + name) + } + return creator() } diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 5e40692905..bf578d54ac 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -29,27 +29,19 @@ import ( ) import ( - env "github.com/apache/dubbo-go/common/config" + common_cfg "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/config" "github.com/apache/dubbo-go/config_center" - "github.com/apache/dubbo-go/metadata/mapping" + "github.com/apache/dubbo-go/metadata" ) const ( defaultGroup = config_center.DEFAULT_GROUP slash = "/" - name = "dynamic" ) -func init() { - extension.SetServiceNameMapping(name, GetServiceNameMappingInstance) - extension.SetServiceNameMapping(constant.DEFAULT_KEY, GetServiceNameMappingInstance) -} - // DynamicConfigurationServiceNameMapping is the implementation based on config center -// It could be thought as singleton pattern. type DynamicConfigurationServiceNameMapping struct { dc config_center.DynamicConfiguration } @@ -87,21 +79,15 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str } var ( - instance *DynamicConfigurationServiceNameMapping - initOnce sync.Once + serviceNameMappingInstance *DynamicConfigurationServiceNameMapping + serviceNameMappingInitOnce sync.Once ) -// newServiceNameMapping will create an instance of DynamicConfigurationServiceNameMapping -func newServiceNameMapping(dc config_center.DynamicConfiguration) *DynamicConfigurationServiceNameMapping { - return &DynamicConfigurationServiceNameMapping{dc: dc} -} - -// GetServiceNameMappingInstance will return the instance. -// If the instance is not initiated, it will create one -func GetServiceNameMappingInstance() mapping.ServiceNameMapping { - initOnce.Do(func() { - dc := env.GetEnvInstance().GetDynamicConfiguration() - instance = newServiceNameMapping(dc) +// GetServiceNameMappingInstance will return an instance of DynamicConfigurationServiceNameMapping +func GetServiceNameMappingInstance() metadata.ServiceNameMapping { + serviceNameMappingInitOnce.Do(func() { + dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() + serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc} }) - return instance + return serviceNameMappingInstance } diff --git a/metadata/mapping/dynamic/service_name_mapping_test.go b/metadata/mapping/dynamic/service_name_mapping_test.go index 31aaf3f11c..647a15ae78 100644 --- a/metadata/mapping/dynamic/service_name_mapping_test.go +++ b/metadata/mapping/dynamic/service_name_mapping_test.go @@ -41,7 +41,7 @@ func TestDynamicConfigurationServiceNameMapping(t *testing.T) { }).GetDynamicConfiguration(nil) config.GetApplicationConfig().Name = appName - mapping := newServiceNameMapping(dc) + mapping := &DynamicConfigurationServiceNameMapping{dc: dc} intf := constant.METADATA_SERVICE_NAME group := "myGroup" version := "myVersion" diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go index 8a891491bd..cf051a11e4 100644 --- a/metadata/mapping/memory/service_name_mapping.go +++ b/metadata/mapping/memory/service_name_mapping.go @@ -17,14 +17,24 @@ package memory +import ( + "sync" +) + import ( gxset "github.com/dubbogo/gost/container/set" ) import ( + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata" ) +func init() { + extension.SetServiceNameMapping("in-memory", GetInMemoryServiceNameMappingInstance) +} + type InMemoryServiceNameMapping struct{} func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, version string, protocol string) error { @@ -34,3 +44,15 @@ func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, v func (i InMemoryServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { return gxset.NewSet(config.GetApplicationConfig().Name), nil } + +var ( + nameMappingInstance *InMemoryServiceNameMapping + nameMappingInitOnce sync.Once +) + +func GetInMemoryServiceNameMappingInstance() metadata.ServiceNameMapping { + nameMappingInitOnce.Do(func() { + nameMappingInstance = &InMemoryServiceNameMapping{} + }) + return nameMappingInstance +} diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index be558a815b..7d3406cac2 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -18,21 +18,15 @@ package nacos import ( - "fmt" - "sync" - "github.com/dubbogo/gost/container/set" "github.com/dubbogo/gost/page" - "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" perrors "github.com/pkg/errors" - - "github.com/apache/dubbo-go/config" - "github.com/apache/dubbo-go/remoting/nacos" ) 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" @@ -53,12 +47,8 @@ func init() { // There is a problem, the go client for nacos does not support the id field. // we will use the metadata to store the id of ServiceInstance type nacosServiceDiscovery struct { + nacosBaseRegistry group string - // descriptor is a short string about the basic information of this instance - descriptor string - - // namingClient is the Nacos' client - namingClient naming_client.INamingClient } // Destroy will close the service discovery. @@ -247,7 +237,7 @@ func (n *nacosServiceDiscovery) DispatchEventForInstances(serviceName string, in // DispatchEvent will dispatch the event func (n *nacosServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { - extension.GetGlobalDispatcher().Dispatch(event) + // TODO(waiting for event dispatcher, another task) return nil } @@ -281,62 +271,15 @@ func (n *nacosServiceDiscovery) toDeregisterInstance(instance registry.ServiceIn } } -// String will return the description of the instance -func (n *nacosServiceDiscovery) String() string { - return n.descriptor -} - -var ( - // 16 would be enough. We won't use concurrentMap because in most cases, there are not race condition - instanceMap = make(map[string]registry.ServiceDiscovery, 16) - initLock sync.Mutex -) +// toDeregisterInstance will create new service discovery instance +func newNacosServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { -// newNacosServiceDiscovery will try to find the instance withe name, if not found, a new one will be created. -// use double-check pattern to reduce race condition -func newNacosServiceDiscovery(name string) (registry.ServiceDiscovery, error) { - - instance, ok := instanceMap[name] - if ok { - return instance, nil - } - - initLock.Lock() - defer initLock.Unlock() - - // double check - instance, ok = instanceMap[name] - if ok { - return instance, nil - } - - sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(name) - if !ok || len(sdc.RemoteRef) == 0 { - return nil, perrors.New("could not init the instance because the config is invalid") - } - - remoteConfig, ok := config.GetBaseConfig().GetRemoteConfig(sdc.RemoteRef) - if !ok { - return nil, perrors.New("could not find the remote config for name: " + sdc.RemoteRef) - } - group := sdc.Group - if len(group) == 0 { - group = defaultGroup - } - - client, err := nacos.NewNacosClient(remoteConfig) + base, err := newBaseRegistry(url) if err != nil { - return nil, perrors.WithMessage(err, "create nacos client failed.") + return nil, perrors.WithStack(err) } - - descriptor := fmt.Sprintf("nacos-service-discovery[%s]", remoteConfig.Address) - - instance = &nacosServiceDiscovery{ - group: group, - namingClient: client, - descriptor: descriptor, - } - - instanceMap[name] = instance - return instance, nil + return &nacosServiceDiscovery{ + nacosBaseRegistry: base, + group: url.GetParam(constant.NACOS_GROUP, defaultGroup), + }, nil } From 99ac8c58da576ba0062fd405782f3dff8e33b90f Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 6 May 2020 16:54:58 +0800 Subject: [PATCH 049/209] add Event --- common/observer/event.go | 2 +- .../event_publishing_service_discovery.go | 64 ++++++++++---- registry/common/service_discovery_event.go | 87 +++++++++++++++++++ registry/common/service_instance_event.go | 68 +++++++++++++++ 4 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 registry/common/service_discovery_event.go create mode 100644 registry/common/service_instance_event.go diff --git a/common/observer/event.go b/common/observer/event.go index 8c3362feee..d78179043e 100644 --- a/common/observer/event.go +++ b/common/observer/event.go @@ -58,7 +58,7 @@ func (b *BaseEvent) String() string { return fmt.Sprintf("BaseEvent[source = %#v]", b.Source) } -func newBaseEvent(source interface{}) *BaseEvent { +func NewBaseEvent(source interface{}) *BaseEvent { return &BaseEvent{ Source: source, Timestamp: time.Now(), diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go index 8c6881f65a..8c019c7aaa 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/common/event_publishing_service_discovery.go @@ -18,6 +18,7 @@ package common import ( + "github.com/apache/dubbo-go/common/extension" gxset "github.com/dubbogo/gost/container/set" gxpage "github.com/dubbogo/gost/page" ) @@ -26,73 +27,100 @@ import ( "github.com/apache/dubbo-go/registry" ) +var dispatcher = extension.GetGlobalDispatcher() + // EventPublishingServiceDiscovery will enhance Service Discovery // Publish some event about service discovery type EventPublishingServiceDiscovery struct { - serviceDiscovery *registry.ServiceDiscovery + serviceDiscovery registry.ServiceDiscovery } // NewEventPublishingServiceDiscovery is a constructor -func NewEventPublishingServiceDiscovery(serviceDiscovery *registry.ServiceDiscovery) *EventPublishingServiceDiscovery { - return &EventPublishingServiceDiscovery{serviceDiscovery: serviceDiscovery} +func NewEventPublishingServiceDiscovery(serviceDiscovery registry.ServiceDiscovery) *EventPublishingServiceDiscovery { + return &EventPublishingServiceDiscovery{ + serviceDiscovery: serviceDiscovery, + } } func (epsd *EventPublishingServiceDiscovery) String() string { - panic("implement me") + return epsd.serviceDiscovery.String() } func (epsd *EventPublishingServiceDiscovery) Destroy() error { - panic("implement me") + dispatcher.Dispatch(NewServiceDiscoveryDestroyingEvent(epsd, epsd.serviceDiscovery)) + if err := epsd.serviceDiscovery.Destroy(); err != nil { + dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + return err + } + dispatcher.Dispatch(NewServiceDiscoveryDestroyedEvent(epsd, epsd.serviceDiscovery)) + return nil } func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceInstance) error { - panic("implement me") + dispatcher.Dispatch(NewServiceInstancePreRegisteredEvent(epsd.serviceDiscovery, instance)) + if err := epsd.serviceDiscovery.Register(instance); err != nil { + dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + return err + } + dispatcher.Dispatch(NewServiceInstanceRegisteredEvent(epsd.serviceDiscovery, instance)) + return nil } func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceInstance) error { - panic("implement me") + if err := epsd.serviceDiscovery.Update(instance); err != nil { + dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + return err + } + return nil } func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.ServiceInstance) error { - panic("implement me") + dispatcher.Dispatch(NewServiceInstancePreUnregisteredEvent(epsd.serviceDiscovery, instance)) + if err := epsd.serviceDiscovery.Register(instance); err != nil { + dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + return err + } + dispatcher.Dispatch(NewServiceInstanceUnregisteredEvent(epsd.serviceDiscovery, instance)) + return nil } func (epsd *EventPublishingServiceDiscovery) GetDefaultPageSize() int { - panic("implement me") + return epsd.serviceDiscovery.GetDefaultPageSize() } func (epsd *EventPublishingServiceDiscovery) GetServices() *gxset.HashSet { - panic("implement me") + return epsd.serviceDiscovery.GetServices() } func (epsd *EventPublishingServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { - panic("implement me") + return epsd.serviceDiscovery.GetInstances(serviceName) } func (epsd *EventPublishingServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { - panic("implement me") + return epsd.serviceDiscovery.GetInstancesByPage(serviceName, offset, pageSize) } func (epsd *EventPublishingServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { - panic("implement me") + return epsd.serviceDiscovery.GetHealthyInstancesByPage(serviceName, offset, pageSize, healthy) } func (epsd *EventPublishingServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { - panic("implement me") + return epsd.serviceDiscovery.GetRequestInstances(serviceNames, offset, requestedSize) } func (epsd *EventPublishingServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { - panic("implement me") + dispatcher.AddEventListener(listener) + return epsd.serviceDiscovery.AddListener(listener) } func (epsd *EventPublishingServiceDiscovery) DispatchEventByServiceName(serviceName string) error { - panic("implement me") + return epsd.DispatchEventByServiceName(serviceName) } func (epsd *EventPublishingServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { - panic("implement me") + return epsd.serviceDiscovery.DispatchEventForInstances(serviceName, instances) } func (epsd *EventPublishingServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { - panic("implement me") + return epsd.serviceDiscovery.DispatchEvent(event) } diff --git a/registry/common/service_discovery_event.go b/registry/common/service_discovery_event.go new file mode 100644 index 0000000000..4bc7928f24 --- /dev/null +++ b/registry/common/service_discovery_event.go @@ -0,0 +1,87 @@ +/* + * 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 common + +import ( + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/registry" +) + +type ServiceDiscoveryEvent struct { + observer.BaseEvent + original registry.ServiceDiscovery + err error +} + +func NewServiceDiscoveryEventWithoutError(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryEvent { + return &ServiceDiscoveryEvent{ + BaseEvent: *observer.NewBaseEvent(discovery), + original: original, + } +} + +func NewServiceDiscoveryEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery, err error) *ServiceDiscoveryEvent { + return &ServiceDiscoveryEvent{ + BaseEvent: *observer.NewBaseEvent(discovery), + original: original, + err: err, + } +} + +func (sde *ServiceDiscoveryEvent) GetServiceDiscovery() registry.ServiceDiscovery { + return sde.GetSource().(registry.ServiceDiscovery) +} + +func (sde *ServiceDiscoveryEvent) GetOriginal() registry.ServiceDiscovery { + return sde.original +} + +type ServiceDiscoveryDestroyingEvent ServiceDiscoveryEvent + +type ServiceDiscoveryExceptionEvent ServiceDiscoveryEvent + +type ServiceDiscoveryInitializedEvent ServiceDiscoveryEvent + +type ServiceDiscoveryInitializingEvent ServiceDiscoveryEvent + +type ServiceDiscoveryDestroyedEvent ServiceDiscoveryEvent + +// NewServiceDiscoveryDestroyingEvent create a ServiceDiscoveryDestroyingEvent +func NewServiceDiscoveryDestroyingEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryDestroyingEvent { + return (*ServiceDiscoveryDestroyingEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) +} + +// NewServiceDiscoveryExceptionEvent create a ServiceDiscoveryExceptionEvent +func NewServiceDiscoveryExceptionEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery, err error) *ServiceDiscoveryExceptionEvent { + return (*ServiceDiscoveryExceptionEvent)(NewServiceDiscoveryEvent(discovery, original, err)) +} + +// NewServiceDiscoveryInitializedEvent create a ServiceDiscoveryInitializedEvent +func NewServiceDiscoveryInitializedEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryInitializedEvent { + return (*ServiceDiscoveryInitializedEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) +} + +// NewServiceDiscoveryInitializingEvent create a ServiceDiscoveryInitializingEvent +func NewServiceDiscoveryInitializingEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryInitializingEvent { + return (*ServiceDiscoveryInitializingEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) +} + +// NewServiceDiscoveryDestroyedEvent create a ServiceDiscoveryDestroyedEvent +func NewServiceDiscoveryDestroyedEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryDestroyedEvent { + return (*ServiceDiscoveryDestroyedEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) +} diff --git a/registry/common/service_instance_event.go b/registry/common/service_instance_event.go new file mode 100644 index 0000000000..029fa8c536 --- /dev/null +++ b/registry/common/service_instance_event.go @@ -0,0 +1,68 @@ +/* + * 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 common + +import ( + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/registry" +) + +type ServiceInstanceEvent struct { + observer.BaseEvent + serviceInstance registry.ServiceInstance +} + +// NewServiceInstanceEvent create a ServiceInstanceEvent +func NewServiceInstanceEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstanceEvent { + return &ServiceInstanceEvent{ + BaseEvent: *observer.NewBaseEvent(source), + serviceInstance: instance, + } +} + +func (sie *ServiceInstanceEvent) getServiceInstance() registry.ServiceInstance { + return sie.serviceInstance +} + +type ServiceInstancePreRegisteredEvent ServiceInstanceEvent + +type ServiceInstancePreUnregisteredEvent ServiceInstanceEvent + +type ServiceInstanceRegisteredEvent ServiceInstanceEvent + +type ServiceInstanceUnregisteredEvent ServiceInstanceEvent + +// NewServiceInstancePreRegisteredEvent create a ServiceInstancePreRegisteredEvent +func NewServiceInstancePreRegisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstancePreRegisteredEvent { + return (*ServiceInstancePreRegisteredEvent)(NewServiceInstanceEvent(source, instance)) +} + +// NewServiceInstancePreUnregisteredEvent create a ServiceInstancePreUnregisteredEvent +func NewServiceInstancePreUnregisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstancePreUnregisteredEvent { + return (*ServiceInstancePreUnregisteredEvent)(NewServiceInstanceEvent(source, instance)) +} + +// NewServiceInstanceRegisteredEvent create a ServiceInstanceRegisteredEvent +func NewServiceInstanceRegisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstanceRegisteredEvent { + return (*ServiceInstanceRegisteredEvent)(NewServiceInstanceEvent(source, instance)) +} + +// NewServiceInstanceUnregisteredEvent create a ServiceInstanceUnregisteredEvent +func NewServiceInstanceUnregisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstanceUnregisteredEvent { + return (*ServiceInstanceUnregisteredEvent)(NewServiceInstanceEvent(source, instance)) +} From b87dbe226895fc45fe2f5eb81b14b4319682c371 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Wed, 6 May 2020 17:44:57 +0800 Subject: [PATCH 050/209] Add:metadata report delegate & remote metadata service --- common/constant/key.go | 4 + config/instance/metedata_report.go | 25 +- config/metadata_report_config.go | 2 +- go.mod | 1 + go.sum | 11 + metadata/definition/definition.go | 40 +++ metadata/definition/definition_test.go | 52 ++++ metadata/definition/mock.go | 46 +++ .../identifier/service_metadata_identifier.go | 13 + .../subscribe_metadata_identifier.go | 2 +- metadata/report/delegate/delegate_report.go | 281 ++++++++++++++++++ .../report/delegate/delegate_report_test.go | 123 ++++++++ metadata/report/report.go | 13 +- metadata/service/inmemory/service.go | 39 ++- metadata/service/inmemory/service_test.go | 27 +- metadata/service/remote/service.go | 195 ++++++++++++ metadata/service/remote/service_test.go | 139 +++++++++ metadata/service/service.go | 7 + 18 files changed, 961 insertions(+), 59 deletions(-) create mode 100644 metadata/definition/definition_test.go create mode 100644 metadata/definition/mock.go create mode 100644 metadata/report/delegate/delegate_report.go create mode 100644 metadata/report/delegate/delegate_report_test.go create mode 100644 metadata/service/remote/service.go create mode 100644 metadata/service/remote/service_test.go diff --git a/common/constant/key.go b/common/constant/key.go index da21a3a9e1..6acb2299c4 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -79,6 +79,10 @@ const ( EXECUTE_REJECTED_EXECUTION_HANDLER_KEY = "execute.limit.rejected.handler" PROVIDER_SHUTDOWN_FILTER = "pshutdown" CONSUMER_SHUTDOWN_FILTER = "cshutdown" + SYNC_REPORT_KEY = "sync.report" + RETRY_PERIOD_KEY = "retry.period" + RETRY_TIMES_KEY = "retry.times" + CYCLE_REPORT_KEY = "cycle.report" ) const ( diff --git a/config/instance/metedata_report.go b/config/instance/metedata_report.go index 9cf435bc9d..70e6ffc23d 100644 --- a/config/instance/metedata_report.go +++ b/config/instance/metedata_report.go @@ -28,14 +28,31 @@ import ( ) var ( - instance report.MetadataReport - once sync.Once + instance report.MetadataReport + reportUrl common.URL + once sync.Once ) -// GetMetadataReportInstance ... -func GetMetadataReportInstance(url *common.URL) report.MetadataReport { +// InitMetadataReportInstance will create the metadata report instance by the specified metadata report url +func InitMetadataReportInstance(url *common.URL) report.MetadataReport { once.Do(func() { instance = extension.GetMetadataReportFactory(url.Protocol).CreateMetadataReport(url) + reportUrl = *url }) return instance } + +// GetMetadataReportInstance will return the instance +func GetMetadataReportInstance() report.MetadataReport { + return instance +} + +// GetMetadataReportUrl will return the report instance url +func GetMetadataReportUrl() common.URL { + return reportUrl +} + +// SetMetadataReportUrl will only can be used by unit test to mock url +func SetMetadataReportUrl(url common.URL) { + reportUrl = url +} diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index 41fb6b4769..95506462a2 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -101,7 +101,7 @@ func startMetadataReport(metadataType string, metadataReportConfig *MetadataRepo } if url, err := metadataReportConfig.ToUrl(); err == nil { - instance.GetMetadataReportInstance(url) + instance.InitMetadataReportInstance(url) } else { return perrors.New("MetadataConfig is invalid!") } diff --git a/go.mod b/go.mod index fe1891ea6e..54e5ebcd93 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/dubbogo/gost v1.8.0 github.com/emicklei/go-restful/v3 v3.0.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect + github.com/go-co-op/gocron v0.1.1 github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect diff --git a/go.sum b/go.sum index 73c3da87a0..46235271ab 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-co-op/gocron v0.1.1 h1:OfDmkqkCguFtFMsm6Eaayci3DADLa8pXvdmOlPU/JcU= +github.com/go-co-op/gocron v0.1.1/go.mod h1:Y9PWlYqDChf2Nbgg7kfS+ZsXHDTZbMZYPEQ0MILqH+M= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= @@ -152,6 +154,7 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+ github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-resty/resty/v2 v2.1.0 h1:Z6IefCpUMfnvItVJaJXWv/pMiiD11So35QgwEELsldE= github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4 h1:1LlmVz15APoKz9dnm5j2ePptburJlwEH+/v/pUuoxck= @@ -391,10 +394,14 @@ github.com/oklog/run v0.0.0-20180308005104-6934b124db28/go.mod h1:dlhp/R75TPv97u github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= @@ -526,6 +533,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20170807180024-9a379c6b3e95/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -534,6 +543,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 8d4a584ee5..18578cb2c1 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -19,6 +19,8 @@ package definition import ( "bytes" + "encoding/json" + "fmt" ) import ( @@ -26,6 +28,11 @@ import ( "github.com/apache/dubbo-go/common/constant" ) +// ServiceDefinition is a interface of service's definition +type ServiceDefiner interface { + ToBytes() ([]byte, error) +} + // ServiceDefinition is the describer of service definition type ServiceDefinition struct { CanonicalName string @@ -34,6 +41,39 @@ type ServiceDefinition struct { Types []TypeDefinition } +func (def ServiceDefinition) ToBytes() ([]byte, error) { + return json.Marshal(def) + +} + +func (def ServiceDefinition) String() string { + var methodStr string + for _, m := range def.Methods { + var paramType string + for _, p := range m.ParameterTypes { + paramType = paramType + fmt.Sprintf("{type:%v}", p) + } + var param string + for _, d := range m.Parameters { + param = param + fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName) + } + methodStr = methodStr + fmt.Sprintf("{name:%v,parameterTypes:[%v],returnType:%v,params:[%v] }", m.Name, paramType, m.ReturnType, param) + + } + var types string + for _, d := range def.Types { + types = types + fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName) + } + + return fmt.Sprintf("{canonicalName:%v, codeSource:%v, methods:[%v], types:[%v]}", def.CanonicalName, def.CodeSource, methodStr, types) +} + +// FullServiceDefinition is the describer of service definition with parameters +type FullServiceDefinition struct { + ServiceDefinition + Params map[string]string +} + // MethodDefinition is the describer of method definition type MethodDefinition struct { Name string diff --git a/metadata/definition/definition_test.go b/metadata/definition/definition_test.go new file mode 100644 index 0000000000..958f9324d0 --- /dev/null +++ b/metadata/definition/definition_test.go @@ -0,0 +1,52 @@ +/* + * 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 + +import ( + "fmt" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" +) + +func TestBuildServiceDefinition(t *testing.T) { + serviceName := "com.ikurento.user.UserProvider" + group := "group1" + version := "0.0.1" + protocol := "dubbo" + beanName := "UserProvider" + url, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider1?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, serviceName, group, version, beanName)) + assert.NoError(t, err) + _, err = common.ServiceMap.Register(serviceName, protocol, &UserProvider{}) + assert.NoError(t, err) + service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + sd := BuildServiceDefinition(*service, url) + assert.Equal(t, "{canonicalName:com.ikurento.user.UserProvider, codeSource:, methods:[{name:GetUser,parameterTypes:[{type:slice}],returnType:ptr,params:[] }], types:[]}", sd.String()) +} diff --git a/metadata/definition/mock.go b/metadata/definition/mock.go new file mode 100644 index 0000000000..ca9e125a74 --- /dev/null +++ b/metadata/definition/mock.go @@ -0,0 +1,46 @@ +/* + * 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 + +import ( + "context" + "time" +) + +type User struct { + Id string + Name string + Age int32 + Time time.Time +} + +type UserProvider struct { +} + +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { + rsp := User{"A001", "Alex Stocks", 18, time.Now()} + return &rsp, nil +} + +func (u *UserProvider) Reference() string { + return "UserProvider" +} + +func (u User) JavaClassName() string { + return "com.ikurento.user.User" +} diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index 92c15704db..7cdb55e53d 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -18,6 +18,7 @@ package identifier import ( + "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" ) @@ -28,6 +29,18 @@ type ServiceMetadataIdentifier struct { BaseMetadataIdentifier } +func NewServiceMetadataIdentifier(url common.URL) *ServiceMetadataIdentifier { + return &ServiceMetadataIdentifier{ + BaseMetadataIdentifier: BaseMetadataIdentifier{ + ServiceInterface: url.Service(), + Version: url.GetParam(constant.VERSION_KEY, ""), + Group: url.GetParam(constant.GROUP_KEY, ""), + Side: url.GetParam(constant.SIDE_KEY, ""), + }, + Protocol: url.Protocol, + } +} + // GetIdentifierKey will return string format as service:Version:Group:Side:Protocol:"revision"+Revision func (mdi *ServiceMetadataIdentifier) GetIdentifierKey() string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.Protocol, constant.KEY_REVISON_PREFIX+mdi.Revision) diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index e599fc9e0d..fa35ab79d6 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -20,7 +20,7 @@ package identifier // SubscriberMetadataIdentifier is inherit baseMetaIdentifier with service params: Revision type SubscriberMetadataIdentifier struct { Revision string - BaseMetadataIdentifier + MetadataIdentifier } // GetIdentifierKey will return string format as service:Version:Group:Side:Revision diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go new file mode 100644 index 0000000000..870625b9cb --- /dev/null +++ b/metadata/report/delegate/delegate_report.go @@ -0,0 +1,281 @@ +/* + * 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 delegate + +import ( + "encoding/json" + "sync" + "time" +) + +import ( + "github.com/go-co-op/gocron" + "go.uber.org/atomic" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/config/instance" + "github.com/apache/dubbo-go/metadata/definition" + "github.com/apache/dubbo-go/metadata/identifier" +) + +const ( + // defaultMetadataReportRetryTimes is defined for max times to retry + defaultMetadataReportRetryTimes int64 = 100 + // defaultMetadataReportRetryPeriod is defined for cycle interval to retry, the unit is second + defaultMetadataReportRetryPeriod int64 = 3 + // defaultMetadataReportRetryPeriod is defined for cycle report or not + defaultMetadataReportCycleReport bool = true +) + +// metadataReportRetry is a scheduler for retrying task +type metadataReportRetry struct { + retryPeriod int64 + retryLimit int64 + scheduler *gocron.Scheduler + job *gocron.Job + retryCounter *atomic.Int64 + // if no failed report, wait how many times to run retry task. + retryTimesIfNonFail int64 +} + +// newMetadataReportRetry will create a scheduler for retry task +func newMetadataReportRetry(retryPeriod int64, retryLimit int64, retryFunc func() bool) (*metadataReportRetry, error) { + s1 := gocron.NewScheduler(time.UTC) + + mrr := &metadataReportRetry{ + retryPeriod: retryPeriod, + retryLimit: retryLimit, + scheduler: s1, + retryCounter: atomic.NewInt64(0), + retryTimesIfNonFail: 600, + } + + newJob, err := mrr.scheduler.Every(uint64(mrr.retryPeriod)).Seconds().Do( + func() { + mrr.retryCounter.Inc() + logger.Infof("start to retry task for metadata report. retry times: %v", mrr.retryCounter.Load()) + if mrr.retryCounter.Load() > mrr.retryLimit { + mrr.scheduler.Clear() + } else if retryFunc() && mrr.retryCounter.Load() > mrr.retryTimesIfNonFail { + mrr.scheduler.Clear() // may not interrupt the running job + } + }) + + mrr.job = newJob + return mrr, err +} + +// startRetryTask will make scheduler with retry task run +func (mrr *metadataReportRetry) startRetryTask() { + mrr.scheduler.StartAt(time.Now().Add(500 * time.Millisecond)) + mrr.scheduler.Start() +} + +// MetadataReport is a absolute delegate for MetadataReport +type MetadataReport struct { + reportUrl common.URL + syncReport bool + metadataReportRetry *metadataReportRetry + + failedReports map[*identifier.MetadataIdentifier]interface{} + failedReportsLock sync.RWMutex + + // allMetadataReports store all the metdadata reports records in memory + allMetadataReports map[*identifier.MetadataIdentifier]interface{} + allMetadataReportsLock sync.RWMutex +} + +// NewMetadataReport will create a MetadataReport with initiation +func NewMetadataReport() (*MetadataReport, error) { + url := instance.GetMetadataReportUrl() + bmr := &MetadataReport{ + reportUrl: url, + syncReport: url.GetParamBool(constant.SYNC_REPORT_KEY, false), + failedReports: make(map[*identifier.MetadataIdentifier]interface{}, 4), + allMetadataReports: make(map[*identifier.MetadataIdentifier]interface{}, 4), + } + + mrr, err := newMetadataReportRetry( + url.GetParamInt(constant.RETRY_PERIOD_KEY, defaultMetadataReportRetryPeriod), + url.GetParamInt(constant.RETRY_TIMES_KEY, defaultMetadataReportRetryTimes), + bmr.retry, + ) + + if err != nil { + return nil, err + } + + bmr.metadataReportRetry = mrr + if url.GetParamBool(constant.CYCLE_REPORT_KEY, defaultMetadataReportCycleReport) { + scheduler := gocron.NewScheduler(time.UTC) + _, err := scheduler.Every(1).Day().Do( + func() { + logger.Info("start to publish all metadata.") + bmr.allMetadataReportsLock.RLock() + bmr.doHandlerMetadataCollection(bmr.allMetadataReports) + bmr.allMetadataReportsLock.RUnlock() + + }) + if err != nil { + return nil, err + } + scheduler.StartAt(time.Now().Add(500 * time.Millisecond)) + scheduler.Start() + } + return bmr, nil +} + +// retry will do metadata failed reports collection by call metadata report sdk +func (bmr *MetadataReport) retry() bool { + bmr.failedReportsLock.RLock() + bmr.failedReportsLock.Unlock() + return bmr.doHandlerMetadataCollection(bmr.failedReports) +} + +// StoreProviderMetadata will delegate to call remote metadata's sdk to store provider service definition +func (bmr *MetadataReport) StoreProviderMetadata(identifier *identifier.MetadataIdentifier, definer definition.ServiceDefiner) { + if bmr.syncReport { + bmr.storeMetadataTask(common.PROVIDER, identifier, definer) + } else { + go bmr.storeMetadataTask(common.PROVIDER, identifier, definer) + } +} + +// storeMetadataTask will delegate to call remote metadata's sdk to store +func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.MetadataIdentifier, definer interface{}) { + logger.Infof("store provider metadata. Identifier :%v ; definition: %v .", identifier, definer) + bmr.allMetadataReportsLock.Lock() + bmr.allMetadataReports[identifier] = definer + bmr.allMetadataReportsLock.Unlock() + + bmr.failedReportsLock.Lock() + delete(bmr.failedReports, identifier) + bmr.failedReportsLock.Unlock() + // data is store the json marshaled definition + var ( + data []byte + err error + ) + + defer func() { + if r := recover(); r != nil { + bmr.failedReportsLock.Lock() + bmr.failedReports[identifier] = definer + bmr.failedReportsLock.Unlock() + bmr.metadataReportRetry.startRetryTask() + logger.Errorf("Failed to put provider metadata %v in %v, cause: %v", identifier, string(data), r) + } + }() + + data, err = json.Marshal(definer) + if err != nil { + logger.Errorf("storeProviderMetadataTask error in stage json.Marshal, msg is %v", err) + panic(err) + } + report := instance.GetMetadataReportInstance() + if role == common.PROVIDER { + err = report.StoreProviderMetadata(identifier, string(data)) + } else if role == common.CONSUMER { + err = report.StoreConsumerMetadata(identifier, string(data)) + } + + if err != nil { + logger.Errorf("storeProviderMetadataTask error in stage call metadata report to StoreProviderMetadata, msg is %v", err) + panic(err) + } + +} + +// StoreConsumerMetadata will delegate to call remote metadata's sdk to store consumer side service definition +func (bmr *MetadataReport) StoreConsumerMetadata(identifier *identifier.MetadataIdentifier, definer map[string]string) { + if bmr.syncReport { + bmr.storeMetadataTask(common.CONSUMER, identifier, definer) + } else { + go bmr.storeMetadataTask(common.CONSUMER, identifier, definer) + } +} + +// SaveServiceMetadata will delegate to call remote metadata's sdk to save service metadata +func (bmr *MetadataReport) SaveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier, url common.URL) error { + report := instance.GetMetadataReportInstance() + if bmr.syncReport { + return report.SaveServiceMetadata(identifier, url) + } else { + go report.SaveServiceMetadata(identifier, url) + return nil + } +} + +// RemoveServiceMetadata will delegate to call remote metadata's sdk to remove service metadata +func (bmr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier) error { + report := instance.GetMetadataReportInstance() + if bmr.syncReport { + return report.RemoveServiceMetadata(identifier) + } else { + go report.RemoveServiceMetadata(identifier) + return nil + } +} + +// GetExportedURLs will delegate to call remote metadata's sdk to get exported urls +func (bmr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadataIdentifier) []string { + report := instance.GetMetadataReportInstance() + return report.GetExportedURLs(identifier) +} + +// SaveSubscribedData will delegate to call remote metadata's sdk to save subscribed data +func (bmr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { + report := instance.GetMetadataReportInstance() + if bmr.syncReport { + return report.SaveSubscribedData(identifier, urls) + } else { + go report.SaveSubscribedData(identifier, urls) + return nil + } +} + +// GetSubscribedURLs will delegate to call remote metadata's sdk to get subscribed urls +func (MetadataReport) GetSubscribedURLs(identifier *identifier.SubscriberMetadataIdentifier) []string { + report := instance.GetMetadataReportInstance() + return report.GetSubscribedURLs(identifier) +} + +// GetServiceDefinition will delegate to call remote metadata's sdk to get service definitions +func (MetadataReport) GetServiceDefinition(identifier *identifier.MetadataIdentifier) string { + report := instance.GetMetadataReportInstance() + return report.GetServiceDefinition(identifier) +} + +// doHandlerMetadataCollection will store metadata to metadata support with given metadataMap +func (bmr *MetadataReport) doHandlerMetadataCollection(metadataMap map[*identifier.MetadataIdentifier]interface{}) bool { + if len(metadataMap) == 0 { + return true + } + for e := range metadataMap { + if common.RoleType(common.PROVIDER).Role() == e.Side { + bmr.StoreProviderMetadata(e, metadataMap[e].(*definition.FullServiceDefinition)) + } else if common.RoleType(common.CONSUMER).Role() == e.Side { + bmr.StoreConsumerMetadata(e, metadataMap[e].(map[string]string)) + } + } + return false +} diff --git a/metadata/report/delegate/delegate_report_test.go b/metadata/report/delegate/delegate_report_test.go new file mode 100644 index 0000000000..b5f8551a1a --- /dev/null +++ b/metadata/report/delegate/delegate_report_test.go @@ -0,0 +1,123 @@ +/* + * 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 delegate + +import ( + "fmt" + "testing" + "time" +) + +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/logger" + "github.com/apache/dubbo-go/config/instance" + "github.com/apache/dubbo-go/metadata/definition" + "github.com/apache/dubbo-go/metadata/identifier" +) + +func TestMetadataReport_MetadataReportRetry(t *testing.T) { + counter := 1 + + retry, err := newMetadataReportRetry(1, 10, func() bool { + counter++ + return true + }) + assert.NoError(t, err) + retry.startRetryTask() + itsTime := time.After(2500 * time.Millisecond) + select { + case <-itsTime: + retry.scheduler.Clear() + assert.Equal(t, counter, 3) + logger.Info("over") + } +} + +func TestMetadataReport_MetadataReportRetryWithLimit(t *testing.T) { + counter := 1 + + retry, err := newMetadataReportRetry(1, 1, func() bool { + counter++ + return true + }) + assert.NoError(t, err) + retry.startRetryTask() + itsTime := time.After(2500 * time.Millisecond) + select { + case <-itsTime: + retry.scheduler.Clear() + assert.Equal(t, counter, 2) + logger.Info("over") + } + +} + +func mockNewMetadataReport(t *testing.T) *MetadataReport { + syncReportKey := "false" + retryPeroidKey := "3" + retryTimesKey := "100" + cycleReportKey := "true" + + url, err := common.NewURL(fmt.Sprintf( + "test://127.0.0.1:20000/?"+constant.SYNC_REPORT_KEY+"=%v&"+constant.RETRY_PERIOD_KEY+"=%v&"+ + constant.RETRY_TIMES_KEY+"=%v&"+constant.CYCLE_REPORT_KEY+"=%v", + syncReportKey, retryPeroidKey, retryTimesKey, cycleReportKey)) + assert.NoError(t, err) + instance.SetMetadataReportUrl(url) + mtr, err := NewMetadataReport() + assert.NoError(t, err) + assert.NotNil(t, mtr) + return mtr +} + +func TestMetadataReport_StoreProviderMetadata(t *testing.T) { + mtr := mockNewMetadataReport(t) + var metadataId = &identifier.MetadataIdentifier{ + Application: "app", + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: "com.ikurento.user.UserProvider", + Version: "0.0.1", + Group: "group1", + Side: "provider", + }, + } + + mtr.StoreProviderMetadata(metadataId, getMockDefinition(metadataId, t)) +} + +func getMockDefinition(id *identifier.MetadataIdentifier, t *testing.T) definition.ServiceDefinition { + protocol := "dubbo" + beanName := "UserProvider" + url, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider1?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, id.ServiceInterface, id.Group, id.Version, beanName)) + assert.NoError(t, err) + _, err = common.ServiceMap.Register(id.ServiceInterface, protocol, &definition.UserProvider{}) + assert.NoError(t, err) + service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + return definition.BuildServiceDefinition(*service, url) +} diff --git a/metadata/report/report.go b/metadata/report/report.go index 81227e0c76..61cdda1f96 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -19,18 +19,17 @@ package report import ( "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/metadata/definition" "github.com/apache/dubbo-go/metadata/identifier" ) // MetadataReport is an interface of remote metadata report type MetadataReport interface { - StoreProviderMetadata(*identifier.MetadataIdentifier, *definition.ServiceDefinition) - StoreConsumerMetadata(*identifier.MetadataIdentifier, map[string]string) - SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, *common.URL) - RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) + StoreProviderMetadata(*identifier.MetadataIdentifier, string) error + StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error + SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error + RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string - SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []*common.URL) + SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []common.URL) error GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string - GetServiceDefinition(*identifier.MetadataIdentifier) + GetServiceDefinition(*identifier.MetadataIdentifier) string } diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index c59949401f..df0ec7a4a7 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -17,7 +17,6 @@ package inmemory import ( - "encoding/json" "sync" ) @@ -53,13 +52,13 @@ func NewMetadataService() *MetadataService { } } -// comparator is defined as Comparator for skip list to compare the URL -type comparator common.URL +// Comparator is defined as Comparator for skip list to compare the URL +type Comparator common.URL // Compare is defined as Comparator for skip list to compare the URL -func (c comparator) Compare(comp cm.Comparator) int { +func (c Comparator) Compare(comp cm.Comparator) int { a := common.URL(c).String() - b := common.URL(comp.(comparator)).String() + b := common.URL(comp.(Comparator)).String() switch { case a > b: return 1 @@ -79,7 +78,7 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { logger.Debug(url.ServiceKey()) if urlSet, loaded = targetMap.LoadOrStore(url.ServiceKey(), skip.New(uint64(0))); loaded { mts.lock.RLock() - wantedUrl := urlSet.(*skip.SkipList).Get(comparator(*url)) + wantedUrl := urlSet.(*skip.SkipList).Get(Comparator(*url)) if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.RUnlock() return false @@ -88,12 +87,12 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { } mts.lock.Lock() //double chk - wantedUrl := urlSet.(*skip.SkipList).Get(comparator(*url)) + wantedUrl := urlSet.(*skip.SkipList).Get(Comparator(*url)) if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.Unlock() return false } - urlSet.(*skip.SkipList).Insert(comparator(*url)) + urlSet.(*skip.SkipList).Insert(Comparator(*url)) mts.lock.Unlock() return true } @@ -102,7 +101,7 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { if value, loaded := targetMap.Load(url.ServiceKey()); loaded { mts.lock.Lock() - value.(*skip.SkipList).Delete(comparator(*url)) + value.(*skip.SkipList).Delete(Comparator(*url)) mts.lock.Unlock() mts.lock.RLock() defer mts.lock.RUnlock() @@ -118,9 +117,9 @@ func (mts *MetadataService) getAllService(services *sync.Map) *skip.SkipList { services.Range(func(key, value interface{}) bool { urls := value.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { - url := common.URL(urls.ByPosition(i).(comparator)) + url := common.URL(urls.ByPosition(i).(Comparator)) if url.GetParam(constant.INTERFACE_KEY, url.Path) != "MetadataService" { - skipList.Insert(comparator(url)) + skipList.Insert(Comparator(url)) } } return true @@ -135,9 +134,9 @@ func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey s if loaded { urls := serviceList.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { - url := common.URL(urls.ByPosition(i).(comparator)) + url := common.URL(urls.ByPosition(i).(Comparator)) if len(protocol) == 0 || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { - skipList.Insert(comparator(url)) + skipList.Insert(Comparator(url)) } } } @@ -182,9 +181,9 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { // //TODO:generate the service definition and store it //} sd := definition.BuildServiceDefinition(*service, url) - data, err := json.Marshal(sd) + data, err := sd.ToBytes() if err != nil { - logger.Errorf("publishProvider getServiceDescriptor error. providerUrl:%v , error: ", url, err) + logger.Errorf("publishProvider getServiceDescriptor error. providerUrl:%v , error:%v ", url, err) } mts.serviceDefinitions.Store(url.ServiceKey(), string(data)) return nil @@ -221,12 +220,12 @@ func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) return v.(string), nil } -// Version will return the version of metadata service -func (mts *MetadataService) Version() string { - return "1.0.0" +// RefreshMetadata will always return true because it will be implement by remote service +func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { + return true } // Version will return the version of metadata service -func (mts *MetadataService) Reference() string { - return "MetadataService" +func (mts *MetadataService) Version() string { + return "1.0.0" } diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go index 9e593db282..fc0410ecca 100644 --- a/metadata/service/inmemory/service_test.go +++ b/metadata/service/inmemory/service_test.go @@ -18,10 +18,8 @@ package inmemory import ( - "context" "fmt" "testing" - "time" ) import ( @@ -33,29 +31,6 @@ import ( "github.com/apache/dubbo-go/metadata/definition" ) -type User struct { - Id string - Name string - Age int32 - Time time.Time -} - -type UserProvider struct { -} - -func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { - rsp := User{"A001", "Alex Stocks", 18, time.Now()} - return &rsp, nil -} - -func (u *UserProvider) Reference() string { - return "UserProvider" -} - -func (u User) JavaClassName() string { - return "com.ikurento.user.User" -} - func TestMetadataService(t *testing.T) { mts := NewMetadataService() serviceName := "com.ikurento.user.UserProvider" @@ -111,7 +86,7 @@ func TestMetadataService(t *testing.T) { list4, _ := mts.GetSubscribedURLs() assert.Equal(t, uint64(0), list4.Len()) - userProvider := &UserProvider{} + userProvider := &definition.UserProvider{} common.ServiceMap.Register(serviceName, protocol, userProvider) mts.PublishServiceDefinition(u) expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," + diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go new file mode 100644 index 0000000000..706f2f919c --- /dev/null +++ b/metadata/service/remote/service.go @@ -0,0 +1,195 @@ +/* + * 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 remote + +import ( + "github.com/Workiva/go-datastructures/slice/skip" + "go.uber.org/atomic" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "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/identifier" + "github.com/apache/dubbo-go/metadata/report/delegate" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/metadata/service/inmemory" +) + +// MetadataService is a implement of metadata service which will delegate the remote metadata report +type MetadataService struct { + service.BaseMetadataService + inMemoryMetadataService *inmemory.MetadataService + exportedRevision atomic.String + subscribedRevision atomic.String + delegateReport *delegate.MetadataReport +} + +// NewMetadataService will create a new remote MetadataService instance +func NewMetadataService() (*MetadataService, error) { + mr, err := delegate.NewMetadataReport() + if err != nil { + return nil, err + } + return &MetadataService{ + inMemoryMetadataService: inmemory.NewMetadataService(), + delegateReport: mr, + }, nil +} + +// setInMemoryMetadataService will replace the in memory metadata service by the specific param +func (mts *MetadataService) setInMemoryMetadataService(metadata *inmemory.MetadataService) { + mts.inMemoryMetadataService = metadata +} + +// ExportURL will be implemented by in memory service +func (mts *MetadataService) ExportURL(url common.URL) (bool, error) { + return true, nil +} + +// UnexportURL +func (mts *MetadataService) UnexportURL(url common.URL) error { + smi := identifier.NewServiceMetadataIdentifier(url) + smi.Revision = mts.exportedRevision.Load() + return mts.delegateReport.RemoveServiceMetadata(smi) +} + +// SubscribeURL will be implemented by in memory service +func (MetadataService) SubscribeURL(url common.URL) (bool, error) { + return true, nil +} + +// UnsubscribeURL will be implemented by in memory service +func (MetadataService) UnsubscribeURL(url common.URL) error { + return nil +} + +// PublishServiceDefinition will call remote metadata's StoreProviderMetadata to store url info and service definition +func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { + interfaceName := url.GetParam(constant.INTERFACE_KEY, "") + isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) + if len(interfaceName) > 0 && !isGeneric { + service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + sd := definition.BuildServiceDefinition(*service, url) + id := &identifier.MetadataIdentifier{ + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: interfaceName, + Version: url.GetParam(constant.VERSION_KEY, ""), + Group: url.GetParam(constant.GROUP_KEY, ""), + }, + } + mts.delegateReport.StoreProviderMetadata(id, sd) + } + logger.Errorf("publishProvider interfaceName is empty . providerUrl:%v ", url) + return nil +} + +// GetExportedURLs will be implemented by in memory service +func (MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { + return nil, nil +} + +// GetSubscribedURLs will be implemented by in memory service +func (MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { + return nil, nil +} + +// GetServiceDefinition will be implemented by in memory service +func (MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + return "", nil +} + +// GetServiceDefinitionByServiceKey will be implemented by in memory service +func (MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + return "", nil +} + +// RefreshMetadata will refresh the exported & subscribed metadata to remote metadata report from the inmemory metadata service +func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { + result := true + if len(exportedRevision) != 0 && exportedRevision != mts.exportedRevision.Load() { + mts.exportedRevision.Store(exportedRevision) + urls, err := mts.inMemoryMetadataService.GetExportedURLs(constant.ANY_VALUE, "", "", "") + if err != nil { + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + result = false + } + iterator := urls.Iter(inmemory.Comparator{}) + logger.Infof("urls length = %v", urls.Len()) + for { + if !iterator.Next() { + break + } + url := iterator.Value().(inmemory.Comparator) + id := identifier.NewServiceMetadataIdentifier(common.URL(url)) + id.Revision = mts.exportedRevision.Load() + if err := mts.delegateReport.SaveServiceMetadata(id, common.URL(url)); err != nil { + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + result = false + } + + } + } + + if len(subscribedRevision) != 0 && subscribedRevision != mts.subscribedRevision.Load() { + mts.subscribedRevision.Store(subscribedRevision) + urls, err := mts.inMemoryMetadataService.GetSubscribedURLs() + if err != nil { + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + result = false + } + if urls != nil && urls.Len() > 0 { + id := &identifier.SubscriberMetadataIdentifier{ + MetadataIdentifier: identifier.MetadataIdentifier{ + Application: config.GetApplicationConfig().Name, + }, + Revision: subscribedRevision, + } + if err := mts.delegateReport.SaveSubscribedData(id, convertUrls(urls)); err != nil { + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + result = false + } + } + } + return result +} + +// Version will return the remote service version +func (MetadataService) Version() string { + return "1.0.0" +} + +// convertUrls will convert the skip list to slice +func convertUrls(list *skip.SkipList) []common.URL { + urls := make([]common.URL, list.Len()) + iterator := list.Iter(inmemory.Comparator{}) + for { + if iterator.Value() == nil { + break + } + url := iterator.Value().(inmemory.Comparator) + urls = append(urls, common.URL(url)) + if !iterator.Next() { + break + } + } + return urls +} diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go new file mode 100644 index 0000000000..05378cb8b1 --- /dev/null +++ b/metadata/service/remote/service_test.go @@ -0,0 +1,139 @@ +/* + * 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 remote + +import ( + "fmt" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/config/instance" + "github.com/apache/dubbo-go/metadata/definition" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" + "github.com/apache/dubbo-go/metadata/service/inmemory" +) + +var serviceMetadata = make(map[*identifier.ServiceMetadataIdentifier]common.URL, 4) +var subscribedMetadata = make(map[*identifier.SubscriberMetadataIdentifier][]common.URL, 4) + +func getMetadataReportFactory() factory.MetadataReportFactory { + return &metadataReportFactory{} +} + +type metadataReportFactory struct { +} + +func (mrf *metadataReportFactory) CreateMetadataReport(*common.URL) report.MetadataReport { + return &metadataReport{} +} + +type metadataReport struct { +} + +func (metadataReport) StoreProviderMetadata(*identifier.MetadataIdentifier, string) error { + return nil +} + +func (metadataReport) StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error { + return nil +} + +func (mr *metadataReport) SaveServiceMetadata(id *identifier.ServiceMetadataIdentifier, url common.URL) error { + logger.Infof("SaveServiceMetadata , url is %v", url) + serviceMetadata[id] = url + return nil +} + +func (metadataReport) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error { + return nil +} + +func (metadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string { + return nil +} + +func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { + logger.Infof("SaveSubscribedData, , url is %v", urls) + subscribedMetadata[id] = urls + return nil +} + +func (metadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string { + return nil +} + +func (metadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) string { + return "" +} + +func TestMetadataService(t *testing.T) { + extension.SetMetadataReportFactory("mock", getMetadataReportFactory) + u, err := common.NewURL(fmt.Sprintf( + "mock://127.0.0.1:20000/?sync.report=true")) + assert.NoError(t, err) + instance.InitMetadataReportInstance(&u) + mts, err := NewMetadataService() + assert.NoError(t, err) + mts.setInMemoryMetadataService(mockInmemoryProc(t)) + mts.RefreshMetadata("0.0.1", "0.0.1") + assert.Equal(t, 1, len(serviceMetadata)) + assert.Equal(t, 1, len(subscribedMetadata)) +} + +func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { + mts := inmemory.NewMetadataService() + serviceName := "com.ikurento.user.UserProvider" + group := "group1" + version := "0.0.1" + protocol := "dubbo" + beanName := "UserProvider" + + u, err := common.NewURL(fmt.Sprintf( + "%v://127.0.0.1:20000/com.ikurento.user.UserProvider1?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=%v&ip=192.168.56.1&methods=GetUser&module=dubbogo+user-info+server&org=ikurento.com&"+ + "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", + protocol, serviceName, group, version, beanName)) + assert.NoError(t, err) + mts.ExportURL(u) + + mts.SubscribeURL(u) + + userProvider := &definition.UserProvider{} + common.ServiceMap.Register(serviceName, protocol, userProvider) + mts.PublishServiceDefinition(u) + expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," + + "\"Methods\":[{\"Name\":\"GetUser\",\"ParameterTypes\":[\"slice\"],\"ReturnType\":\"ptr\"," + + "\"Parameters\":null}],\"Types\":null}" + def1, _ := mts.GetServiceDefinition(serviceName, group, version) + assert.Equal(t, expected, def1) + serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) + def2, _ := mts.GetServiceDefinitionByServiceKey(serviceKey) + assert.Equal(t, expected, def2) + return mts +} diff --git a/metadata/service/service.go b/metadata/service/service.go index bc526c5411..a1b812c0ac 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -49,6 +49,8 @@ type MetadataService interface { GetServiceDefinition(interfaceName string, group string, version string) (string, error) // GetServiceDefinition will get the target service info store in metadata by service key GetServiceDefinitionByServiceKey(serviceKey string) (string, error) + // RefreshMetadata will refresh the metadata + RefreshMetadata(exportedRevision string, subscribedRevision string) bool // Version will return the metadata service version Version() string } @@ -61,3 +63,8 @@ type BaseMetadataService struct { func (mts *BaseMetadataService) ServiceName() (string, error) { return config.GetApplicationConfig().Name, nil } + +// Version will return the version of metadata service +func (mts *BaseMetadataService) Reference() string { + return "MetadataService" +} From 73f21fa3e1316b2e80a982b1374de8f9bf1c3e96 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Wed, 6 May 2020 17:47:31 +0800 Subject: [PATCH 051/209] Mod:for ut --- .../identifier/subscribe_metadata_identifier_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/metadata/identifier/subscribe_metadata_identifier_test.go b/metadata/identifier/subscribe_metadata_identifier_test.go index 9c9ef70641..215aa3c569 100644 --- a/metadata/identifier/subscribe_metadata_identifier_test.go +++ b/metadata/identifier/subscribe_metadata_identifier_test.go @@ -27,11 +27,13 @@ import ( var subscribeMetadataId = &SubscriberMetadataIdentifier{ Revision: "1.0", - BaseMetadataIdentifier: BaseMetadataIdentifier{ - ServiceInterface: "org.apache.pkg.mockService", - Version: "1.0.0", - Group: "Group", - Side: "provider", + MetadataIdentifier: MetadataIdentifier{ + BaseMetadataIdentifier: BaseMetadataIdentifier{ + ServiceInterface: "org.apache.pkg.mockService", + Version: "1.0.0", + Group: "Group", + Side: "provider", + }, }, } From 2938f51876a0b435f289639a93026d4f528e31d5 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 6 May 2020 18:27:58 +0800 Subject: [PATCH 052/209] optimize code --- .../event_publishing_service_discovery.go | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go index 8c019c7aaa..b34b4bc8d6 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/common/event_publishing_service_discovery.go @@ -19,6 +19,7 @@ package common import ( "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" gxset "github.com/dubbogo/gost/container/set" gxpage "github.com/dubbogo/gost/page" ) @@ -47,41 +48,35 @@ func (epsd *EventPublishingServiceDiscovery) String() string { } func (epsd *EventPublishingServiceDiscovery) Destroy() error { - dispatcher.Dispatch(NewServiceDiscoveryDestroyingEvent(epsd, epsd.serviceDiscovery)) - if err := epsd.serviceDiscovery.Destroy(); err != nil { - dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) - return err + f := func() error { + return epsd.serviceDiscovery.Destroy() } - dispatcher.Dispatch(NewServiceDiscoveryDestroyedEvent(epsd, epsd.serviceDiscovery)) - return nil + return epsd.executeWithEvents(NewServiceDiscoveryDestroyingEvent(epsd, epsd.serviceDiscovery), + f, NewServiceDiscoveryDestroyedEvent(epsd, epsd.serviceDiscovery)) } func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceInstance) error { - dispatcher.Dispatch(NewServiceInstancePreRegisteredEvent(epsd.serviceDiscovery, instance)) - if err := epsd.serviceDiscovery.Register(instance); err != nil { - dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) - return err + f := func() error { + return epsd.serviceDiscovery.Register(instance) } - dispatcher.Dispatch(NewServiceInstanceRegisteredEvent(epsd.serviceDiscovery, instance)) - return nil + return epsd.executeWithEvents(NewServiceInstancePreRegisteredEvent(epsd.serviceDiscovery, instance), + f, NewServiceInstanceRegisteredEvent(epsd.serviceDiscovery, instance)) + } func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceInstance) error { - if err := epsd.serviceDiscovery.Update(instance); err != nil { - dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) - return err + f := func() error { + return epsd.serviceDiscovery.Update(instance) } - return nil + return epsd.executeWithEvents(nil, f, nil) } func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.ServiceInstance) error { - dispatcher.Dispatch(NewServiceInstancePreUnregisteredEvent(epsd.serviceDiscovery, instance)) - if err := epsd.serviceDiscovery.Register(instance); err != nil { - dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) - return err + f := func() error { + return epsd.serviceDiscovery.Register(instance) } - dispatcher.Dispatch(NewServiceInstanceUnregisteredEvent(epsd.serviceDiscovery, instance)) - return nil + return epsd.executeWithEvents(NewServiceInstancePreUnregisteredEvent(epsd.serviceDiscovery, instance), + f, NewServiceInstanceUnregisteredEvent(epsd.serviceDiscovery, instance)) } func (epsd *EventPublishingServiceDiscovery) GetDefaultPageSize() int { @@ -124,3 +119,17 @@ func (epsd *EventPublishingServiceDiscovery) DispatchEventForInstances(serviceNa func (epsd *EventPublishingServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { return epsd.serviceDiscovery.DispatchEvent(event) } + +func (epsd *EventPublishingServiceDiscovery) executeWithEvents(beforeEvent observer.Event, f func() error, afterEvent observer.Event) error { + if beforeEvent != nil { + dispatcher.Dispatch(beforeEvent) + } + if err := f(); err != nil { + dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + return err + } + if afterEvent != nil { + dispatcher.Dispatch(afterEvent) + } + return nil +} From ada27e2aca430eeb8611ef42af8bf2a00c2fd5d9 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 8 May 2020 11:05:35 +0800 Subject: [PATCH 053/209] add unit tests and modify event struct --- ...vent_publishing_service_deiscovery_test.go | 161 ++++++++++++++++++ .../event_publishing_service_discovery.go | 28 +-- registry/common/service_discovery_event.go | 52 +++--- registry/common/service_instance_event.go | 32 +++- 4 files changed, 234 insertions(+), 39 deletions(-) create mode 100644 registry/common/event_publishing_service_deiscovery_test.go diff --git a/registry/common/event_publishing_service_deiscovery_test.go b/registry/common/event_publishing_service_deiscovery_test.go new file mode 100644 index 0000000000..856a902d1c --- /dev/null +++ b/registry/common/event_publishing_service_deiscovery_test.go @@ -0,0 +1,161 @@ +/* + * 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 common + +import ( + "reflect" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" + dispatcher2 "github.com/apache/dubbo-go/common/observer/dispatcher" + "github.com/apache/dubbo-go/registry" + gxset "github.com/dubbogo/gost/container/set" + gxpage "github.com/dubbogo/gost/page" +) + +func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { + dc := NewEventPublishingServiceDiscovery(&ServiceDiscoveryA{}) + tsd := &TestServiceDiscoveryDestroyingEventListener{} + tsd.SetT(t) + tsi := &TestServiceInstancePreRegisteredEventListener{} + tsi.SetT(t) + extension.AddEventListener(tsd) + extension.AddEventListener(tsi) + extension.SetEventDispatcher("direct", dispatcher2.NewDirectEventDispatcher) + extension.SetAndInitGlobalDispatcher("direct") + err := dc.Destroy() + assert.Nil(t, err) + si := ®istry.DefaultServiceInstance{Id: "testServiceInstance"} + err = dc.Register(si) + assert.Nil(t, err) + +} + +type TestServiceDiscoveryDestroyingEventListener struct { + suite.Suite + observer.BaseListenable +} + +func (tel *TestServiceDiscoveryDestroyingEventListener) OnEvent(e observer.Event) error { + e1, ok := e.(*ServiceDiscoveryDestroyingEvent) + assert.Equal(tel.T(), ok, true) + assert.Equal(tel.T(), "testServiceDiscovery", e1.GetOriginal().String()) + assert.Equal(tel.T(), "testServiceDiscovery", e1.GetServiceDiscovery().String()) + return nil +} + +func (tel *TestServiceDiscoveryDestroyingEventListener) GetPriority() int { + return -1 +} + +func (tel *TestServiceDiscoveryDestroyingEventListener) GetEventType() reflect.Type { + return reflect.TypeOf(ServiceDiscoveryDestroyingEvent{}) +} + +type TestServiceInstancePreRegisteredEventListener struct { + suite.Suite + observer.BaseListenable +} + +func (tel *TestServiceInstancePreRegisteredEventListener) OnEvent(e observer.Event) error { + e1, ok := e.(*ServiceInstancePreRegisteredEvent) + assert.Equal(tel.T(), ok, true) + assert.Equal(tel.T(), "testServiceInstance", e1.getServiceInstance().GetId()) + return nil +} + +func (tel *TestServiceInstancePreRegisteredEventListener) GetPriority() int { + return -1 +} + +func (tel *TestServiceInstancePreRegisteredEventListener) GetEventType() reflect.Type { + return reflect.TypeOf(ServiceInstancePreRegisteredEvent{}) +} + +type ServiceDiscoveryA struct { +} + +// String return mockServiceDiscovery +func (msd *ServiceDiscoveryA) String() string { + return "testServiceDiscovery" +} + +// Destroy do nothing +func (msd *ServiceDiscoveryA) Destroy() error { + return nil +} + +func (msd *ServiceDiscoveryA) Register(instance registry.ServiceInstance) error { + return nil +} + +func (msd *ServiceDiscoveryA) Update(instance registry.ServiceInstance) error { + return nil +} + +func (msd *ServiceDiscoveryA) Unregister(instance registry.ServiceInstance) error { + return nil +} + +func (msd *ServiceDiscoveryA) GetDefaultPageSize() int { + return 1 +} + +func (msd *ServiceDiscoveryA) GetServices() *gxset.HashSet { + return nil +} + +func (msd *ServiceDiscoveryA) GetInstances(serviceName string) []registry.ServiceInstance { + return nil +} + +func (msd *ServiceDiscoveryA) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + return nil +} + +func (msd *ServiceDiscoveryA) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + return nil +} + +func (msd *ServiceDiscoveryA) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + return nil +} + +func (msd *ServiceDiscoveryA) AddListener(listener *registry.ServiceInstancesChangedListener) error { + return nil +} + +func (msd *ServiceDiscoveryA) DispatchEventByServiceName(serviceName string) error { + return nil +} + +func (msd *ServiceDiscoveryA) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + return nil +} + +func (msd *ServiceDiscoveryA) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + return nil +} diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go index b34b4bc8d6..43d2917c32 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/common/event_publishing_service_discovery.go @@ -17,6 +17,10 @@ package common +import ( + "github.com/apache/dubbo-go/registry" +) + import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" @@ -24,12 +28,6 @@ import ( gxpage "github.com/dubbogo/gost/page" ) -import ( - "github.com/apache/dubbo-go/registry" -) - -var dispatcher = extension.GetGlobalDispatcher() - // EventPublishingServiceDiscovery will enhance Service Discovery // Publish some event about service discovery type EventPublishingServiceDiscovery struct { @@ -43,10 +41,12 @@ func NewEventPublishingServiceDiscovery(serviceDiscovery registry.ServiceDiscove } } +// String func (epsd *EventPublishingServiceDiscovery) String() string { return epsd.serviceDiscovery.String() } +// Destroy delegate function func (epsd *EventPublishingServiceDiscovery) Destroy() error { f := func() error { return epsd.serviceDiscovery.Destroy() @@ -55,6 +55,7 @@ func (epsd *EventPublishingServiceDiscovery) Destroy() error { f, NewServiceDiscoveryDestroyedEvent(epsd, epsd.serviceDiscovery)) } +// Register delegate function func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceInstance) error { f := func() error { return epsd.serviceDiscovery.Register(instance) @@ -64,6 +65,7 @@ func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceI } +// Update delegate function func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceInstance) error { f := func() error { return epsd.serviceDiscovery.Update(instance) @@ -71,9 +73,10 @@ func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceIns return epsd.executeWithEvents(nil, f, nil) } +// Unregister delegate function func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.ServiceInstance) error { f := func() error { - return epsd.serviceDiscovery.Register(instance) + return epsd.serviceDiscovery.Unregister(instance) } return epsd.executeWithEvents(NewServiceInstancePreUnregisteredEvent(epsd.serviceDiscovery, instance), f, NewServiceInstanceUnregisteredEvent(epsd.serviceDiscovery, instance)) @@ -103,8 +106,9 @@ func (epsd *EventPublishingServiceDiscovery) GetRequestInstances(serviceNames [] return epsd.serviceDiscovery.GetRequestInstances(serviceNames, offset, requestedSize) } +// AddListener add event listener func (epsd *EventPublishingServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { - dispatcher.AddEventListener(listener) + extension.GetGlobalDispatcher().AddEventListener(listener) return epsd.serviceDiscovery.AddListener(listener) } @@ -120,16 +124,18 @@ func (epsd *EventPublishingServiceDiscovery) DispatchEvent(event *registry.Servi return epsd.serviceDiscovery.DispatchEvent(event) } +// executeWithEvents dispatch before event and after event if return error will dispatch exception event func (epsd *EventPublishingServiceDiscovery) executeWithEvents(beforeEvent observer.Event, f func() error, afterEvent observer.Event) error { + globalDispatcher := extension.GetGlobalDispatcher() if beforeEvent != nil { - dispatcher.Dispatch(beforeEvent) + globalDispatcher.Dispatch(beforeEvent) } if err := f(); err != nil { - dispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) + globalDispatcher.Dispatch(NewServiceDiscoveryExceptionEvent(epsd, epsd.serviceDiscovery, err)) return err } if afterEvent != nil { - dispatcher.Dispatch(afterEvent) + globalDispatcher.Dispatch(afterEvent) } return nil } diff --git a/registry/common/service_discovery_event.go b/registry/common/service_discovery_event.go index 4bc7928f24..a60ca56a39 100644 --- a/registry/common/service_discovery_event.go +++ b/registry/common/service_discovery_event.go @@ -25,24 +25,15 @@ import ( type ServiceDiscoveryEvent struct { observer.BaseEvent original registry.ServiceDiscovery - err error } -func NewServiceDiscoveryEventWithoutError(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryEvent { +func NewServiceDiscoveryEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryEvent { return &ServiceDiscoveryEvent{ BaseEvent: *observer.NewBaseEvent(discovery), original: original, } } -func NewServiceDiscoveryEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery, err error) *ServiceDiscoveryEvent { - return &ServiceDiscoveryEvent{ - BaseEvent: *observer.NewBaseEvent(discovery), - original: original, - err: err, - } -} - func (sde *ServiceDiscoveryEvent) GetServiceDiscovery() registry.ServiceDiscovery { return sde.GetSource().(registry.ServiceDiscovery) } @@ -51,37 +42,58 @@ func (sde *ServiceDiscoveryEvent) GetOriginal() registry.ServiceDiscovery { return sde.original } -type ServiceDiscoveryDestroyingEvent ServiceDiscoveryEvent +// ServiceDiscoveryDestroyingEvent +// this event will be dispatched before service discovery be destroyed +type ServiceDiscoveryDestroyingEvent struct { + ServiceDiscoveryEvent +} -type ServiceDiscoveryExceptionEvent ServiceDiscoveryEvent +// ServiceDiscoveryExceptionEvent +// this event will be dispatched when the error occur in service discovery +type ServiceDiscoveryExceptionEvent struct { + ServiceDiscoveryEvent + err error +} -type ServiceDiscoveryInitializedEvent ServiceDiscoveryEvent +// ServiceDiscoveryInitializedEvent +// this event will be dispatched after service discovery initialize +type ServiceDiscoveryInitializedEvent struct { + ServiceDiscoveryEvent +} -type ServiceDiscoveryInitializingEvent ServiceDiscoveryEvent +// ServiceDiscoveryInitializingEvent +// this event will be dispatched before service discovery initialize +type ServiceDiscoveryInitializingEvent struct { + ServiceDiscoveryEvent +} -type ServiceDiscoveryDestroyedEvent ServiceDiscoveryEvent +// ServiceDiscoveryDestroyedEvent +// this event will be dispatched after service discovery be destroyed +type ServiceDiscoveryDestroyedEvent struct { + ServiceDiscoveryEvent +} // NewServiceDiscoveryDestroyingEvent create a ServiceDiscoveryDestroyingEvent func NewServiceDiscoveryDestroyingEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryDestroyingEvent { - return (*ServiceDiscoveryDestroyingEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) + return &ServiceDiscoveryDestroyingEvent{*NewServiceDiscoveryEvent(discovery, original)} } // NewServiceDiscoveryExceptionEvent create a ServiceDiscoveryExceptionEvent func NewServiceDiscoveryExceptionEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery, err error) *ServiceDiscoveryExceptionEvent { - return (*ServiceDiscoveryExceptionEvent)(NewServiceDiscoveryEvent(discovery, original, err)) + return &ServiceDiscoveryExceptionEvent{*NewServiceDiscoveryEvent(discovery, original), err} } // NewServiceDiscoveryInitializedEvent create a ServiceDiscoveryInitializedEvent func NewServiceDiscoveryInitializedEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryInitializedEvent { - return (*ServiceDiscoveryInitializedEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) + return &ServiceDiscoveryInitializedEvent{*NewServiceDiscoveryEvent(discovery, original)} } // NewServiceDiscoveryInitializingEvent create a ServiceDiscoveryInitializingEvent func NewServiceDiscoveryInitializingEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryInitializingEvent { - return (*ServiceDiscoveryInitializingEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) + return &ServiceDiscoveryInitializingEvent{*NewServiceDiscoveryEvent(discovery, original)} } // NewServiceDiscoveryDestroyedEvent create a ServiceDiscoveryDestroyedEvent func NewServiceDiscoveryDestroyedEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryDestroyedEvent { - return (*ServiceDiscoveryDestroyedEvent)(NewServiceDiscoveryEventWithoutError(discovery, original)) + return &ServiceDiscoveryDestroyedEvent{*NewServiceDiscoveryEvent(discovery, original)} } diff --git a/registry/common/service_instance_event.go b/registry/common/service_instance_event.go index 029fa8c536..f70e7ee0ff 100644 --- a/registry/common/service_instance_event.go +++ b/registry/common/service_instance_event.go @@ -39,30 +39,46 @@ func (sie *ServiceInstanceEvent) getServiceInstance() registry.ServiceInstance { return sie.serviceInstance } -type ServiceInstancePreRegisteredEvent ServiceInstanceEvent +// ServiceInstancePreRegisteredEvent +// this event will be dispatched before service instance be registered +type ServiceInstancePreRegisteredEvent struct { + ServiceInstanceEvent +} -type ServiceInstancePreUnregisteredEvent ServiceInstanceEvent +// ServiceInstancePreUnregisteredEvent +// this event will be dispatched before service instance be unregistered +type ServiceInstancePreUnregisteredEvent struct { + ServiceInstanceEvent +} -type ServiceInstanceRegisteredEvent ServiceInstanceEvent +// ServiceInstanceRegisteredEvent +// this event will be dispatched after service instance be registered +type ServiceInstanceRegisteredEvent struct { + ServiceInstanceEvent +} -type ServiceInstanceUnregisteredEvent ServiceInstanceEvent +// ServiceInstanceRegisteredEvent +// this event will be dispatched after service instance be unregistered +type ServiceInstanceUnregisteredEvent struct { + ServiceInstanceEvent +} // NewServiceInstancePreRegisteredEvent create a ServiceInstancePreRegisteredEvent func NewServiceInstancePreRegisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstancePreRegisteredEvent { - return (*ServiceInstancePreRegisteredEvent)(NewServiceInstanceEvent(source, instance)) + return &ServiceInstancePreRegisteredEvent{*NewServiceInstanceEvent(source, instance)} } // NewServiceInstancePreUnregisteredEvent create a ServiceInstancePreUnregisteredEvent func NewServiceInstancePreUnregisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstancePreUnregisteredEvent { - return (*ServiceInstancePreUnregisteredEvent)(NewServiceInstanceEvent(source, instance)) + return &ServiceInstancePreUnregisteredEvent{*NewServiceInstanceEvent(source, instance)} } // NewServiceInstanceRegisteredEvent create a ServiceInstanceRegisteredEvent func NewServiceInstanceRegisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstanceRegisteredEvent { - return (*ServiceInstanceRegisteredEvent)(NewServiceInstanceEvent(source, instance)) + return &ServiceInstanceRegisteredEvent{*NewServiceInstanceEvent(source, instance)} } // NewServiceInstanceUnregisteredEvent create a ServiceInstanceUnregisteredEvent func NewServiceInstanceUnregisteredEvent(source interface{}, instance registry.ServiceInstance) *ServiceInstanceUnregisteredEvent { - return (*ServiceInstanceUnregisteredEvent)(NewServiceInstanceEvent(source, instance)) + return &ServiceInstanceUnregisteredEvent{*NewServiceInstanceEvent(source, instance)} } From 9f7e1f3c5a8f9b50d2e9e2eebf05f2e59b679646 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 8 May 2020 11:11:44 +0800 Subject: [PATCH 054/209] fix imports --- registry/common/event_publishing_service_deiscovery_test.go | 4 ++-- registry/common/event_publishing_service_discovery.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/registry/common/event_publishing_service_deiscovery_test.go b/registry/common/event_publishing_service_deiscovery_test.go index 856a902d1c..1e08335e04 100644 --- a/registry/common/event_publishing_service_deiscovery_test.go +++ b/registry/common/event_publishing_service_deiscovery_test.go @@ -23,6 +23,8 @@ import ( ) import ( + gxset "github.com/dubbogo/gost/container/set" + gxpage "github.com/dubbogo/gost/page" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) @@ -32,8 +34,6 @@ import ( "github.com/apache/dubbo-go/common/observer" dispatcher2 "github.com/apache/dubbo-go/common/observer/dispatcher" "github.com/apache/dubbo-go/registry" - gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" ) func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { diff --git a/registry/common/event_publishing_service_discovery.go b/registry/common/event_publishing_service_discovery.go index 43d2917c32..f61dd84690 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/common/event_publishing_service_discovery.go @@ -18,14 +18,14 @@ package common import ( - "github.com/apache/dubbo-go/registry" + gxset "github.com/dubbogo/gost/container/set" + gxpage "github.com/dubbogo/gost/page" ) import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" - gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + "github.com/apache/dubbo-go/registry" ) // EventPublishingServiceDiscovery will enhance Service Discovery From 3e81841a3d70e24b81776ee3e39fe76c8e788c37 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sun, 10 May 2020 21:48:22 +0800 Subject: [PATCH 055/209] add unregister for Registry and FacadeBasedRegistry --- go.sum | 6 --- registry/base_registry.go | 72 ++++++++++++++++++++++++++++----- registry/consul/registry.go | 6 +-- registry/etcdv3/registry.go | 9 +++++ registry/kubernetes/registry.go | 10 +++++ registry/mock_registry.go | 6 +-- registry/nacos/registry.go | 4 +- registry/registry.go | 15 +++++-- registry/zookeeper/registry.go | 9 +++++ 9 files changed, 109 insertions(+), 28 deletions(-) diff --git a/go.sum b/go.sum index 326b4e6897..9bcb1fe457 100644 --- a/go.sum +++ b/go.sum @@ -35,11 +35,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apache/dubbo-go-hessian2 v1.5.0 h1:fzulDG5G7nX0ccgKdiN9XipJ7tZ4WXKgmk4stdlDS6s= github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -53,7 +50,6 @@ github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL6 github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -389,8 +385,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nacos-group/nacos-sdk-go v0.3.1 h1:MI7bNDAN5m9UFcRRUTSPfJi4dCQo+TYG85qVB1rCHeg= github.com/nacos-group/nacos-sdk-go v0.3.1/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= diff --git a/registry/base_registry.go b/registry/base_registry.go index 0b87a54d7d..4fc2ba4483 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -29,6 +29,7 @@ import ( ) import ( + gxset "github.com/dubbogo/gost/container/set" gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" ) @@ -74,8 +75,12 @@ type FacadeBasedRegistry interface { CreatePath(string) error // DoRegister actually do the register job DoRegister(string, string) error + // DoUnregister do the unregister job + DoUnregister(string, string) error // DoSubscribe actually subscribe the URL DoSubscribe(conf *common.URL) (Listener, error) + // DoUnsubscribe does unsubscribe the URL + DoUnsubscribe(svc *common.URL) error // CloseAndNilClient close the client and then reset the client in registry to nil // you should notice that this method will be invoked inside a lock. // So you should implement this method as light weighted as you can. @@ -91,11 +96,12 @@ type BaseRegistry struct { context context.Context facadeBasedRegistry FacadeBasedRegistry *common.URL - birth int64 // time of file birth, seconds since Epoch; 0 if unknown - wg sync.WaitGroup // wg+done for zk restart - done chan struct{} - cltLock sync.Mutex //ctl lock is a lock for services map - services map[string]common.URL // service name + protocol -> service config, for store the service registered + birth int64 // time of file birth, seconds since Epoch; 0 if unknown + wg sync.WaitGroup // wg+done for zk restart + done chan struct{} + cltLock sync.Mutex //ctl lock is a lock for services map + services map[string]common.URL // service name + protocol -> service config, for store the service registered + serviceListener map[string]*gxset.HashSet // service name + protocol -> service listener, for store the service listener registered } // InitBaseRegistry for init some local variables and set BaseRegistry's subclass to it @@ -156,6 +162,26 @@ func (r *BaseRegistry) Register(conf common.URL) error { // UnRegister func (r *BaseRegistry) UnRegister(conf common.URL) error { + var ( + ok bool + err error + ) + r.cltLock.Lock() + _, ok = r.services[conf.Key()] + r.cltLock.Unlock() + + if ok { + return perrors.Errorf("Path{%s} has not registered", conf.Key()) + } + + err = r.unregister(conf) + if err != nil { + return perrors.WithMessagef(err, "register(conf:%+v)", conf) + } + + r.cltLock.Lock() + delete(r.services, conf.Key()) + r.cltLock.Unlock() return nil } @@ -195,6 +221,15 @@ func (r *BaseRegistry) RestartCallBack() bool { // register for register url to registry, include init params func (r *BaseRegistry) register(c common.URL) error { + return r.processURL(c, r.facadeBasedRegistry.DoRegister) +} + +// unregister for unregister url to registry, include init params +func (r *BaseRegistry) unregister(c common.URL) error { + return r.processURL(c, r.facadeBasedRegistry.DoUnregister) +} + +func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error) error { var ( err error //revision string @@ -227,7 +262,7 @@ func (r *BaseRegistry) register(c common.URL) error { } encodedURL = url.QueryEscape(rawURL) dubboPath = strings.ReplaceAll(dubboPath, "$", "%24") - err = r.facadeBasedRegistry.DoRegister(dubboPath, encodedURL) + err = f(dubboPath, encodedURL) if err != nil { return perrors.WithMessagef(err, "register Node(path:%s, url:%s)", dubboPath, rawURL) @@ -329,8 +364,15 @@ func sleepWait(n int) { } // Subscribe :subscribe from registry, event will notify by notifyListener -func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { +func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener) { n := 0 + + r.cltLock.Lock() + set := r.serviceListener[url.Key()] + if set == nil { + r.serviceListener[url.Key()] = gxset.NewSet() + } + r.cltLock.Unlock() for { n++ if !r.IsAvailable() { @@ -356,7 +398,12 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) break } else { logger.Infof("update begin, service event: %v", serviceEvent.String()) - notifyListener.Notify(serviceEvent) + listener := *notifyListener + listener.Notify(serviceEvent) + r.cltLock.Lock() + set := r.serviceListener[url.Key()] + set.Add(listener) + r.cltLock.Unlock() } } @@ -365,8 +412,13 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } // UnSubscribe : -func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { - +func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener *NotifyListener) { + ////r.serviceListener[url.Key()] = notifyListener + //for index, configuration := range configurations { + // if configuration == a2 { + // configurations = append(configurations[:index], configurations[index+1:]...) + // } + //} } // closeRegisters close and remove registry client and reset services map diff --git a/registry/consul/registry.go b/registry/consul/registry.go index 415bf42860..c5ca7e1e0c 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -112,15 +112,15 @@ func (r *consulRegistry) unregister(url common.URL) error { return r.client.Agent().ServiceDeregister(buildId(url)) } -func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { +func (r *consulRegistry) Subscribe(url *common.URL, notifyListener *registry.NotifyListener) { role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) if role == common.CONSUMER { - r.subscribe(url, notifyListener) + r.subscribe(url, *notifyListener) } } // UnSubscribe : -func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { +func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener *registry.NotifyListener) { } diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index 5d389c3637..9b4bd4430b 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -114,6 +114,10 @@ func (r *etcdV3Registry) DoRegister(root string, node string) error { return r.client.Create(path.Join(root, node), "") } +func (r *etcdV3Registry) DoUnregister(root string, node string) error { + return r.client.Delete(path.Join(root, node)) +} + func (r *etcdV3Registry) CloseAndNilClient() { r.client.Close() r.client = nil @@ -168,3 +172,8 @@ func (r *etcdV3Registry) DoSubscribe(svc *common.URL) (registry.Listener, error) return configListener, nil } + +func (r *etcdV3Registry) DoUnsubscribe(svc *common.URL) error { + panic("DoUnsubscribe is not support in etcdV3Registry") + return nil +} diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index 8a02d0e3e6..61d2616b77 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -107,6 +107,11 @@ func (r *kubernetesRegistry) DoRegister(root string, node string) error { return r.client.Create(path.Join(root, node), "") } +func (r *kubernetesRegistry) DoUnregister(root string, node string) error { + panic("DoUnregister is not support in kubernetesRegistry") + return nil +} + func (r *kubernetesRegistry) DoSubscribe(svc *common.URL) (registry.Listener, error) { var ( @@ -139,6 +144,11 @@ func (r *kubernetesRegistry) DoSubscribe(svc *common.URL) (registry.Listener, er return configListener, nil } +func (r *kubernetesRegistry) DoUnsubscribe(svc *common.URL) error { + panic("DoUnsubscribe is not support in kubernetesRegistry") + return nil +} + func (r *kubernetesRegistry) InitListeners() { r.listener = kubernetes.NewEventListener(r.client) r.configListener = NewConfigurationListener(r) diff --git a/registry/mock_registry.go b/registry/mock_registry.go index e661981d0d..91165063f3 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -78,7 +78,7 @@ func (r *MockRegistry) subscribe(*common.URL) (Listener, error) { } // Subscribe ... -func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { +func (r *MockRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener) { go func() { for { if !r.IsAvailable() { @@ -106,14 +106,14 @@ func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } logger.Infof("update begin, service event: %v", serviceEvent.String()) - notifyListener.Notify(serviceEvent) + (*notifyListener).Notify(serviceEvent) } } }() } // UnSubscribe : -func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { +func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener *NotifyListener) { } diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index b2caa39459..6835378ce7 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -147,7 +147,7 @@ func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) } //subscribe from registry -func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { +func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener *registry.NotifyListener) { for { if !nr.IsAvailable() { logger.Warnf("event listener game over.") @@ -174,7 +174,7 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti } logger.Infof("update begin, service event: %v", serviceEvent.String()) - notifyListener.Notify(serviceEvent) + (*notifyListener).Notify(serviceEvent) } } diff --git a/registry/registry.go b/registry/registry.go index 65756202f1..17720779d3 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -34,7 +34,10 @@ type Registry interface { //And it is also used for service consumer calling , register services cared about ,for dubbo's admin monitoring. Register(url common.URL) error - // UnRegister ... + // UnRegister is required to support the contract: + // 1. If it is the persistent stored data of dynamic=false, the registration data can not be found, then the IllegalStateException is thrown, otherwise it is ignored. + // 2. Unregister according to the full url match. + // url Registration information , is not allowed to be empty, e.g: dubbo://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin UnRegister(url common.URL) error //When creating new registry extension,pls select one of the following modes. @@ -45,10 +48,14 @@ type Registry interface { //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). - Subscribe(*common.URL, NotifyListener) + Subscribe(*common.URL, *NotifyListener) - // UnSubscribe ... - UnSubscribe(*common.URL, NotifyListener) + // UnSubscribe is required to support the contract: + // 1. If don't subscribe, ignore it directly. + // 2. Unsubscribe by full URL match. + // url Subscription condition, not allowed to be empty, e.g. consumer://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin + // listener A listener of the change event, not allowed to be empty + UnSubscribe(*common.URL, *NotifyListener) } // NotifyListener ... diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 88d5d6221b..b4ec7be9da 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -20,6 +20,7 @@ package zookeeper import ( "fmt" "net/url" + "path" "sync" "time" ) @@ -149,10 +150,18 @@ func (r *zkRegistry) DoRegister(root string, node string) error { return r.registerTempZookeeperNode(root, node) } +func (r *zkRegistry) DoUnregister(root string, node string) error { + return r.ZkClient().Delete(path.Join(root, node)) +} + func (r *zkRegistry) DoSubscribe(conf *common.URL) (registry.Listener, error) { return r.getListener(conf) } +func (r *zkRegistry) DoUnsubscribe(svc *common.URL) error { + return nil +} + func (r *zkRegistry) CloseAndNilClient() { r.client.Close() r.client = nil From df74f8d36a42914532ac1f85597b2311c324efec Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sun, 10 May 2020 22:47:41 +0800 Subject: [PATCH 056/209] add test case for Registry unregister --- registry/base_registry.go | 3 +++ registry/zookeeper/registry_test.go | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/registry/base_registry.go b/registry/base_registry.go index 4fc2ba4483..0e2bdc9b1b 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -230,6 +230,9 @@ func (r *BaseRegistry) unregister(c common.URL) error { } func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error) error { + if f == nil { + panic(" Must provide a `function(string, string) error` to process URL. ") + } var ( err error //revision string diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index 688deccfbe..04a00d50cd 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -45,6 +45,24 @@ func Test_Register(t *testing.T) { assert.NoError(t, err) } +func Test_UnRegister(t *testing.T) { + // register + regurl, _ := common.NewURL("registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithParamsValue("serviceid", "soa.mock"), common.WithMethods([]string{"GetUser", "AddUser"})) + + ts, reg, _ := newMockZkRegistry(®url) + defer ts.Stop() + err := reg.Register(url) + children, _ := reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") + assert.Regexp(t, ".*dubbo%3A%2F%2F127.0.0.1%3A20000%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26cluster%3Dmock%26.*.serviceid%3Dsoa.mock", children) + assert.NoError(t, err) + + reg.UnRegister(url) + children, err = reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") + assert.Equal(t, len(children), 0) + assert.NoError(t, err) +} + func Test_Subscribe(t *testing.T) { regurl, _ := common.NewURL("registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"})) From 4970301f1c69240d86e1f7719444dbe52f506d4c Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 11 May 2020 15:16:03 +0800 Subject: [PATCH 057/209] modify test case for Registry unregister --- registry/base_registry.go | 6 +++--- registry/consul/registry.go | 6 +++--- registry/mock_registry.go | 6 +++--- registry/nacos/registry.go | 4 ++-- registry/registry.go | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 0e2bdc9b1b..5ebde2bc9a 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -367,7 +367,7 @@ func sleepWait(n int) { } // Subscribe :subscribe from registry, event will notify by notifyListener -func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener) { +func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { n := 0 r.cltLock.Lock() @@ -401,7 +401,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener break } else { logger.Infof("update begin, service event: %v", serviceEvent.String()) - listener := *notifyListener + listener := notifyListener listener.Notify(serviceEvent) r.cltLock.Lock() set := r.serviceListener[url.Key()] @@ -415,7 +415,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener } // UnSubscribe : -func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener *NotifyListener) { +func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { ////r.serviceListener[url.Key()] = notifyListener //for index, configuration := range configurations { // if configuration == a2 { diff --git a/registry/consul/registry.go b/registry/consul/registry.go index c5ca7e1e0c..415bf42860 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -112,15 +112,15 @@ func (r *consulRegistry) unregister(url common.URL) error { return r.client.Agent().ServiceDeregister(buildId(url)) } -func (r *consulRegistry) Subscribe(url *common.URL, notifyListener *registry.NotifyListener) { +func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) if role == common.CONSUMER { - r.subscribe(url, *notifyListener) + r.subscribe(url, notifyListener) } } // UnSubscribe : -func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener *registry.NotifyListener) { +func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { } diff --git a/registry/mock_registry.go b/registry/mock_registry.go index 91165063f3..e661981d0d 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -78,7 +78,7 @@ func (r *MockRegistry) subscribe(*common.URL) (Listener, error) { } // Subscribe ... -func (r *MockRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener) { +func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { go func() { for { if !r.IsAvailable() { @@ -106,14 +106,14 @@ func (r *MockRegistry) Subscribe(url *common.URL, notifyListener *NotifyListener } logger.Infof("update begin, service event: %v", serviceEvent.String()) - (*notifyListener).Notify(serviceEvent) + notifyListener.Notify(serviceEvent) } } }() } // UnSubscribe : -func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener *NotifyListener) { +func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { } diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index 6835378ce7..b2caa39459 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -147,7 +147,7 @@ func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) } //subscribe from registry -func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener *registry.NotifyListener) { +func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { for { if !nr.IsAvailable() { logger.Warnf("event listener game over.") @@ -174,7 +174,7 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener *registry.Not } logger.Infof("update begin, service event: %v", serviceEvent.String()) - (*notifyListener).Notify(serviceEvent) + notifyListener.Notify(serviceEvent) } } diff --git a/registry/registry.go b/registry/registry.go index 17720779d3..740296937f 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -48,14 +48,14 @@ type Registry interface { //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). - Subscribe(*common.URL, *NotifyListener) + Subscribe(*common.URL, NotifyListener) // UnSubscribe is required to support the contract: // 1. If don't subscribe, ignore it directly. // 2. Unsubscribe by full URL match. // url Subscription condition, not allowed to be empty, e.g. consumer://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin // listener A listener of the change event, not allowed to be empty - UnSubscribe(*common.URL, *NotifyListener) + UnSubscribe(*common.URL, NotifyListener) } // NotifyListener ... From 69ace5ea6524054e4891dc66741d38bc4d1c4a66 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 11 May 2020 15:44:46 +0800 Subject: [PATCH 058/209] modify test case for Registry unregister --- registry/base_registry.go | 2 +- registry/zookeeper/registry_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 5ebde2bc9a..83ceb60e74 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -170,7 +170,7 @@ func (r *BaseRegistry) UnRegister(conf common.URL) error { _, ok = r.services[conf.Key()] r.cltLock.Unlock() - if ok { + if !ok { return perrors.Errorf("Path{%s} has not registered", conf.Key()) } diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index 04a00d50cd..9ae0027daf 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -57,10 +57,10 @@ func Test_UnRegister(t *testing.T) { assert.Regexp(t, ".*dubbo%3A%2F%2F127.0.0.1%3A20000%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26cluster%3Dmock%26.*.serviceid%3Dsoa.mock", children) assert.NoError(t, err) - reg.UnRegister(url) + err = reg.UnRegister(url) children, err = reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") - assert.Equal(t, len(children), 0) - assert.NoError(t, err) + assert.Equal(t, 0, len(children)) + assert.Error(t, err) } func Test_Subscribe(t *testing.T) { From e73f3bf0fe97ac51019a1afa03310e601ac767cb Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Mon, 11 May 2020 21:02:05 +0800 Subject: [PATCH 059/209] fix impl_test error --- config_center/nacos/impl_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/config_center/nacos/impl_test.go b/config_center/nacos/impl_test.go index b74c155d92..b0a54b8d37 100644 --- a/config_center/nacos/impl_test.go +++ b/config_center/nacos/impl_test.go @@ -132,8 +132,6 @@ func Test_AddListener(t *testing.T) { listener := &mockDataListener{} time.Sleep(time.Second * 2) nacos.AddListener("dubbo.properties", listener) - listener.wg.Add(1) - listener.wg.Wait() } func Test_RemoveListener(t *testing.T) { From 322eb5ff09b9e630e33bdbb1d4da4dc463ffe58b Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 11 May 2020 23:18:58 +0800 Subject: [PATCH 060/209] add Registry unsubscribe --- registry/base_registry.go | 50 ++++++++++++--------------------- registry/etcdv3/registry.go | 4 +-- registry/kubernetes/registry.go | 4 +-- registry/zookeeper/listener.go | 12 ++++++++ registry/zookeeper/registry.go | 38 +++++++++++++++++++++++-- 5 files changed, 70 insertions(+), 38 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 83ceb60e74..27feaef91f 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -29,7 +29,6 @@ import ( ) import ( - gxset "github.com/dubbogo/gost/container/set" gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" ) @@ -80,7 +79,7 @@ type FacadeBasedRegistry interface { // DoSubscribe actually subscribe the URL DoSubscribe(conf *common.URL) (Listener, error) // DoUnsubscribe does unsubscribe the URL - DoUnsubscribe(svc *common.URL) error + DoUnsubscribe(conf *common.URL) (Listener, error) // CloseAndNilClient close the client and then reset the client in registry to nil // you should notice that this method will be invoked inside a lock. // So you should implement this method as light weighted as you can. @@ -96,12 +95,11 @@ type BaseRegistry struct { context context.Context facadeBasedRegistry FacadeBasedRegistry *common.URL - birth int64 // time of file birth, seconds since Epoch; 0 if unknown - wg sync.WaitGroup // wg+done for zk restart - done chan struct{} - cltLock sync.Mutex //ctl lock is a lock for services map - services map[string]common.URL // service name + protocol -> service config, for store the service registered - serviceListener map[string]*gxset.HashSet // service name + protocol -> service listener, for store the service listener registered + birth int64 // time of file birth, seconds since Epoch; 0 if unknown + wg sync.WaitGroup // wg+done for zk restart + done chan struct{} + cltLock sync.Mutex //ctl lock is a lock for services map + services map[string]common.URL // service name + protocol -> service config, for store the service registered } // InitBaseRegistry for init some local variables and set BaseRegistry's subclass to it @@ -368,14 +366,17 @@ func sleepWait(n int) { // Subscribe :subscribe from registry, event will notify by notifyListener func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { - n := 0 + r.processSubscribe(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) +} - r.cltLock.Lock() - set := r.serviceListener[url.Key()] - if set == nil { - r.serviceListener[url.Key()] = gxset.NewSet() - } - r.cltLock.Unlock() +// UnSubscribe : +func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { + r.processSubscribe(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) +} + +// process Subscribe or UnSubscribe +func (r *BaseRegistry) processSubscribe(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) { + n := 0 for { n++ if !r.IsAvailable() { @@ -383,7 +384,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) return } - listener, err := r.facadeBasedRegistry.DoSubscribe(url) + listener, err := f(url) if err != nil { if !r.IsAvailable() { logger.Warnf("event listener game over.") @@ -401,12 +402,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) break } else { logger.Infof("update begin, service event: %v", serviceEvent.String()) - listener := notifyListener - listener.Notify(serviceEvent) - r.cltLock.Lock() - set := r.serviceListener[url.Key()] - set.Add(listener) - r.cltLock.Unlock() + notifyListener.Notify(serviceEvent) } } @@ -414,16 +410,6 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } } -// UnSubscribe : -func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { - ////r.serviceListener[url.Key()] = notifyListener - //for index, configuration := range configurations { - // if configuration == a2 { - // configurations = append(configurations[:index], configurations[index+1:]...) - // } - //} -} - // closeRegisters close and remove registry client and reset services map func (r *BaseRegistry) closeRegisters() { logger.Infof("begin to close provider client") diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index 9b4bd4430b..60a2eadd93 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -173,7 +173,7 @@ func (r *etcdV3Registry) DoSubscribe(svc *common.URL) (registry.Listener, error) return configListener, nil } -func (r *etcdV3Registry) DoUnsubscribe(svc *common.URL) error { +func (r *etcdV3Registry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) { panic("DoUnsubscribe is not support in etcdV3Registry") - return nil + return nil, nil } diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index 61d2616b77..db3e6ee440 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -144,9 +144,9 @@ func (r *kubernetesRegistry) DoSubscribe(svc *common.URL) (registry.Listener, er return configListener, nil } -func (r *kubernetesRegistry) DoUnsubscribe(svc *common.URL) error { +func (r *kubernetesRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) { panic("DoUnsubscribe is not support in kubernetesRegistry") - return nil + return nil, nil } func (r *kubernetesRegistry) InitListeners() { diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index c5b2f33c61..f428f0f719 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -56,6 +56,18 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen l.subscribed[url] = listener } +// SubscribeURL is used to set a watch listener for url +func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.ConfigurationListener { + if l.closed { + return nil + } + l.mutex.Lock() + listener := l.subscribed[url] + delete(l.subscribed, url) + l.mutex.Unlock() + return listener +} + // DataChange accepts all events sent from the zookeeper server and trigger the corresponding listener for processing func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool { // Intercept the last bit diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index b4ec7be9da..3811811bf7 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -158,8 +158,8 @@ func (r *zkRegistry) DoSubscribe(conf *common.URL) (registry.Listener, error) { return r.getListener(conf) } -func (r *zkRegistry) DoUnsubscribe(svc *common.URL) error { - return nil +func (r *zkRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) { + return r.getCloseListener(conf) } func (r *zkRegistry) CloseAndNilClient() { @@ -264,3 +264,37 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen return zkListener, nil } + +func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationListener, error) { + + var zkListener *RegistryConfigurationListener + dataListener := r.dataListener + dataListener.mutex.Lock() + defer dataListener.mutex.Unlock() + if r.dataListener.subscribed[conf] != nil { + + zkListener, _ := r.dataListener.subscribed[conf].(*RegistryConfigurationListener) + if zkListener != nil { + r.listenerLock.Lock() + defer r.listenerLock.Unlock() + if zkListener.isClosed { + return nil, perrors.New("configListener already been closed") + } else { + return zkListener, nil + } + } + } + + zkListener = r.dataListener.UnSubscribeURL(conf).(*RegistryConfigurationListener) + if r.listener == nil { + return nil, perrors.New("listener is null can not close.") + } + + //Interested register to dataconfig. + r.listenerLock.Lock() + r.dataListener.Close() + r.listener.Close() + r.listenerLock.Unlock() + + return zkListener, nil +} From 393d12a88ca88ee5df894e640b10c9aa9760f97f Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Tue, 12 May 2020 21:01:01 +0800 Subject: [PATCH 061/209] fix import error --- common/extension/service_name_mapping.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 795595905d..2935f49d81 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -17,19 +17,17 @@ package extension -import ( - "github.com/apache/dubbo-go/metadata" -) +import "github.com/apache/dubbo-go/metadata/mapping" var ( - nameMappings = make(map[string]func() metadata.ServiceNameMapping) + nameMappings = make(map[string]func() mapping.ServiceNameMapping) ) -func SetServiceNameMapping(name string, creator func() metadata.ServiceNameMapping) { +func SetServiceNameMapping(name string, creator func() mapping.ServiceNameMapping) { nameMappings[name] = creator } -func GetServiceNameMapping(name string) metadata.ServiceNameMapping { +func GetServiceNameMapping(name string) mapping.ServiceNameMapping { creator, ok := nameMappings[name] if !ok { panic("Can not find the target service name mapping: " + name) From 31f8663600d209e42ff37b9071823231be543f32 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 12 May 2020 22:40:06 +0800 Subject: [PATCH 062/209] change lock granularity --- registry/zookeeper/listener.go | 4 ++-- registry/zookeeper/registry.go | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index f428f0f719..61a69c587f 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -58,13 +58,13 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen // SubscribeURL is used to set a watch listener for url func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.ConfigurationListener { + l.mutex.Lock() + defer l.mutex.Unlock() if l.closed { return nil } - l.mutex.Lock() listener := l.subscribed[url] delete(l.subscribed, url) - l.mutex.Unlock() return listener } diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 3811811bf7..06197920bb 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -285,16 +285,19 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL } } - zkListener = r.dataListener.UnSubscribeURL(conf).(*RegistryConfigurationListener) + zkListener = dataListener.UnSubscribeURL(conf).(*RegistryConfigurationListener) if r.listener == nil { return nil, perrors.New("listener is null can not close.") } //Interested register to dataconfig. r.listenerLock.Lock() - r.dataListener.Close() - r.listener.Close() + listener := r.listener + r.listener = nil r.listenerLock.Unlock() + dataListener.Close() + listener.Close() + return zkListener, nil } From 341bc5fbfab8f4e2d8dba9f930cc82fa9ece945e Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 12 May 2020 22:43:38 +0800 Subject: [PATCH 063/209] add panic for not support implement --- registry/consul/registry.go | 2 +- registry/nacos/registry.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/consul/registry.go b/registry/consul/registry.go index 415bf42860..5a4524c047 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -121,7 +121,7 @@ func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.Noti // UnSubscribe : func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { - + panic(" UnSubscribe not support in consulRegistry ") } func (r *consulRegistry) subscribe(url *common.URL, notifyListener registry.NotifyListener) { diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index b2caa39459..e70de75708 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -138,7 +138,7 @@ func (nr *nacosRegistry) Register(url common.URL) error { // UnRegister func (nr *nacosRegistry) UnRegister(conf common.URL) error { - + panic(" UnRegister not support in nacosRegistry ") return nil } @@ -182,7 +182,7 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti // UnSubscribe : func (nr *nacosRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { - + panic(" UnSubscribe not support in nacosRegistry ") } func (nr *nacosRegistry) GetUrl() common.URL { From aaeabc662e2a568ef1002d98c19beca3c5a39f75 Mon Sep 17 00:00:00 2001 From: lizhipeng Date: Tue, 12 May 2020 23:44:26 +0800 Subject: [PATCH 064/209] fix import error --- metadata/mapping/dynamic/service_name_mapping.go | 4 ++-- metadata/mapping/memory/service_name_mapping.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index bf578d54ac..49b7747065 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -18,6 +18,7 @@ package dynamic import ( + "github.com/apache/dubbo-go/metadata/mapping" "strconv" "sync" "time" @@ -33,7 +34,6 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/config_center" - "github.com/apache/dubbo-go/metadata" ) const ( @@ -84,7 +84,7 @@ var ( ) // GetServiceNameMappingInstance will return an instance of DynamicConfigurationServiceNameMapping -func GetServiceNameMappingInstance() metadata.ServiceNameMapping { +func GetServiceNameMappingInstance() mapping.ServiceNameMapping { serviceNameMappingInitOnce.Do(func() { dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc} diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go index cf051a11e4..747753a140 100644 --- a/metadata/mapping/memory/service_name_mapping.go +++ b/metadata/mapping/memory/service_name_mapping.go @@ -18,6 +18,7 @@ package memory import ( + "github.com/apache/dubbo-go/metadata/mapping" "sync" ) @@ -28,7 +29,6 @@ import ( import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/config" - "github.com/apache/dubbo-go/metadata" ) func init() { @@ -50,7 +50,7 @@ var ( nameMappingInitOnce sync.Once ) -func GetInMemoryServiceNameMappingInstance() metadata.ServiceNameMapping { +func GetInMemoryServiceNameMappingInstance() mapping.ServiceNameMapping { nameMappingInitOnce.Do(func() { nameMappingInstance = &InMemoryServiceNameMapping{} }) From f1d5aa497cd13a0654fced01cdb024cdfc34f54d Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Thu, 14 May 2020 00:24:35 +0800 Subject: [PATCH 065/209] fix review problems --- registry/base_registry.go | 71 +++++++++++++++++----------------- registry/zookeeper/listener.go | 2 +- registry/zookeeper/registry.go | 5 +++ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 27feaef91f..75c0f45d42 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -161,11 +161,13 @@ func (r *BaseRegistry) Register(conf common.URL) error { // UnRegister func (r *BaseRegistry) UnRegister(conf common.URL) error { var ( - ok bool - err error + ok bool + err error + oldURL common.URL ) r.cltLock.Lock() - _, ok = r.services[conf.Key()] + oldURL, ok = r.services[conf.Key()] + delete(r.services, conf.Key()) r.cltLock.Unlock() if !ok { @@ -174,13 +176,12 @@ func (r *BaseRegistry) UnRegister(conf common.URL) error { err = r.unregister(conf) if err != nil { + r.cltLock.Lock() + r.services[conf.Key()] = oldURL + r.cltLock.Unlock() return perrors.WithMessagef(err, "register(conf:%+v)", conf) } - r.cltLock.Lock() - delete(r.services, conf.Key()) - r.cltLock.Unlock() - return nil } @@ -219,15 +220,15 @@ func (r *BaseRegistry) RestartCallBack() bool { // register for register url to registry, include init params func (r *BaseRegistry) register(c common.URL) error { - return r.processURL(c, r.facadeBasedRegistry.DoRegister) + return r.processURL(c, r.facadeBasedRegistry.DoRegister, r.createPath) } // unregister for unregister url to registry, include init params func (r *BaseRegistry) unregister(c common.URL) error { - return r.processURL(c, r.facadeBasedRegistry.DoUnregister) + return r.processURL(c, r.facadeBasedRegistry.DoUnregister, nil) } -func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error) error { +func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error, createPathFunc func(dubboPath string) error) error { if f == nil { panic(" Must provide a `function(string, string) error` to process URL. ") } @@ -255,9 +256,9 @@ func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error) er switch role { case common.PROVIDER: - dubboPath, rawURL, err = r.providerRegistry(c, params) + dubboPath, rawURL, err = r.providerRegistry(c, params, createPathFunc) case common.CONSUMER: - dubboPath, rawURL, err = r.consumerRegistry(c, params) + dubboPath, rawURL, err = r.consumerRegistry(c, params, createPathFunc) default: return perrors.Errorf("@c{%v} type is not referencer or provider", c) } @@ -271,8 +272,15 @@ func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error) er return nil } +// createPath will create dubbo path in register +func (r *BaseRegistry) createPath(dubboPath string) error { + r.cltLock.Lock() + defer r.cltLock.Unlock() + return r.facadeBasedRegistry.CreatePath(dubboPath) +} + // providerRegistry for provider role do -func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values) (string, string, error) { +func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values, createPathFunc func(dubboPath string) error) (string, string, error) { var ( dubboPath string rawURL string @@ -282,11 +290,9 @@ func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values) (string return "", "", perrors.Errorf("conf{Path:%s, Methods:%s}", c.Path, c.Methods) } dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.PROVIDER]) - func() { - r.cltLock.Lock() - defer r.cltLock.Unlock() - err = r.facadeBasedRegistry.CreatePath(dubboPath) - }() + if createPathFunc != nil { + err = createPathFunc(dubboPath) + } if err != nil { logger.Errorf("facadeBasedRegistry.CreatePath(path{%s}) = error{%#v}", dubboPath, perrors.WithStack(err)) return "", "", perrors.WithMessagef(err, "facadeBasedRegistry.CreatePath(path:%s)", dubboPath) @@ -316,7 +322,7 @@ func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values) (string } // consumerRegistry for consumer role do -func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values) (string, string, error) { +func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values, createPathFunc func(dubboPath string) error) (string, string, error) { var ( dubboPath string rawURL string @@ -324,23 +330,18 @@ func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values) (string ) dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.CONSUMER]) - func() { - r.cltLock.Lock() - defer r.cltLock.Unlock() - err = r.facadeBasedRegistry.CreatePath(dubboPath) - - }() + if createPathFunc != nil { + err = createPathFunc(dubboPath) + } if err != nil { logger.Errorf("facadeBasedRegistry.CreatePath(path{%s}) = error{%v}", dubboPath, perrors.WithStack(err)) return "", "", perrors.WithStack(err) } dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.PROVIDER]) - func() { - r.cltLock.Lock() - defer r.cltLock.Unlock() - err = r.facadeBasedRegistry.CreatePath(dubboPath) - }() + if createPathFunc != nil { + err = createPathFunc(dubboPath) + } if err != nil { logger.Errorf("facadeBasedRegistry.CreatePath(path{%s}) = error{%v}", dubboPath, perrors.WithStack(err)) @@ -366,16 +367,16 @@ func sleepWait(n int) { // Subscribe :subscribe from registry, event will notify by notifyListener func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { - r.processSubscribe(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) + r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) } -// UnSubscribe : +// UnSubscribe :UnSubscribeURL func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { - r.processSubscribe(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) + r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) } -// process Subscribe or UnSubscribe -func (r *BaseRegistry) processSubscribe(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) { +// processNotify can process notify listener when Subscribe or UnSubscribe +func (r *BaseRegistry) processNotify(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) { n := 0 for { n++ diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index 61a69c587f..10e37d4125 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -56,7 +56,7 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen l.subscribed[url] = listener } -// SubscribeURL is used to set a watch listener for url +// UnSubscribeURL is used to set a watch listener for url func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.ConfigurationListener { l.mutex.Lock() defer l.mutex.Unlock() diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 06197920bb..a021cbae4d 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -151,6 +151,11 @@ func (r *zkRegistry) DoRegister(root string, node string) error { } func (r *zkRegistry) DoUnregister(root string, node string) error { + r.cltLock.Lock() + defer r.cltLock.Unlock() + if !r.ZkClient().ZkConnValid() { + return perrors.Errorf("zk client is not valid.") + } return r.ZkClient().Delete(path.Join(root, node)) } From ce89e9b4e3cd33da6e27450bbf43b8b0ca6e677d Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Fri, 15 May 2020 19:09:18 +0800 Subject: [PATCH 066/209] fix review comments --- registry/base_registry.go | 94 +++++++++++++++++------------ registry/consul/registry.go | 7 ++- registry/etcdv3/registry.go | 3 +- registry/kubernetes/registry.go | 3 +- registry/mock_registry.go | 7 ++- registry/nacos/registry.go | 10 +-- registry/registry.go | 4 +- registry/zookeeper/listener.go | 2 - registry/zookeeper/registry.go | 21 +++---- registry/zookeeper/registry_test.go | 33 ++++++++++ remoting/zookeeper/listener.go | 1 + 11 files changed, 115 insertions(+), 70 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 75c0f45d42..17dfdcbe19 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -98,7 +98,7 @@ type BaseRegistry struct { birth int64 // time of file birth, seconds since Epoch; 0 if unknown wg sync.WaitGroup // wg+done for zk restart done chan struct{} - cltLock sync.Mutex //ctl lock is a lock for services map + cltLock sync.RWMutex //ctl lock is a lock for services map services map[string]common.URL // service name + protocol -> service config, for store the service registered } @@ -138,9 +138,9 @@ func (r *BaseRegistry) Register(conf common.URL) error { ) role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) // Check if the service has been registered - r.cltLock.Lock() + r.cltLock.RLock() _, ok = r.services[conf.Key()] - r.cltLock.Unlock() + r.cltLock.RUnlock() if ok { return perrors.Errorf("Path{%s} has been registered", conf.Key()) } @@ -165,10 +165,17 @@ func (r *BaseRegistry) UnRegister(conf common.URL) error { err error oldURL common.URL ) - r.cltLock.Lock() - oldURL, ok = r.services[conf.Key()] - delete(r.services, conf.Key()) - r.cltLock.Unlock() + func() { + r.cltLock.RLock() + defer r.cltLock.RUnlock() + oldURL, ok = r.services[conf.Key()] + }() + + func() { + r.cltLock.RLock() + defer r.cltLock.Unlock() + delete(r.services, conf.Key()) + }() if !ok { return perrors.Errorf("Path{%s} has not registered", conf.Key()) @@ -176,9 +183,11 @@ func (r *BaseRegistry) UnRegister(conf common.URL) error { err = r.unregister(conf) if err != nil { - r.cltLock.Lock() - r.services[conf.Key()] = oldURL - r.cltLock.Unlock() + func() { + r.cltLock.Lock() + defer r.cltLock.Unlock() + r.services[conf.Key()] = oldURL + }() return perrors.WithMessagef(err, "register(conf:%+v)", conf) } @@ -366,49 +375,54 @@ func sleepWait(n int) { } // Subscribe :subscribe from registry, event will notify by notifyListener -func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { - r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) +func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) error { + n := 0 + for { + n++ + err := r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) + if err == nil { + return nil + } + sleepWait(n) + } } // UnSubscribe :UnSubscribeURL -func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { - r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) +func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error { + return r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) } // processNotify can process notify listener when Subscribe or UnSubscribe -func (r *BaseRegistry) processNotify(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) { - n := 0 - for { - n++ +func (r *BaseRegistry) processNotify(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) error { + + if !r.IsAvailable() { + logger.Warnf("event listener game over.") + return nil + } + + listener, err := f(url) + if err != nil { if !r.IsAvailable() { logger.Warnf("event listener game over.") - return + return nil } + logger.Warnf("getListener() = err:%v", perrors.WithStack(err)) + time.Sleep(time.Duration(RegistryConnDelay) * time.Second) + return perrors.WithStack(err) + } - listener, err := f(url) - if err != nil { - if !r.IsAvailable() { - logger.Warnf("event listener game over.") - return - } - logger.Warnf("getListener() = err:%v", perrors.WithStack(err)) - time.Sleep(time.Duration(RegistryConnDelay) * time.Second) - continue + for { + if serviceEvent, err := listener.Next(); err != nil { + logger.Warnf("Selector.watch() = error{%v}", perrors.WithStack(err)) + listener.Close() + break + } else { + logger.Infof("update begin, service event: %v", serviceEvent.String()) + notifyListener.Notify(serviceEvent) } - for { - if serviceEvent, err := listener.Next(); err != nil { - logger.Warnf("Selector.watch() = error{%v}", perrors.WithStack(err)) - listener.Close() - break - } else { - logger.Infof("update begin, service event: %v", serviceEvent.String()) - notifyListener.Notify(serviceEvent) - } - - } - sleepWait(n) } + return nil } // closeRegisters close and remove registry client and reset services map diff --git a/registry/consul/registry.go b/registry/consul/registry.go index 5a4524c047..c9e0718346 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -112,16 +112,17 @@ func (r *consulRegistry) unregister(url common.URL) error { return r.client.Agent().ServiceDeregister(buildId(url)) } -func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { +func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) error { role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) if role == common.CONSUMER { r.subscribe(url, notifyListener) } + return nil } // UnSubscribe : -func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { - panic(" UnSubscribe not support in consulRegistry ") +func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) error { + return perrors.New("UnSubscribe not support in consulRegistry") } func (r *consulRegistry) subscribe(url *common.URL, notifyListener registry.NotifyListener) { diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index 60a2eadd93..a2722a2e67 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -174,6 +174,5 @@ func (r *etcdV3Registry) DoSubscribe(svc *common.URL) (registry.Listener, error) } func (r *etcdV3Registry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) { - panic("DoUnsubscribe is not support in etcdV3Registry") - return nil, nil + return nil, perrors.New("DoUnsubscribe is not support in etcdV3Registry") } diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index db3e6ee440..e64f9acb07 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -145,8 +145,7 @@ func (r *kubernetesRegistry) DoSubscribe(svc *common.URL) (registry.Listener, er } func (r *kubernetesRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) { - panic("DoUnsubscribe is not support in kubernetesRegistry") - return nil, nil + return nil, perrors.New("DoUnsubscribe is not support in kubernetesRegistry") } func (r *kubernetesRegistry) InitListeners() { diff --git a/registry/mock_registry.go b/registry/mock_registry.go index e661981d0d..ddf445ac8a 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -78,7 +78,7 @@ func (r *MockRegistry) subscribe(*common.URL) (Listener, error) { } // Subscribe ... -func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) { +func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) error { go func() { for { if !r.IsAvailable() { @@ -110,11 +110,12 @@ func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } } }() + return nil } // UnSubscribe : -func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) { - +func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error { + return nil } type listener struct { diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index e70de75708..6c8749ff38 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -138,8 +138,7 @@ func (nr *nacosRegistry) Register(url common.URL) error { // UnRegister func (nr *nacosRegistry) UnRegister(conf common.URL) error { - panic(" UnRegister not support in nacosRegistry ") - return nil + return perrors.New("UnRegister is not support in nacosRegistry") } func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) { @@ -147,7 +146,7 @@ func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) } //subscribe from registry -func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) { +func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) error { for { if !nr.IsAvailable() { logger.Warnf("event listener game over.") @@ -178,11 +177,12 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti } } + return nil } // UnSubscribe : -func (nr *nacosRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) { - panic(" UnSubscribe not support in nacosRegistry ") +func (nr *nacosRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) error { + return perrors.New("UnSubscribe not support in nacosRegistry") } func (nr *nacosRegistry) GetUrl() common.URL { diff --git a/registry/registry.go b/registry/registry.go index 740296937f..74e63aa66e 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -48,14 +48,14 @@ type Registry interface { //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). - Subscribe(*common.URL, NotifyListener) + Subscribe(*common.URL, NotifyListener) error // UnSubscribe is required to support the contract: // 1. If don't subscribe, ignore it directly. // 2. Unsubscribe by full URL match. // url Subscription condition, not allowed to be empty, e.g. consumer://10.20.153.10/org.apache.dubbo.foo.BarService?version=1.0.0&application=kylin // listener A listener of the change event, not allowed to be empty - UnSubscribe(*common.URL, NotifyListener) + UnSubscribe(*common.URL, NotifyListener) error } // NotifyListener ... diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index 10e37d4125..d0220ddf0d 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -58,8 +58,6 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen // UnSubscribeURL is used to set a watch listener for url func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.ConfigurationListener { - l.mutex.Lock() - defer l.mutex.Unlock() if l.closed { return nil } diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index a021cbae4d..f51ec67186 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -273,24 +273,24 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationListener, error) { var zkListener *RegistryConfigurationListener - dataListener := r.dataListener - dataListener.mutex.Lock() - defer dataListener.mutex.Unlock() - if r.dataListener.subscribed[conf] != nil { + r.dataListener.mutex.Lock() + configurationListener := r.dataListener.subscribed[conf] + if configurationListener != nil { - zkListener, _ := r.dataListener.subscribed[conf].(*RegistryConfigurationListener) + zkListener, _ := configurationListener.(*RegistryConfigurationListener) if zkListener != nil { r.listenerLock.Lock() - defer r.listenerLock.Unlock() if zkListener.isClosed { + r.listenerLock.Unlock() return nil, perrors.New("configListener already been closed") - } else { - return zkListener, nil } + r.listenerLock.Unlock() } } - zkListener = dataListener.UnSubscribeURL(conf).(*RegistryConfigurationListener) + zkListener = r.dataListener.UnSubscribeURL(conf).(*RegistryConfigurationListener) + r.dataListener.mutex.Unlock() + if r.listener == nil { return nil, perrors.New("listener is null can not close.") } @@ -299,9 +299,8 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL r.listenerLock.Lock() listener := r.listener r.listener = nil - r.listenerLock.Unlock() - dataListener.Close() + r.dataListener.Close() listener.Close() return zkListener, nil diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index 9ae0027daf..b7451f9543 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -92,6 +92,39 @@ func Test_Subscribe(t *testing.T) { defer ts.Stop() } +func Test_NoSubscribe(t *testing.T) { + regurl, _ := common.NewURL("registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"})) + ts, reg, _ := newMockZkRegistry(®url) + + //provider register + err := reg.Register(url) + assert.NoError(t, err) + + if err != nil { + return + } + + //consumer register + regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)) + _, reg2, _ := newMockZkRegistry(®url, zookeeper.WithTestCluster(ts)) + + reg2.Register(url) + listener, _ := reg2.DoSubscribe(&url) + + serviceEvent, _ := listener.Next() + assert.NoError(t, err) + if err != nil { + return + } + assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent.String()) + + reg2.DoUnsubscribe(&url) + assert.Nil(t, reg2.listener) + + defer ts.Stop() +} + func Test_ConsumerDestory(t *testing.T) { regurl, _ := common.NewURL("registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))) url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"})) diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 8487766776..6c9d072385 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -316,5 +316,6 @@ func (l *ZkEventListener) valid() bool { // Close ... func (l *ZkEventListener) Close() { + close(l.client.exit) l.wg.Wait() } From 50c24b1dbc5dacdca68922ec4abddaee7b881072 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sat, 16 May 2020 13:50:10 +0800 Subject: [PATCH 067/209] fix review comments --- registry/base_registry.go | 23 ++++++++++++----------- registry/nacos/registry.go | 6 +++--- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 17dfdcbe19..3a9569740f 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -138,9 +138,9 @@ func (r *BaseRegistry) Register(conf common.URL) error { ) role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) // Check if the service has been registered - r.cltLock.RLock() + r.cltLock.Lock() _, ok = r.services[conf.Key()] - r.cltLock.RUnlock() + r.cltLock.Unlock() if ok { return perrors.Errorf("Path{%s} has been registered", conf.Key()) } @@ -158,27 +158,28 @@ func (r *BaseRegistry) Register(conf common.URL) error { return nil } -// UnRegister +// UnRegister implement interface registry to unregister func (r *BaseRegistry) UnRegister(conf common.URL) error { var ( ok bool err error oldURL common.URL ) - func() { - r.cltLock.RLock() - defer r.cltLock.RUnlock() - oldURL, ok = r.services[conf.Key()] - }() func() { - r.cltLock.RLock() + r.cltLock.Lock() defer r.cltLock.Unlock() + oldURL, ok = r.services[conf.Key()] + + if !ok { + err = perrors.Errorf("Path{%s} has not registered", conf.Key()) + } + delete(r.services, conf.Key()) }() - if !ok { - return perrors.Errorf("Path{%s} has not registered", conf.Key()) + if err != nil { + return err } err = r.unregister(conf) diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index 6c8749ff38..c98bbc7843 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -150,14 +150,14 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti for { if !nr.IsAvailable() { logger.Warnf("event listener game over.") - return + return perrors.New("nacosRegistry is not available.") } listener, err := nr.subscribe(url) if err != nil { if !nr.IsAvailable() { logger.Warnf("event listener game over.") - return + return err } logger.Warnf("getListener() = err:%v", perrors.WithStack(err)) time.Sleep(time.Duration(RegistryConnDelay) * time.Second) @@ -169,7 +169,7 @@ func (nr *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.Noti if err != nil { logger.Warnf("Selector.watch() = error{%v}", perrors.WithStack(err)) listener.Close() - return + return err } logger.Infof("update begin, service event: %v", serviceEvent.String()) From f3a78454d495b81aa5f65e3d89befa50c2478dcf Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sat, 16 May 2020 14:13:18 +0800 Subject: [PATCH 068/209] add comment and test case --- registry/zookeeper/registry_test.go | 7 +++++++ remoting/zookeeper/listener.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index b7451f9543..d4141e8012 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -61,6 +61,13 @@ func Test_UnRegister(t *testing.T) { children, err = reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") assert.Equal(t, 0, len(children)) assert.Error(t, err) + assert.True(t, reg.IsAvailable()) + + err = reg.Register(url) + children, _ = reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") + assert.Regexp(t, ".*dubbo%3A%2F%2F127.0.0.1%3A20000%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26cluster%3Dmock%26.*.serviceid%3Dsoa.mock", children) + assert.NoError(t, err) + } func Test_Subscribe(t *testing.T) { diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 6c9d072385..097106acf6 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -314,7 +314,7 @@ func (l *ZkEventListener) valid() bool { return l.client.ZkConnValid() } -// Close ... +// Close will let client listen exit func (l *ZkEventListener) Close() { close(l.client.exit) l.wg.Wait() From 0048609d9bedde83cca98c2d03b98d376d50dca4 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 17 May 2020 16:27:09 +0800 Subject: [PATCH 069/209] Mod:resolve pr review --- common/constant/default.go | 4 ++++ config/instance/metedata_report.go | 18 +++++++-------- config/metadata_report_config.go | 2 +- go.mod | 2 -- go.sum | 6 ----- metadata/definition/definition.go | 22 +++++++++---------- metadata/report/delegate/delegate_report.go | 1 - .../report/delegate/delegate_report_test.go | 14 ++++++------ .../service/exporter/configurable/exporter.go | 2 +- metadata/service/inmemory/service.go | 7 ++++-- metadata/service/remote/service.go | 6 +++-- metadata/service/remote/service_test.go | 2 +- metadata/service/service.go | 3 ++- 13 files changed, 44 insertions(+), 45 deletions(-) diff --git a/common/constant/default.go b/common/constant/default.go index 3c889158e4..6b9d914c87 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -74,3 +74,7 @@ const ( const ( COMMA_SPLIT_PATTERN = "\\s*[,]+\\s*" ) + +const ( + SIMPLE_METADATA_SERVICE_NAME = "MetadataService" +) diff --git a/config/instance/metedata_report.go b/config/instance/metedata_report.go index 70e6ffc23d..8e833dd70b 100644 --- a/config/instance/metedata_report.go +++ b/config/instance/metedata_report.go @@ -33,20 +33,20 @@ var ( once sync.Once ) -// InitMetadataReportInstance will create the metadata report instance by the specified metadata report url -func InitMetadataReportInstance(url *common.URL) report.MetadataReport { +// GetMetadataReportInstance will return the instance in lazy mode. Be careful the instance create will only +// execute once. +func GetMetadataReportInstance(selectiveUrl ...*common.URL) report.MetadataReport { once.Do(func() { - instance = extension.GetMetadataReportFactory(url.Protocol).CreateMetadataReport(url) - reportUrl = *url + var url *common.URL + if len(selectiveUrl) > 0 { + url = selectiveUrl[0] + instance = extension.GetMetadataReportFactory(url.Protocol).CreateMetadataReport(url) + reportUrl = *url + } }) return instance } -// GetMetadataReportInstance will return the instance -func GetMetadataReportInstance() report.MetadataReport { - return instance -} - // GetMetadataReportUrl will return the report instance url func GetMetadataReportUrl() common.URL { return reportUrl diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index 95506462a2..41fb6b4769 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -101,7 +101,7 @@ func startMetadataReport(metadataType string, metadataReportConfig *MetadataRepo } if url, err := metadataReportConfig.ToUrl(); err == nil { - instance.InitMetadataReportInstance(url) + instance.GetMetadataReportInstance(url) } else { return perrors.New("MetadataConfig is invalid!") } diff --git a/go.mod b/go.mod index 5de123bdb3..ba3cf3e219 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,7 @@ require ( github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.9.0 github.com/emicklei/go-restful/v3 v3.0.0 - github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/go-co-op/gocron v0.1.1 - github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 diff --git a/go.sum b/go.sum index 5e07006205..eb84bde1fb 100644 --- a/go.sum +++ b/go.sum @@ -35,11 +35,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apache/dubbo-go-hessian2 v1.5.0 h1:fzulDG5G7nX0ccgKdiN9XipJ7tZ4WXKgmk4stdlDS6s= github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -53,7 +50,6 @@ github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL6 github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -392,8 +388,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= github.com/nacos-group/nacos-sdk-go v0.3.1 h1:MI7bNDAN5m9UFcRRUTSPfJi4dCQo+TYG85qVB1rCHeg= github.com/nacos-group/nacos-sdk-go v0.3.1/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 18578cb2c1..11e137a14b 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -21,6 +21,7 @@ import ( "bytes" "encoding/json" "fmt" + "strings" ) import ( @@ -43,29 +44,26 @@ type ServiceDefinition struct { func (def ServiceDefinition) ToBytes() ([]byte, error) { return json.Marshal(def) - } func (def ServiceDefinition) String() string { - var methodStr string + var methodStr strings.Builder for _, m := range def.Methods { - var paramType string + var paramType strings.Builder for _, p := range m.ParameterTypes { - paramType = paramType + fmt.Sprintf("{type:%v}", p) + paramType.WriteString(fmt.Sprintf("{type:%v}", p)) } - var param string + var param strings.Builder for _, d := range m.Parameters { - param = param + fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName) + param.WriteString(fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName)) } - methodStr = methodStr + fmt.Sprintf("{name:%v,parameterTypes:[%v],returnType:%v,params:[%v] }", m.Name, paramType, m.ReturnType, param) - + methodStr.WriteString(fmt.Sprintf("{name:%v,parameterTypes:[%v],returnType:%v,params:[%v] }", m.Name, paramType.String(), m.ReturnType, param.String())) } - var types string + var types strings.Builder for _, d := range def.Types { - types = types + fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName) + types.WriteString(fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.Id, d.Type, d.TypeBuilderName)) } - - return fmt.Sprintf("{canonicalName:%v, codeSource:%v, methods:[%v], types:[%v]}", def.CanonicalName, def.CodeSource, methodStr, types) + return fmt.Sprintf("{canonicalName:%v, codeSource:%v, methods:[%v], types:[%v]}", def.CanonicalName, def.CodeSource, methodStr.String(), types.String()) } // FullServiceDefinition is the describer of service definition with parameters diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 870625b9cb..a363047988 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -202,7 +202,6 @@ func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.Me logger.Errorf("storeProviderMetadataTask error in stage call metadata report to StoreProviderMetadata, msg is %v", err) panic(err) } - } // StoreConsumerMetadata will delegate to call remote metadata's sdk to store consumer side service definition diff --git a/metadata/report/delegate/delegate_report_test.go b/metadata/report/delegate/delegate_report_test.go index b5f8551a1a..0e8da60700 100644 --- a/metadata/report/delegate/delegate_report_test.go +++ b/metadata/report/delegate/delegate_report_test.go @@ -25,6 +25,7 @@ import ( import ( "github.com/stretchr/testify/assert" + "go.uber.org/atomic" ) import ( @@ -37,10 +38,10 @@ import ( ) func TestMetadataReport_MetadataReportRetry(t *testing.T) { - counter := 1 + counter := atomic.NewInt64(1) retry, err := newMetadataReportRetry(1, 10, func() bool { - counter++ + counter.Add(1) return true }) assert.NoError(t, err) @@ -49,16 +50,16 @@ func TestMetadataReport_MetadataReportRetry(t *testing.T) { select { case <-itsTime: retry.scheduler.Clear() - assert.Equal(t, counter, 3) + assert.Equal(t, counter.Load(), int64(3)) logger.Info("over") } } func TestMetadataReport_MetadataReportRetryWithLimit(t *testing.T) { - counter := 1 + counter := atomic.NewInt64(1) retry, err := newMetadataReportRetry(1, 1, func() bool { - counter++ + counter.Add(1) return true }) assert.NoError(t, err) @@ -67,10 +68,9 @@ func TestMetadataReport_MetadataReportRetryWithLimit(t *testing.T) { select { case <-itsTime: retry.scheduler.Clear() - assert.Equal(t, counter, 2) + assert.Equal(t, counter.Load(), int64(2)) logger.Info("over") } - } func mockNewMetadataReport(t *testing.T) *MetadataReport { diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index 3d12e0ecd4..ec3f8ec2d0 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -49,7 +49,7 @@ func NewMetadataServiceExporter(metadataService service.MetadataService) exporte func (exporter *MetadataServiceExporter) Export() error { if !exporter.IsExported() { - serviceConfig := config.NewServiceConfig("MetadataService", context.Background()) + serviceConfig := config.NewServiceConfig(constant.SIMPLE_METADATA_SERVICE_NAME, context.Background()) serviceConfig.Protocol = constant.DEFAULT_PROTOCOL serviceConfig.Protocols = map[string]*config.ProtocolConfig{ constant.DEFAULT_PROTOCOL: generateMetadataProtocol(), diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index df0ec7a4a7..4b6f4330a1 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -33,6 +33,9 @@ import ( "github.com/apache/dubbo-go/metadata/service" ) +// version will be used by Version func +const version = "1.0.0" + // MetadataService is store and query the metadata info in memory when each service registry type MetadataService struct { service.BaseMetadataService @@ -118,7 +121,7 @@ func (mts *MetadataService) getAllService(services *sync.Map) *skip.SkipList { urls := value.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) - if url.GetParam(constant.INTERFACE_KEY, url.Path) != "MetadataService" { + if url.GetParam(constant.INTERFACE_KEY, url.Path) != constant.SIMPLE_METADATA_SERVICE_NAME { skipList.Insert(Comparator(url)) } } @@ -227,5 +230,5 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR // Version will return the version of metadata service func (mts *MetadataService) Version() string { - return "1.0.0" + return version } diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index 706f2f919c..f4587638ef 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -34,6 +34,9 @@ import ( "github.com/apache/dubbo-go/metadata/service/inmemory" ) +// version will be used by Version func +const version = "1.0.0" + // MetadataService is a implement of metadata service which will delegate the remote metadata report type MetadataService struct { service.BaseMetadataService @@ -145,7 +148,6 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) result = false } - } } @@ -174,7 +176,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR // Version will return the remote service version func (MetadataService) Version() string { - return "1.0.0" + return version } // convertUrls will convert the skip list to slice diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 05378cb8b1..308c631e41 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -96,7 +96,7 @@ func TestMetadataService(t *testing.T) { u, err := common.NewURL(fmt.Sprintf( "mock://127.0.0.1:20000/?sync.report=true")) assert.NoError(t, err) - instance.InitMetadataReportInstance(&u) + instance.GetMetadataReportInstance(&u) mts, err := NewMetadataService() assert.NoError(t, err) mts.setInMemoryMetadataService(mockInmemoryProc(t)) diff --git a/metadata/service/service.go b/metadata/service/service.go index a1b812c0ac..13464087ed 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -23,6 +23,7 @@ import ( import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/config" ) @@ -66,5 +67,5 @@ func (mts *BaseMetadataService) ServiceName() (string, error) { // Version will return the version of metadata service func (mts *BaseMetadataService) Reference() string { - return "MetadataService" + return constant.SIMPLE_METADATA_SERVICE_NAME } From 235edf5881a731a49af24442b4eb8016a4f4bed7 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 17 May 2020 16:54:18 +0800 Subject: [PATCH 070/209] Mod:resolve pr review --- metadata/report/delegate/delegate_report.go | 23 ++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index a363047988..4e3995d2ea 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -147,7 +147,7 @@ func NewMetadataReport() (*MetadataReport, error) { // retry will do metadata failed reports collection by call metadata report sdk func (bmr *MetadataReport) retry() bool { bmr.failedReportsLock.RLock() - bmr.failedReportsLock.Unlock() + defer bmr.failedReportsLock.RUnlock() return bmr.doHandlerMetadataCollection(bmr.failedReports) } @@ -155,9 +155,8 @@ func (bmr *MetadataReport) retry() bool { func (bmr *MetadataReport) StoreProviderMetadata(identifier *identifier.MetadataIdentifier, definer definition.ServiceDefiner) { if bmr.syncReport { bmr.storeMetadataTask(common.PROVIDER, identifier, definer) - } else { - go bmr.storeMetadataTask(common.PROVIDER, identifier, definer) } + go bmr.storeMetadataTask(common.PROVIDER, identifier, definer) } // storeMetadataTask will delegate to call remote metadata's sdk to store @@ -208,9 +207,8 @@ func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.Me func (bmr *MetadataReport) StoreConsumerMetadata(identifier *identifier.MetadataIdentifier, definer map[string]string) { if bmr.syncReport { bmr.storeMetadataTask(common.CONSUMER, identifier, definer) - } else { - go bmr.storeMetadataTask(common.CONSUMER, identifier, definer) } + go bmr.storeMetadataTask(common.CONSUMER, identifier, definer) } // SaveServiceMetadata will delegate to call remote metadata's sdk to save service metadata @@ -218,10 +216,9 @@ func (bmr *MetadataReport) SaveServiceMetadata(identifier *identifier.ServiceMet report := instance.GetMetadataReportInstance() if bmr.syncReport { return report.SaveServiceMetadata(identifier, url) - } else { - go report.SaveServiceMetadata(identifier, url) - return nil } + go report.SaveServiceMetadata(identifier, url) + return nil } // RemoveServiceMetadata will delegate to call remote metadata's sdk to remove service metadata @@ -229,10 +226,9 @@ func (bmr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceM report := instance.GetMetadataReportInstance() if bmr.syncReport { return report.RemoveServiceMetadata(identifier) - } else { - go report.RemoveServiceMetadata(identifier) - return nil } + go report.RemoveServiceMetadata(identifier) + return nil } // GetExportedURLs will delegate to call remote metadata's sdk to get exported urls @@ -246,10 +242,9 @@ func (bmr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberM report := instance.GetMetadataReportInstance() if bmr.syncReport { return report.SaveSubscribedData(identifier, urls) - } else { - go report.SaveSubscribedData(identifier, urls) - return nil } + go report.SaveSubscribedData(identifier, urls) + return nil } // GetSubscribedURLs will delegate to call remote metadata's sdk to get subscribed urls From 7a87b5a9643e89a613f8b2969b56ae3d8bdcb137 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 18 May 2020 18:19:30 +0800 Subject: [PATCH 071/209] fix review comments --- registry/base_registry.go | 37 +++++++++++++++++++++++++++---------- registry/mock_registry.go | 1 - 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 3a9569740f..8c62062cd0 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -380,9 +380,32 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) n := 0 for { n++ - err := r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoSubscribe) - if err == nil { - return nil + if !r.IsAvailable() { + logger.Warnf("event listener game over.") + return perrors.New("nacosRegistry is not available.") + } + + listener, err := r.facadeBasedRegistry.DoSubscribe(url) + if err != nil { + if !r.IsAvailable() { + logger.Warnf("event listener game over.") + return err + } + logger.Warnf("getListener() = err:%v", perrors.WithStack(err)) + time.Sleep(time.Duration(RegistryConnDelay) * time.Second) + continue + } + + for { + if serviceEvent, err := listener.Next(); err != nil { + logger.Warnf("Selector.watch() = error{%v}", perrors.WithStack(err)) + listener.Close() + break + } else { + logger.Infof("update begin, service event: %v", serviceEvent.String()) + notifyListener.Notify(serviceEvent) + } + } sleepWait(n) } @@ -390,18 +413,12 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) // UnSubscribe :UnSubscribeURL func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error { - return r.processNotify(url, notifyListener, r.facadeBasedRegistry.DoUnsubscribe) -} - -// processNotify can process notify listener when Subscribe or UnSubscribe -func (r *BaseRegistry) processNotify(url *common.URL, notifyListener NotifyListener, f func(conf *common.URL) (Listener, error)) error { - if !r.IsAvailable() { logger.Warnf("event listener game over.") return nil } - listener, err := f(url) + listener, err := r.facadeBasedRegistry.DoUnsubscribe(url) if err != nil { if !r.IsAvailable() { logger.Warnf("event listener game over.") diff --git a/registry/mock_registry.go b/registry/mock_registry.go index ddf445ac8a..f39490a267 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -53,7 +53,6 @@ func (*MockRegistry) Register(url common.URL) error { // UnRegister func (r *MockRegistry) UnRegister(conf common.URL) error { - return nil } From ab046ef92385dd8ba407ce54095524a89befbfcd Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 18 May 2020 18:23:17 +0800 Subject: [PATCH 072/209] fix review comments --- registry/base_registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 8c62062cd0..39186eef0a 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -411,7 +411,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) } } -// UnSubscribe :UnSubscribeURL +// UnSubscribe URL func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error { if !r.IsAvailable() { logger.Warnf("event listener game over.") From 2699fccd2ac7d0a7f77aabe890c2a8b7aefa0a73 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 19 May 2020 08:37:33 +0800 Subject: [PATCH 073/209] fix review problems --- registry/etcdv3/registry.go | 2 +- registry/kubernetes/registry.go | 3 +-- registry/zookeeper/registry.go | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index a2722a2e67..a65d090349 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -115,7 +115,7 @@ func (r *etcdV3Registry) DoRegister(root string, node string) error { } func (r *etcdV3Registry) DoUnregister(root string, node string) error { - return r.client.Delete(path.Join(root, node)) + return perrors.New("DoUnregister is not support in etcdV3Registry") } func (r *etcdV3Registry) CloseAndNilClient() { diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index e64f9acb07..7ee0f6b0ee 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -108,8 +108,7 @@ func (r *kubernetesRegistry) DoRegister(root string, node string) error { } func (r *kubernetesRegistry) DoUnregister(root string, node string) error { - panic("DoUnregister is not support in kubernetesRegistry") - return nil + return perrors.New("DoUnregister is not support in kubernetesRegistry") } func (r *kubernetesRegistry) DoSubscribe(svc *common.URL) (registry.Listener, error) { diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index f51ec67186..e68265068b 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -279,12 +279,9 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL zkListener, _ := configurationListener.(*RegistryConfigurationListener) if zkListener != nil { - r.listenerLock.Lock() if zkListener.isClosed { - r.listenerLock.Unlock() return nil, perrors.New("configListener already been closed") } - r.listenerLock.Unlock() } } @@ -299,6 +296,7 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL r.listenerLock.Lock() listener := r.listener r.listener = nil + r.listenerLock.Unlock() r.dataListener.Close() listener.Close() From f0c9c8f990489cd975428520cf550ffc331c439f Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 19 May 2020 08:39:13 +0800 Subject: [PATCH 074/209] fix review problems --- registry/base_registry.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index 39186eef0a..b3044294d8 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -56,6 +56,8 @@ func init() { localIP, _ = gxnet.GetLocalIP() } +type createPathFunc func(dubboPath string) error + /* * -----------------------------------NOTICE--------------------------------------------- * If there is no special case, you'd better inherit BaseRegistry and implement the @@ -332,7 +334,7 @@ func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values, createP } // consumerRegistry for consumer role do -func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values, createPathFunc func(dubboPath string) error) (string, string, error) { +func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values, f createPathFunc) (string, string, error) { var ( dubboPath string rawURL string @@ -340,8 +342,8 @@ func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values, createP ) dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.CONSUMER]) - if createPathFunc != nil { - err = createPathFunc(dubboPath) + if f != nil { + err = f(dubboPath) } if err != nil { logger.Errorf("facadeBasedRegistry.CreatePath(path{%s}) = error{%v}", dubboPath, perrors.WithStack(err)) @@ -349,8 +351,8 @@ func (r *BaseRegistry) consumerRegistry(c common.URL, params url.Values, createP } dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.PROVIDER]) - if createPathFunc != nil { - err = createPathFunc(dubboPath) + if f != nil { + err = f(dubboPath) } if err != nil { From df1a43dd7eac8566b8c7515dffe301c9b0a76df9 Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 19 May 2020 22:58:50 +0800 Subject: [PATCH 075/209] Finish code --- metadata/report/nacos/report.go | 171 ++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 metadata/report/nacos/report.go diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go new file mode 100644 index 0000000000..4333d52ac1 --- /dev/null +++ b/metadata/report/nacos/report.go @@ -0,0 +1,171 @@ +/* + * 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 nacos + +import ( + "encoding/json" + "net/url" + + "github.com/nacos-group/nacos-sdk-go/clients/config_client" + "github.com/nacos-group/nacos-sdk-go/vo" + perrors "github.com/pkg/errors" + + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/metadata/identifier" +) + +// nacosMetadataReport is the implementation of MetadataReport based Nacos +type nacosMetadataReport struct { + client config_client.IConfigClient +} + +// StoreProviderMetadata will store the metadata +func (n *nacosMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { + return n.storeMetadata(vo.ConfigParam{ + DataId: providerIdentifier.GetIdentifierKey(), + Group: providerIdentifier.Group, + Content: serviceDefinitions, + }) +} + +// StoreConsumerMetadata will store the metadata +func (n *nacosMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { + return n.storeMetadata(vo.ConfigParam{ + DataId: consumerMetadataIdentifier.GetIdentifierKey(), + Group: consumerMetadataIdentifier.Group, + Content: serviceParameterString, + }) +} + +// SaveServiceMetadata will store the metadata +func (n *nacosMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { + return n.storeMetadata(vo.ConfigParam{ + DataId: metadataIdentifier.GetIdentifierKey(), + Group: metadataIdentifier.Group, + Content: url.String(), + }) +} + +// RemoveServiceMetadata will remove the service metadata +func (n *nacosMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier) error { + return n.deleteMetadata(vo.ConfigParam{ + DataId: metadataIdentifier.GetIdentifierKey(), + Group: metadataIdentifier.Group, + }) +} + +// GetExportedURLs will look up the exported urls. +// if not found, an empty list will be returned. +func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { + return n.getConfigAsArray(vo.ConfigParam{ + DataId: metadataIdentifier.GetIdentifierKey(), + Group: metadataIdentifier.Group, + }) +} + +// SaveSubscribedData will convert the urlList to json array and then store it +func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlList []common.URL) error { + if len(urlList) == 0 { + logger.Warnf("The url list is empty") + return nil + } + urlStrList := make([]string, 0, len(urlList)) + + for _, e := range urlList { + urlStrList = append(urlStrList, e.String()) + } + + bytes, err := json.Marshal(urlStrList) + + if err != nil { + return perrors.WithMessage(err, "Could not convert the array to json") + } + return n.storeMetadata(vo.ConfigParam{ + DataId: subscriberMetadataIdentifier.GetIdentifierKey(), + Group: subscriberMetadataIdentifier.Group, + Content: string(bytes), + }) +} + +// GetSubscribedURLs will lookup the url +// if not found, an empty list will be returned +func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { + return n.getConfigAsArray(vo.ConfigParam{ + DataId: subscriberMetadataIdentifier.GetIdentifierKey(), + Group: subscriberMetadataIdentifier.Group, + }) +} + +// GetServiceDefinition will lookup the service definition +func (n *nacosMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { + return n.getConfig(vo.ConfigParam{ + DataId: metadataIdentifier.GetIdentifierKey(), + Group: metadataIdentifier.Group, + }) +} + +// storeMetadata will publish the metadata to Nacos +// if failed or error is not nil, error will be returned +func (n *nacosMetadataReport) storeMetadata(param vo.ConfigParam) error { + res, err := n.client.PublishConfig(param) + if err != nil { + return perrors.WithMessage(err, "Could not publish the metadata") + } + if !res { + return perrors.New("Publish the metadata failed.") + } + return nil +} + +// deleteMetadata will delete the metadata +func (n *nacosMetadataReport) deleteMetadata(param vo.ConfigParam) error { + res, err := n.client.DeleteConfig(param) + if err != nil { + return perrors.WithMessage(err, "Could not delete the metadata") + } + if !res { + return perrors.New("Deleting the metadata failed.") + } + return nil +} + +// getConfigAsArray will read the config and then convert it as an one-element array +// error or config not found, an empty list will be returned. +func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) []string { + cfg := n.getConfig(param) + res := make([]string, 0, 1) + if len(cfg) == 0 { + return res + } + decodeCfg, err := url.QueryUnescape(cfg) + if err != nil { + logger.Errorf("The config is invalid: %s", cfg) + } + res = append(res, decodeCfg) + return res +} + +// getConfig will read the config +func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) string { + cfg, err := n.client.GetConfig(param) + if err != nil { + logger.Errorf("Finding the configuration failed: %v", param) + } + return cfg +} From 7e7db7bd628f334262f1edf24d2c5fe72217e4f9 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 19 May 2020 22:59:54 +0800 Subject: [PATCH 076/209] fix review problems --- registry/base_registry.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/registry/base_registry.go b/registry/base_registry.go index b3044294d8..ad1a3b6174 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -240,7 +240,7 @@ func (r *BaseRegistry) unregister(c common.URL) error { return r.processURL(c, r.facadeBasedRegistry.DoUnregister, nil) } -func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error, createPathFunc func(dubboPath string) error) error { +func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error, cpf createPathFunc) error { if f == nil { panic(" Must provide a `function(string, string) error` to process URL. ") } @@ -268,9 +268,9 @@ func (r *BaseRegistry) processURL(c common.URL, f func(string, string) error, cr switch role { case common.PROVIDER: - dubboPath, rawURL, err = r.providerRegistry(c, params, createPathFunc) + dubboPath, rawURL, err = r.providerRegistry(c, params, cpf) case common.CONSUMER: - dubboPath, rawURL, err = r.consumerRegistry(c, params, createPathFunc) + dubboPath, rawURL, err = r.consumerRegistry(c, params, cpf) default: return perrors.Errorf("@c{%v} type is not referencer or provider", c) } @@ -292,7 +292,7 @@ func (r *BaseRegistry) createPath(dubboPath string) error { } // providerRegistry for provider role do -func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values, createPathFunc func(dubboPath string) error) (string, string, error) { +func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values, f createPathFunc) (string, string, error) { var ( dubboPath string rawURL string @@ -302,8 +302,8 @@ func (r *BaseRegistry) providerRegistry(c common.URL, params url.Values, createP return "", "", perrors.Errorf("conf{Path:%s, Methods:%s}", c.Path, c.Methods) } dubboPath = fmt.Sprintf("/dubbo/%s/%s", r.service(c), common.DubboNodes[common.PROVIDER]) - if createPathFunc != nil { - err = createPathFunc(dubboPath) + if f != nil { + err = f(dubboPath) } if err != nil { logger.Errorf("facadeBasedRegistry.CreatePath(path{%s}) = error{%#v}", dubboPath, perrors.WithStack(err)) @@ -384,7 +384,7 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) n++ if !r.IsAvailable() { logger.Warnf("event listener game over.") - return perrors.New("nacosRegistry is not available.") + return perrors.New("BaseRegistry is not available.") } listener, err := r.facadeBasedRegistry.DoSubscribe(url) @@ -417,17 +417,16 @@ func (r *BaseRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) func (r *BaseRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error { if !r.IsAvailable() { logger.Warnf("event listener game over.") - return nil + return perrors.New("BaseRegistry is not available.") } listener, err := r.facadeBasedRegistry.DoUnsubscribe(url) if err != nil { if !r.IsAvailable() { logger.Warnf("event listener game over.") - return nil + return perrors.New("BaseRegistry is not available.") } logger.Warnf("getListener() = err:%v", perrors.WithStack(err)) - time.Sleep(time.Duration(RegistryConnDelay) * time.Second) return perrors.WithStack(err) } From 5c767f497cf79838111b2c811300064ea3a16bfa Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Thu, 21 May 2020 23:40:38 +0800 Subject: [PATCH 077/209] change subscribe service key in registrydatalistener --- registry/zookeeper/listener.go | 12 ++++++------ registry/zookeeper/registry.go | 17 +++++++++++------ registry/zookeeper/registry_test.go | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index d0220ddf0d..c6324596e5 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -37,7 +37,7 @@ import ( // RegistryDataListener contains all URL information subscribed by zookeeper registry type RegistryDataListener struct { - subscribed map[*common.URL]config_center.ConfigurationListener + subscribed map[string]config_center.ConfigurationListener mutex sync.Mutex closed bool } @@ -45,7 +45,7 @@ type RegistryDataListener struct { // NewRegistryDataListener constructs a new RegistryDataListener func NewRegistryDataListener() *RegistryDataListener { return &RegistryDataListener{ - subscribed: make(map[*common.URL]config_center.ConfigurationListener)} + subscribed: make(map[string]config_center.ConfigurationListener)} } // SubscribeURL is used to set a watch listener for url @@ -53,7 +53,7 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen if l.closed { return } - l.subscribed[url] = listener + l.subscribed[url.Key()] = listener } // UnSubscribeURL is used to set a watch listener for url @@ -61,8 +61,8 @@ func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.Con if l.closed { return nil } - listener := l.subscribed[url] - delete(l.subscribed, url) + listener := l.subscribed[url.Key()] + delete(l.subscribed, url.Key()) return listener } @@ -86,7 +86,7 @@ func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool { return false } for url, listener := range l.subscribed { - if serviceURL.URLEqual(*url) { + if serviceURL.Key() == url { listener.Process( &config_center.ConfigChangeEvent{ Key: eventType.Path, diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index e68265068b..305b763c3e 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -129,12 +129,17 @@ func (r *zkRegistry) InitListeners() { recoverd := r.dataListener.subscribed if recoverd != nil && len(recoverd) > 0 { // recover all subscribed url - for conf, oldListener := range recoverd { + for recoveredURL, oldListener := range recoverd { if regConfigListener, ok := oldListener.(*RegistryConfigurationListener); ok { regConfigListener.Close() } - newDataListener.SubscribeURL(conf, NewRegistryConfigurationListener(r.client, r)) - go r.listener.ListenServiceEvent(conf, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(conf.Service())), newDataListener) + serviceURL, err := common.NewURL(recoveredURL) + if err != nil { + logger.Errorf("Listen NewURL(r{%s}) = error{%v}", recoveredURL, err) + continue + } + newDataListener.SubscribeURL(&serviceURL, NewRegistryConfigurationListener(r.client, r)) + go r.listener.ListenServiceEvent(&serviceURL, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(serviceURL.Service())), newDataListener) } } @@ -231,9 +236,9 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen dataListener := r.dataListener dataListener.mutex.Lock() defer dataListener.mutex.Unlock() - if r.dataListener.subscribed[conf] != nil { + if r.dataListener.subscribed[conf.Key()] != nil { - zkListener, _ := r.dataListener.subscribed[conf].(*RegistryConfigurationListener) + zkListener, _ := r.dataListener.subscribed[conf.Key()].(*RegistryConfigurationListener) if zkListener != nil { r.listenerLock.Lock() defer r.listenerLock.Unlock() @@ -274,7 +279,7 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL var zkListener *RegistryConfigurationListener r.dataListener.mutex.Lock() - configurationListener := r.dataListener.subscribed[conf] + configurationListener := r.dataListener.subscribed[conf.Key()] if configurationListener != nil { zkListener, _ := configurationListener.(*RegistryConfigurationListener) diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index d4141e8012..2e2602e64c 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -99,7 +99,7 @@ func Test_Subscribe(t *testing.T) { defer ts.Stop() } -func Test_NoSubscribe(t *testing.T) { +func Test_UnSubscribe(t *testing.T) { regurl, _ := common.NewURL("registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"})) ts, reg, _ := newMockZkRegistry(®url) From c21d9284158a8e88d105ffbc27428e888f3c641e Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Fri, 22 May 2020 23:50:35 +0800 Subject: [PATCH 078/209] change to service key --- registry/zookeeper/listener.go | 33 ++++++++++++++++++++------------- registry/zookeeper/registry.go | 26 +++++++++++++------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index c6324596e5..ec82fa0309 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -53,7 +53,7 @@ func (l *RegistryDataListener) SubscribeURL(url *common.URL, listener config_cen if l.closed { return } - l.subscribed[url.Key()] = listener + l.subscribed[url.ServiceKey()] = listener } // UnSubscribeURL is used to set a watch listener for url @@ -61,8 +61,8 @@ func (l *RegistryDataListener) UnSubscribeURL(url *common.URL) config_center.Con if l.closed { return nil } - listener := l.subscribed[url.Key()] - delete(l.subscribed, url.Key()) + listener := l.subscribed[url.ServiceKey()] + delete(l.subscribed, url.ServiceKey()) return listener } @@ -85,8 +85,8 @@ func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool { if l.closed { return false } - for url, listener := range l.subscribed { - if serviceURL.Key() == url { + for serviceKey, listener := range l.subscribed { + if serviceURL.ServiceKey() == serviceKey { listener.Process( &config_center.ConfigChangeEvent{ Key: eventType.Path, @@ -111,18 +111,25 @@ func (l *RegistryDataListener) Close() { // RegistryConfigurationListener represent the processor of zookeeper watcher type RegistryConfigurationListener struct { - client *zk.ZookeeperClient - registry *zkRegistry - events chan *config_center.ConfigChangeEvent - isClosed bool - close chan struct{} - closeOnce sync.Once + client *zk.ZookeeperClient + registry *zkRegistry + events chan *config_center.ConfigChangeEvent + isClosed bool + close chan struct{} + closeOnce sync.Once + subscribeURL *common.URL } // NewRegistryConfigurationListener for listening the event of zk. -func NewRegistryConfigurationListener(client *zk.ZookeeperClient, reg *zkRegistry) *RegistryConfigurationListener { +func NewRegistryConfigurationListener(client *zk.ZookeeperClient, reg *zkRegistry, conf *common.URL) *RegistryConfigurationListener { reg.WaitGroup().Add(1) - return &RegistryConfigurationListener{client: client, registry: reg, events: make(chan *config_center.ConfigChangeEvent, 32), isClosed: false, close: make(chan struct{}, 1)} + return &RegistryConfigurationListener{ + client: client, + registry: reg, + events: make(chan *config_center.ConfigChangeEvent, 32), + isClosed: false, + close: make(chan struct{}, 1), + subscribeURL: conf} } // Process submit the ConfigChangeEvent to the event chan to notify all observer diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 305b763c3e..5d5f9e0526 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -129,17 +129,17 @@ func (r *zkRegistry) InitListeners() { recoverd := r.dataListener.subscribed if recoverd != nil && len(recoverd) > 0 { // recover all subscribed url - for recoveredURL, oldListener := range recoverd { - if regConfigListener, ok := oldListener.(*RegistryConfigurationListener); ok { + for _, oldListener := range recoverd { + var ( + regConfigListener *RegistryConfigurationListener + ok bool + ) + + if regConfigListener, ok = oldListener.(*RegistryConfigurationListener); ok { regConfigListener.Close() } - serviceURL, err := common.NewURL(recoveredURL) - if err != nil { - logger.Errorf("Listen NewURL(r{%s}) = error{%v}", recoveredURL, err) - continue - } - newDataListener.SubscribeURL(&serviceURL, NewRegistryConfigurationListener(r.client, r)) - go r.listener.ListenServiceEvent(&serviceURL, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(serviceURL.Service())), newDataListener) + newDataListener.SubscribeURL(regConfigListener.subscribeURL, NewRegistryConfigurationListener(r.client, r, regConfigListener.subscribeURL)) + go r.listener.ListenServiceEvent(regConfigListener.subscribeURL, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(regConfigListener.subscribeURL.Service())), newDataListener) } } @@ -236,9 +236,9 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen dataListener := r.dataListener dataListener.mutex.Lock() defer dataListener.mutex.Unlock() - if r.dataListener.subscribed[conf.Key()] != nil { + if r.dataListener.subscribed[conf.ServiceKey()] != nil { - zkListener, _ := r.dataListener.subscribed[conf.Key()].(*RegistryConfigurationListener) + zkListener, _ := r.dataListener.subscribed[conf.ServiceKey()].(*RegistryConfigurationListener) if zkListener != nil { r.listenerLock.Lock() defer r.listenerLock.Unlock() @@ -250,7 +250,7 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen } } - zkListener = NewRegistryConfigurationListener(r.client, r) + zkListener = NewRegistryConfigurationListener(r.client, r, conf) if r.listener == nil { r.cltLock.Lock() client := r.client @@ -279,7 +279,7 @@ func (r *zkRegistry) getCloseListener(conf *common.URL) (*RegistryConfigurationL var zkListener *RegistryConfigurationListener r.dataListener.mutex.Lock() - configurationListener := r.dataListener.subscribed[conf.Key()] + configurationListener := r.dataListener.subscribed[conf.ServiceKey()] if configurationListener != nil { zkListener, _ := configurationListener.(*RegistryConfigurationListener) From c312cc8588f8a5c0f5bb3fb63b60a04d2e95652f Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sat, 23 May 2020 23:55:51 +0800 Subject: [PATCH 079/209] Mod:modify for code review --- metadata/definition/definition.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index 11e137a14b..c8dd86b18f 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -29,7 +29,7 @@ import ( "github.com/apache/dubbo-go/common/constant" ) -// ServiceDefinition is a interface of service's definition +// ServiceDefiner is a interface of service's definition type ServiceDefiner interface { ToBytes() ([]byte, error) } @@ -42,11 +42,11 @@ type ServiceDefinition struct { Types []TypeDefinition } -func (def ServiceDefinition) ToBytes() ([]byte, error) { +func (def *ServiceDefinition) ToBytes() ([]byte, error) { return json.Marshal(def) } -func (def ServiceDefinition) String() string { +func (def *ServiceDefinition) String() string { var methodStr strings.Builder for _, m := range def.Methods { var paramType strings.Builder From 0d78b2a65f1c35e93682adeed0d62b0d5e3c679e Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 24 May 2020 12:02:51 +0800 Subject: [PATCH 080/209] Mod:for code review --- metadata/definition/definition.go | 4 ++-- metadata/report/delegate/delegate_report_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index c8dd86b18f..fa195d09d7 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -91,8 +91,8 @@ type TypeDefinition struct { } // BuildServiceDefinition can build service definition which will be used to describe a service -func BuildServiceDefinition(service common.Service, url common.URL) ServiceDefinition { - sd := ServiceDefinition{} +func BuildServiceDefinition(service common.Service, url common.URL) *ServiceDefinition { + sd := &ServiceDefinition{} sd.CanonicalName = url.Service() for k, m := range service.Method() { diff --git a/metadata/report/delegate/delegate_report_test.go b/metadata/report/delegate/delegate_report_test.go index 0e8da60700..04c9e64839 100644 --- a/metadata/report/delegate/delegate_report_test.go +++ b/metadata/report/delegate/delegate_report_test.go @@ -106,7 +106,7 @@ func TestMetadataReport_StoreProviderMetadata(t *testing.T) { mtr.StoreProviderMetadata(metadataId, getMockDefinition(metadataId, t)) } -func getMockDefinition(id *identifier.MetadataIdentifier, t *testing.T) definition.ServiceDefinition { +func getMockDefinition(id *identifier.MetadataIdentifier, t *testing.T) *definition.ServiceDefinition { protocol := "dubbo" beanName := "UserProvider" url, err := common.NewURL(fmt.Sprintf( From c024ce17b3fcd636f4f9e690bfb3a5a3a7f39c32 Mon Sep 17 00:00:00 2001 From: "vito.he" Date: Sun, 24 May 2020 22:42:32 +0800 Subject: [PATCH 081/209] Mod:code review --- metadata/report/delegate/delegate_report.go | 76 +++++++++++---------- metadata/service/remote/service.go | 8 +-- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 4e3995d2ea..cb7e42030b 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -19,6 +19,7 @@ package delegate import ( "encoding/json" + "runtime/debug" "sync" "time" ) @@ -129,7 +130,7 @@ func NewMetadataReport() (*MetadataReport, error) { scheduler := gocron.NewScheduler(time.UTC) _, err := scheduler.Every(1).Day().Do( func() { - logger.Info("start to publish all metadata.") + logger.Info("start to publish all metadata in metadata report %v.", url) bmr.allMetadataReportsLock.RLock() bmr.doHandlerMetadataCollection(bmr.allMetadataReports) bmr.allMetadataReportsLock.RUnlock() @@ -145,30 +146,30 @@ func NewMetadataReport() (*MetadataReport, error) { } // retry will do metadata failed reports collection by call metadata report sdk -func (bmr *MetadataReport) retry() bool { - bmr.failedReportsLock.RLock() - defer bmr.failedReportsLock.RUnlock() - return bmr.doHandlerMetadataCollection(bmr.failedReports) +func (mr *MetadataReport) retry() bool { + mr.failedReportsLock.RLock() + defer mr.failedReportsLock.RUnlock() + return mr.doHandlerMetadataCollection(mr.failedReports) } // StoreProviderMetadata will delegate to call remote metadata's sdk to store provider service definition -func (bmr *MetadataReport) StoreProviderMetadata(identifier *identifier.MetadataIdentifier, definer definition.ServiceDefiner) { - if bmr.syncReport { - bmr.storeMetadataTask(common.PROVIDER, identifier, definer) +func (mr *MetadataReport) StoreProviderMetadata(identifier *identifier.MetadataIdentifier, definer definition.ServiceDefiner) { + if mr.syncReport { + mr.storeMetadataTask(common.PROVIDER, identifier, definer) } - go bmr.storeMetadataTask(common.PROVIDER, identifier, definer) + go mr.storeMetadataTask(common.PROVIDER, identifier, definer) } // storeMetadataTask will delegate to call remote metadata's sdk to store -func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.MetadataIdentifier, definer interface{}) { +func (mr *MetadataReport) storeMetadataTask(role int, identifier *identifier.MetadataIdentifier, definer interface{}) { logger.Infof("store provider metadata. Identifier :%v ; definition: %v .", identifier, definer) - bmr.allMetadataReportsLock.Lock() - bmr.allMetadataReports[identifier] = definer - bmr.allMetadataReportsLock.Unlock() + mr.allMetadataReportsLock.Lock() + mr.allMetadataReports[identifier] = definer + mr.allMetadataReportsLock.Unlock() - bmr.failedReportsLock.Lock() - delete(bmr.failedReports, identifier) - bmr.failedReportsLock.Unlock() + mr.failedReportsLock.Lock() + delete(mr.failedReports, identifier) + mr.failedReportsLock.Unlock() // data is store the json marshaled definition var ( data []byte @@ -177,17 +178,18 @@ func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.Me defer func() { if r := recover(); r != nil { - bmr.failedReportsLock.Lock() - bmr.failedReports[identifier] = definer - bmr.failedReportsLock.Unlock() - bmr.metadataReportRetry.startRetryTask() - logger.Errorf("Failed to put provider metadata %v in %v, cause: %v", identifier, string(data), r) + mr.failedReportsLock.Lock() + mr.failedReports[identifier] = definer + mr.failedReportsLock.Unlock() + mr.metadataReportRetry.startRetryTask() + logger.Errorf("Failed to put provider metadata %v in %v, cause: %v\n%s\n", + identifier, string(data), r, string(debug.Stack())) } }() data, err = json.Marshal(definer) if err != nil { - logger.Errorf("storeProviderMetadataTask error in stage json.Marshal, msg is %v", err) + logger.Errorf("storeProviderMetadataTask error in stage json.Marshal, msg is %+v", err) panic(err) } report := instance.GetMetadataReportInstance() @@ -198,23 +200,23 @@ func (bmr *MetadataReport) storeMetadataTask(role int, identifier *identifier.Me } if err != nil { - logger.Errorf("storeProviderMetadataTask error in stage call metadata report to StoreProviderMetadata, msg is %v", err) + logger.Errorf("storeProviderMetadataTask error in stage call metadata report to StoreProviderMetadata, msg is %+v", err) panic(err) } } // StoreConsumerMetadata will delegate to call remote metadata's sdk to store consumer side service definition -func (bmr *MetadataReport) StoreConsumerMetadata(identifier *identifier.MetadataIdentifier, definer map[string]string) { - if bmr.syncReport { - bmr.storeMetadataTask(common.CONSUMER, identifier, definer) +func (mr *MetadataReport) StoreConsumerMetadata(identifier *identifier.MetadataIdentifier, definer map[string]string) { + if mr.syncReport { + mr.storeMetadataTask(common.CONSUMER, identifier, definer) } - go bmr.storeMetadataTask(common.CONSUMER, identifier, definer) + go mr.storeMetadataTask(common.CONSUMER, identifier, definer) } // SaveServiceMetadata will delegate to call remote metadata's sdk to save service metadata -func (bmr *MetadataReport) SaveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier, url common.URL) error { +func (mr *MetadataReport) SaveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier, url common.URL) error { report := instance.GetMetadataReportInstance() - if bmr.syncReport { + if mr.syncReport { return report.SaveServiceMetadata(identifier, url) } go report.SaveServiceMetadata(identifier, url) @@ -222,9 +224,9 @@ func (bmr *MetadataReport) SaveServiceMetadata(identifier *identifier.ServiceMet } // RemoveServiceMetadata will delegate to call remote metadata's sdk to remove service metadata -func (bmr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier) error { +func (mr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceMetadataIdentifier) error { report := instance.GetMetadataReportInstance() - if bmr.syncReport { + if mr.syncReport { return report.RemoveServiceMetadata(identifier) } go report.RemoveServiceMetadata(identifier) @@ -232,15 +234,15 @@ func (bmr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceM } // GetExportedURLs will delegate to call remote metadata's sdk to get exported urls -func (bmr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadataIdentifier) []string { +func (mr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadataIdentifier) []string { report := instance.GetMetadataReportInstance() return report.GetExportedURLs(identifier) } // SaveSubscribedData will delegate to call remote metadata's sdk to save subscribed data -func (bmr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { +func (mr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { report := instance.GetMetadataReportInstance() - if bmr.syncReport { + if mr.syncReport { return report.SaveSubscribedData(identifier, urls) } go report.SaveSubscribedData(identifier, urls) @@ -260,15 +262,15 @@ func (MetadataReport) GetServiceDefinition(identifier *identifier.MetadataIdenti } // doHandlerMetadataCollection will store metadata to metadata support with given metadataMap -func (bmr *MetadataReport) doHandlerMetadataCollection(metadataMap map[*identifier.MetadataIdentifier]interface{}) bool { +func (mr *MetadataReport) doHandlerMetadataCollection(metadataMap map[*identifier.MetadataIdentifier]interface{}) bool { if len(metadataMap) == 0 { return true } for e := range metadataMap { if common.RoleType(common.PROVIDER).Role() == e.Side { - bmr.StoreProviderMetadata(e, metadataMap[e].(*definition.FullServiceDefinition)) + mr.StoreProviderMetadata(e, metadataMap[e].(*definition.FullServiceDefinition)) } else if common.RoleType(common.CONSUMER).Role() == e.Side { - bmr.StoreConsumerMetadata(e, metadataMap[e].(map[string]string)) + mr.StoreConsumerMetadata(e, metadataMap[e].(map[string]string)) } } return false diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index f4587638ef..f55c482ad8 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -132,7 +132,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR mts.exportedRevision.Store(exportedRevision) urls, err := mts.inMemoryMetadataService.GetExportedURLs(constant.ANY_VALUE, "", "", "") if err != nil { - logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } iterator := urls.Iter(inmemory.Comparator{}) @@ -145,7 +145,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR id := identifier.NewServiceMetadataIdentifier(common.URL(url)) id.Revision = mts.exportedRevision.Load() if err := mts.delegateReport.SaveServiceMetadata(id, common.URL(url)); err != nil { - logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } } @@ -155,7 +155,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR mts.subscribedRevision.Store(subscribedRevision) urls, err := mts.inMemoryMetadataService.GetSubscribedURLs() if err != nil { - logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v+", err) result = false } if urls != nil && urls.Len() > 0 { @@ -166,7 +166,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR Revision: subscribedRevision, } if err := mts.delegateReport.SaveSubscribedData(id, convertUrls(urls)); err != nil { - logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v", err) + logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } } From b364f31815af8067cee14b6e7f618011f59b95de Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 26 May 2020 00:42:20 +0800 Subject: [PATCH 082/209] change test case method --- registry/zookeeper/registry_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index 2e2602e64c..d915fc2ce1 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -126,7 +126,7 @@ func Test_UnSubscribe(t *testing.T) { } assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent.String()) - reg2.DoUnsubscribe(&url) + reg2.UnSubscribe(&url, nil) assert.Nil(t, reg2.listener) defer ts.Stop() From bdd9b71c37ec772a606021614a6810efb625b91b Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 29 May 2020 22:02:35 +0800 Subject: [PATCH 083/209] Add UT --- metadata/report/nacos/report.go | 27 +++++++ metadata/report/nacos/report_test.go | 111 +++++++++++++++++++++++++++ registry/nacos/base_registry.go | 56 +------------- remoting/nacos/builder.go | 95 +++++++++++++++++++++++ 4 files changed, 235 insertions(+), 54 deletions(-) create mode 100644 metadata/report/nacos/report_test.go create mode 100644 remoting/nacos/builder.go diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 4333d52ac1..9dbec51822 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -20,16 +20,31 @@ package nacos import ( "encoding/json" "net/url" +) +import ( "github.com/nacos-group/nacos-sdk-go/clients/config_client" "github.com/nacos-group/nacos-sdk-go/vo" perrors "github.com/pkg/errors" +) +import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" + "github.com/apache/dubbo-go/remoting/nacos" ) +func init() { + ftry := &nacosMetadataReportFactory{} + extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory { + return ftry + }) +} + // nacosMetadataReport is the implementation of MetadataReport based Nacos type nacosMetadataReport struct { client config_client.IConfigClient @@ -169,3 +184,15 @@ func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) string { } return cfg } + +type nacosMetadataReportFactory struct { +} + +func (n *nacosMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { + client, err := nacos.NewNacosConfigClient(url) + if err != nil { + logger.Errorf("Could not create nacos metadata report. URL: %s", url.String()) + return nil + } + return &nacosMetadataReport{client: client} +} diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go new file mode 100644 index 0000000000..711e6281a2 --- /dev/null +++ b/metadata/report/nacos/report_test.go @@ -0,0 +1,111 @@ +/* + * 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 nacos + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + + "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/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" +) + +func TestNacosMetadataReport_CRUD(t *testing.T) { + rpt := newTestReport() + assert.NotNil(t, rpt) + + providerMi := newMetadataIdentifier("server") + providerMeta := "provider" + err := rpt.StoreProviderMetadata(providerMi, providerMeta) + + consumerMi := newMetadataIdentifier("client") + consumerMeta := "consumer" + err = rpt.StoreConsumerMetadata(consumerMi, consumerMeta) + assert.Nil(t, err) + + serviceMi := newServiceMetadataIdentifier() + serviceUrl, _ := common.NewURL("registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + + err = rpt.SaveServiceMetadata(serviceMi, serviceUrl) + assert.Nil(t, err) + + exportedUrls := rpt.GetExportedURLs(serviceMi) + assert.Equal(t, 1, len(exportedUrls)) + + subMi := newSubscribeMetadataIdentifier() + urlList := make([]common.URL, 0, 1) + urlList = append(urlList, serviceUrl) + err = rpt.SaveSubscribedData(subMi, urlList) + assert.Nil(t, err) + + subscribeUrl := rpt.GetSubscribedURLs(subMi) + assert.Equal(t, 1, len(subscribeUrl)) + + err = rpt.RemoveServiceMetadata(serviceMi) + assert.Nil(t, err) + +} + +func newSubscribeMetadataIdentifier() *identifier.SubscriberMetadataIdentifier { + return &identifier.SubscriberMetadataIdentifier{ + Revision: "subscribe", + MetadataIdentifier: *newMetadataIdentifier("provider"), + } + +} + +func newServiceMetadataIdentifier() *identifier.ServiceMetadataIdentifier { + return &identifier.ServiceMetadataIdentifier{ + Protocol: "nacos", + Revision: "a", + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: "com.test.MyTest", + Version: "1.0.0", + Group: "test_group", + Side: "service", + }, + } +} + +func newMetadataIdentifier(side string) *identifier.MetadataIdentifier { + return &identifier.MetadataIdentifier{ + Application: "test", + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: "com.test.MyTest", + Version: "1.0.0", + Group: "test_group", + Side: side, + }, + } +} + +func TestNacosMetadataReportFactory_CreateMetadataReport(t *testing.T) { + res := newTestReport() + assert.NotNil(t, res) +} + +func newTestReport() report.MetadataReport { + regurl, _ := common.NewURL("registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + res := extension.GetMetadataReportFactory("nacos").CreateMetadataReport(®url) + return res +} diff --git a/registry/nacos/base_registry.go b/registry/nacos/base_registry.go index 63f4999675..636ffc302e 100644 --- a/registry/nacos/base_registry.go +++ b/registry/nacos/base_registry.go @@ -18,22 +18,15 @@ package nacos import ( - "net" - "strconv" - "strings" - "time" + "github.com/apache/dubbo-go/remoting/nacos" ) import ( - "github.com/nacos-group/nacos-sdk-go/clients" "github.com/nacos-group/nacos-sdk-go/clients/naming_client" - nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" - perrors "github.com/pkg/errors" ) import ( "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/common/constant" ) // baseRegistry is the parent of both interface-level registry @@ -45,11 +38,7 @@ type nacosBaseRegistry struct { // newBaseRegistry will create new instance func newBaseRegistry(url *common.URL) (nacosBaseRegistry, error) { - nacosConfig, err := getNacosConfig(url) - if err != nil { - return nacosBaseRegistry{}, err - } - client, err := clients.CreateNamingClient(nacosConfig) + client, err := nacos.NewNacosNamingClient(url) if err != nil { return nacosBaseRegistry{}, err } @@ -59,44 +48,3 @@ func newBaseRegistry(url *common.URL) (nacosBaseRegistry, error) { } return registry, nil } - -// getNacosConfig will return the nacos config -func getNacosConfig(url *common.URL) (map[string]interface{}, error) { - if url == nil { - return nil, perrors.New("url is empty!") - } - if len(url.Location) == 0 { - return nil, perrors.New("url.location is empty!") - } - configMap := make(map[string]interface{}, 2) - - addresses := strings.Split(url.Location, ",") - serverConfigs := make([]nacosConstant.ServerConfig, 0, len(addresses)) - for _, addr := range addresses { - ip, portStr, err := net.SplitHostPort(addr) - if err != nil { - return nil, perrors.WithMessagef(err, "split [%s] ", addr) - } - port, _ := strconv.Atoi(portStr) - serverConfigs = append(serverConfigs, nacosConstant.ServerConfig{ - IpAddr: ip, - Port: uint64(port), - }) - } - configMap["serverConfigs"] = serverConfigs - - var clientConfig nacosConstant.ClientConfig - timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) - if err != nil { - return nil, err - } - clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000) - clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs - clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") - clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") - clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") - clientConfig.NotLoadCacheAtStart = true - configMap["clientConfig"] = clientConfig - - return configMap, nil -} diff --git a/remoting/nacos/builder.go b/remoting/nacos/builder.go new file mode 100644 index 0000000000..bf89d4a7b9 --- /dev/null +++ b/remoting/nacos/builder.go @@ -0,0 +1,95 @@ +/* + * 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 nacos + +import ( + "net" + "strconv" + "strings" + "time" +) + +import ( + "github.com/nacos-group/nacos-sdk-go/clients" + "github.com/nacos-group/nacos-sdk-go/clients/config_client" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" + nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" + perrors "github.com/pkg/errors" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" +) + +func NewNacosNamingClient(url *common.URL) (naming_client.INamingClient, error) { + nacosConfig, err := getNacosConfig(url) + if err != nil { + return nil, err + } + return clients.CreateNamingClient(nacosConfig) +} + +func NewNacosConfigClient(url *common.URL) (config_client.IConfigClient, error) { + nacosConfig, err := getNacosConfig(url) + if err != nil { + return nil, err + } + return clients.CreateConfigClient(nacosConfig) +} + +// getNacosConfig will return the nacos config +func getNacosConfig(url *common.URL) (map[string]interface{}, error) { + if url == nil { + return nil, perrors.New("url is empty!") + } + if len(url.Location) == 0 { + return nil, perrors.New("url.location is empty!") + } + configMap := make(map[string]interface{}, 2) + + addresses := strings.Split(url.Location, ",") + serverConfigs := make([]nacosConstant.ServerConfig, 0, len(addresses)) + for _, addr := range addresses { + ip, portStr, err := net.SplitHostPort(addr) + if err != nil { + return nil, perrors.WithMessagef(err, "split [%s] ", addr) + } + port, _ := strconv.Atoi(portStr) + serverConfigs = append(serverConfigs, nacosConstant.ServerConfig{ + IpAddr: ip, + Port: uint64(port), + }) + } + configMap["serverConfigs"] = serverConfigs + + var clientConfig nacosConstant.ClientConfig + timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) + if err != nil { + return nil, err + } + clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000) + clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs + clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") + clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") + clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") + clientConfig.NotLoadCacheAtStart = true + configMap["clientConfig"] = clientConfig + + return configMap, nil +} From b968f7b9be0b096d871ee879d1fe4035ec4ecd5c Mon Sep 17 00:00:00 2001 From: flycash Date: Sat, 30 May 2020 19:18:03 +0800 Subject: [PATCH 084/209] Add unregiste implementation --- .../service_discovery_registry.go | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 6b25bc60ef..30264116a9 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -35,7 +35,7 @@ import ( "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/metadata/mapping" "github.com/apache/dubbo-go/metadata/service" - "github.com/apache/dubbo-go/metadata/service/inmemory" + "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" @@ -76,8 +76,10 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) - // TODO it's need to get implement by factory - metaDataService := inmemory.NewMetadataService() + metaDataService, err := remote.NewMetadataService() + if err != nil { + return nil, perrors.WithMessage(err, "could not init metadata service") + } return &serviceDiscoveryRegistry{ url: url, serviceDiscovery: serviceDiscovery, @@ -91,11 +93,17 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { } func (s *serviceDiscoveryRegistry) UnRegister(url common.URL) error { - panic("implement me") + if !shouldRegister(url) { + return nil + } + return s.metaDataService.UnexportURL(url) } -func (s *serviceDiscoveryRegistry) UnSubscribe(*common.URL, registry.NotifyListener) error { - panic("implement me") +func (s *serviceDiscoveryRegistry) UnSubscribe(url *common.URL, listener registry.NotifyListener) error { + if !shouldSubscribe(*url) { + return nil + } + return s.metaDataService.UnsubscribeURL(*url) } func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { @@ -125,6 +133,7 @@ func (s *serviceDiscoveryRegistry) GetUrl() common.URL { } func (s *serviceDiscoveryRegistry) IsAvailable() bool { + // TODO(whether available depends on metadata service and service discovery) return true } From cc4d56395451ce3cb4822a1fb719ad63720b1a46 Mon Sep 17 00:00:00 2001 From: flycash Date: Sat, 30 May 2020 21:32:59 +0800 Subject: [PATCH 085/209] server start successfully --- config/config_loader.go | 9 ++++- config/metadata_report_config.go | 37 ++++++++++--------- config/metadata_report_config_test.go | 7 +++- config/provider_config.go | 8 ++-- config/remote_config.go | 18 +++++++-- .../mapping/dynamic/service_name_mapping.go | 5 +++ metadata/report/delegate/delegate_report.go | 2 +- metadata/service/remote/service.go | 10 ++--- registry/nacos/service_discovery_test.go | 9 ++--- .../service_discovery_registry.go | 8 +++- remoting/nacos/builder.go | 2 +- remoting/nacos/builder_test.go | 3 +- 12 files changed, 74 insertions(+), 44 deletions(-) diff --git a/config/config_loader.go b/config/config_loader.go index 0922a7a285..b79c2e8249 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -68,11 +68,15 @@ func init() { if errCon := ConsumerInit(confConFile); errCon != nil { log.Printf("[consumerInit] %#v", errCon) consumerConfig = nil + } else { + baseConfig = &consumerConfig.BaseConfig } if errPro := ProviderInit(confProFile); errPro != nil { log.Printf("[providerInit] %#v", errPro) providerConfig = nil + } else { + baseConfig = &providerConfig.BaseConfig } } @@ -282,7 +286,7 @@ func GetProviderConfig() ProviderConfig { defer configAccessMutex.Unlock() if providerConfig == nil { logger.Warnf("creating empty provider config. You should see this log only once.") - providerConfig = &ProviderConfig{} + return ProviderConfig{} } } return *providerConfig @@ -300,13 +304,14 @@ func GetConsumerConfig() ConsumerConfig { defer configAccessMutex.Unlock() if consumerConfig == nil { logger.Warnf("creating empty consumer config. You should see this log only once.") - consumerConfig = &ConsumerConfig{} + return ConsumerConfig{} } } return *consumerConfig } func GetBaseConfig() *BaseConfig { + if baseConfig == nil { baseConfigOnce.Do(func() { baseConfig = &BaseConfig{ diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index 41fb6b4769..caf7c55c28 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -34,13 +34,10 @@ 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"` - Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` - TimeoutStr string `yaml:"timeout" default:"5s" json:"timeout,omitempty" property:"timeout"` // unit: second - Group string `yaml:"group" json:"group,omitempty" property:"group"` + Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` + RemoteRef string `required:"true" yaml:"remote_ref" json:"remote_ref,omitempty"` + Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` } // Prefix ... @@ -70,18 +67,24 @@ func (c *MetadataReportConfig) ToUrl() (*common.URL, error) { } } - url, err := common.NewURL(c.Address, + rc, ok := GetBaseConfig().GetRemoteConfig(c.RemoteRef) + + if !ok { + return nil, perrors.New("Could not find out the remote ref config, name: " + c.RemoteRef) + } + + res, err := common.NewURL(rc.Address, common.WithParams(urlMap), - common.WithUsername(c.Username), - common.WithPassword(c.Password), - common.WithLocation(c.Address), + common.WithUsername(rc.Username), + common.WithPassword(rc.Password), + common.WithLocation(rc.Address), common.WithProtocol(c.Protocol), ) - if err != nil || len(url.Protocol) == 0 { + if err != nil || len(res.Protocol) == 0 { return nil, perrors.New("Invalid MetadataReportConfig.") } - url.SetParam("metadata", url.Protocol) - return &url, nil + res.SetParam("metadata", res.Protocol) + return &res, nil } func (c *MetadataReportConfig) IsValid() bool { @@ -94,10 +97,8 @@ func startMetadataReport(metadataType string, metadataReportConfig *MetadataRepo return nil } - if metadataType == constant.METACONFIG_REMOTE { - return perrors.New("No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled.") - } else if metadataType == constant.METACONFIG_REMOTE && len(metadataReportConfig.Address) == 0 { - return perrors.New("MetadataConfig address can not be empty.") + if metadataType == constant.METACONFIG_REMOTE && len(metadataReportConfig.RemoteRef) == 0 { + return perrors.New("MetadataConfig remote ref can not be empty.") } if url, err := metadataReportConfig.ToUrl(); err == nil { diff --git a/config/metadata_report_config_test.go b/config/metadata_report_config_test.go index 635feecc2d..1c585ee79d 100644 --- a/config/metadata_report_config_test.go +++ b/config/metadata_report_config_test.go @@ -24,12 +24,15 @@ import ( ) func TestMetadataReportConfig_ToUrl(t *testing.T) { - metadataReportConfig := MetadataReportConfig{ - Protocol: "mock", + GetBaseConfig().Remotes["mock"] = &RemoteConfig{ Address: "127.0.0.1:2181", Username: "test", Password: "test", TimeoutStr: "3s", + } + metadataReportConfig := MetadataReportConfig{ + Protocol: "mock", + RemoteRef: "mock", Params: map[string]string{ "k": "v", }, diff --git a/config/provider_config.go b/config/provider_config.go index 81f20e864d..f0d3c4cf7f 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -87,15 +87,15 @@ func ProviderInit(confProFile string) error { } providerConfig.fileStream = bytes.NewBuffer(fileStream) - //set method interfaceId & interfaceName + // set method interfaceId & interfaceName for k, v := range providerConfig.Services { - //set id for reference + // set id for reference for _, n := range providerConfig.Services[k].Methods { n.InterfaceName = v.InterfaceName n.InterfaceId = k } } - //start the metadata report if config set + // start the metadata report if config set if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { return perrors.WithMessagef(err, "Provider starts metadata report error, and the error is {%#v}", err) } @@ -105,7 +105,7 @@ func ProviderInit(confProFile string) error { } func configCenterRefreshProvider() error { - //fresh it + // fresh it if providerConfig.ConfigCenterConfig != nil { providerConfig.fatherConfig = providerConfig if err := providerConfig.startConfigCenter(); err != nil { diff --git a/config/remote_config.go b/config/remote_config.go index ed9dab37a4..4d17cc1c41 100644 --- a/config/remote_config.go +++ b/config/remote_config.go @@ -19,12 +19,24 @@ package config import ( "time" + + "github.com/apache/dubbo-go/common/logger" ) type RemoteConfig struct { - Address string `yaml:"address" json:"address,omitempty"` - Timeout time.Duration `default:"10s" yaml:"timeout" json:"timeout,omitempty"` - Params map[string]string `yaml:"params" json:"address,omitempty"` + Address string `yaml:"address" json:"address,omitempty"` + TimeoutStr string `default:"5s" yaml:"timeout" json:"timeout,omitempty"` + Username string `yaml:"username" json:"username,omitempty" property:"username"` + Password string `yaml:"password" json:"password,omitempty" property:"password"` + Params map[string]string `yaml:"params" json:"address,omitempty"` +} + +func (rc *RemoteConfig) Timeout() time.Duration { + if res, err := time.ParseDuration(rc.TimeoutStr); err == nil { + return res + } + logger.Errorf("Could not parse the timeout string to Duration: %s, the default value will be returned", rc.TimeoutStr) + return 5 * time.Second } // GetParam will return the value of the key. If not found, def will be return; diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 49b7747065..3d502b6184 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -18,6 +18,7 @@ package dynamic import ( + "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/metadata/mapping" "strconv" "sync" @@ -41,6 +42,10 @@ const ( slash = "/" ) +func init() { + extension.SetServiceNameMapping("dynamic", GetServiceNameMappingInstance) +} + // DynamicConfigurationServiceNameMapping is the implementation based on config center type DynamicConfigurationServiceNameMapping struct { dc config_center.DynamicConfiguration diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index cb7e42030b..4bc781a7f5 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -130,7 +130,7 @@ func NewMetadataReport() (*MetadataReport, error) { scheduler := gocron.NewScheduler(time.UTC) _, err := scheduler.Every(1).Day().Do( func() { - logger.Info("start to publish all metadata in metadata report %v.", url) + logger.Info("start to publish all metadata in metadata report %s.", url.String()) bmr.allMetadataReportsLock.RLock() bmr.doHandlerMetadataCollection(bmr.allMetadataReports) bmr.allMetadataReportsLock.RUnlock() diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index f55c482ad8..cd8a2dc837 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -65,7 +65,7 @@ func (mts *MetadataService) setInMemoryMetadataService(metadata *inmemory.Metada // ExportURL will be implemented by in memory service func (mts *MetadataService) ExportURL(url common.URL) (bool, error) { - return true, nil + return mts.inMemoryMetadataService.ExportURL(url) } // UnexportURL @@ -76,13 +76,13 @@ func (mts *MetadataService) UnexportURL(url common.URL) error { } // SubscribeURL will be implemented by in memory service -func (MetadataService) SubscribeURL(url common.URL) (bool, error) { - return true, nil +func (mts *MetadataService) SubscribeURL(url common.URL) (bool, error) { + return mts.inMemoryMetadataService.SubscribeURL(url) } // UnsubscribeURL will be implemented by in memory service -func (MetadataService) UnsubscribeURL(url common.URL) error { - return nil +func (mts *MetadataService) UnsubscribeURL(url common.URL) error { + return mts.UnsubscribeURL(url) } // PublishServiceDefinition will call remote metadata's StoreProviderMetadata to store url info and service definition diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index ca0f24976e..633a1d41c8 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -19,7 +19,6 @@ package nacos import ( "testing" - "time" "github.com/apache/dubbo-go/config" ) @@ -59,8 +58,8 @@ func Test_newNacosServiceDiscovery(t *testing.T) { assert.NotNil(t, err) config.GetBaseConfig().Remotes["mock"] = &config.RemoteConfig{ - Address: "console.nacos.io:80", - Timeout: 10 * time.Second, + Address: "console.nacos.io:80", + TimeoutStr: "10s", } res, err := newNacosServiceDiscovery(name) @@ -168,7 +167,7 @@ func prepareData() { } config.GetBaseConfig().Remotes[testName] = &config.RemoteConfig{ - Address: "console.nacos.io:80", - Timeout: 10 * time.Second, + Address: "console.nacos.io:80", + TimeoutStr: "10s", } } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 30264116a9..33d22e7339 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -33,6 +33,7 @@ import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/metadata/mapping" "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/remote" @@ -107,7 +108,12 @@ func (s *serviceDiscoveryRegistry) UnSubscribe(url *common.URL, listener registr } func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { - return extension.GetServiceDiscovery(url.Protocol, "TODO") + sdcName := url.GetParam(constant.SERVICE_DISCOVERY_KEY, "") + sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(sdcName) + if !ok { + return nil, perrors.Errorf("The service discovery with name: %s is not found", sdcName) + } + return extension.GetServiceDiscovery(sdc.Protocol, sdcName) } func parseServices(literalServices string) *gxset.HashSet { diff --git a/remoting/nacos/builder.go b/remoting/nacos/builder.go index 170f23f60c..16325f88cc 100644 --- a/remoting/nacos/builder.go +++ b/remoting/nacos/builder.go @@ -118,7 +118,7 @@ func NewNacosClient(rc *config.RemoteConfig) (naming_client.INamingClient, error configMap["serverConfigs"] = serverConfigs var clientConfig nacosConstant.ClientConfig - timeout := rc.Timeout + timeout := rc.Timeout() clientConfig.TimeoutMs = uint64(timeout.Nanoseconds() / constant.MsToNanoRate) clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs clientConfig.CacheDir = rc.GetParam(constant.NACOS_CACHE_DIR_KEY, "") diff --git a/remoting/nacos/builder_test.go b/remoting/nacos/builder_test.go index bbfadef71b..61d13ef26f 100644 --- a/remoting/nacos/builder_test.go +++ b/remoting/nacos/builder_test.go @@ -19,7 +19,6 @@ package nacos import ( "testing" - "time" ) import ( @@ -43,7 +42,7 @@ func TestNewNacosClient(t *testing.T) { assert.NotNil(t, err) rc.Address = "console.nacos.io:80" - rc.Timeout = 10 * time.Second + rc.TimeoutStr = "10s" client, err = NewNacosClient(rc) assert.NotNil(t, client) assert.Nil(t, err) From 035d7d919be112eb74f64941522557b7676efe2c Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 31 May 2020 15:55:44 +0800 Subject: [PATCH 086/209] Fix bug: using EventPublishServiceDiscovery --- config/config_loader.go | 10 ---------- metadata/report/delegate/delegate_report.go | 2 +- .../servicediscovery/service_discovery_registry.go | 8 +++++++- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/config/config_loader.go b/config/config_loader.go index b79c2e8249..a4dc62ffbd 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -276,16 +276,10 @@ func GetApplicationConfig() *ApplicationConfig { // GetProviderConfig find the provider config // if not found, create new one -// we use double-check to reduce race condition -// In general, it will be locked 0 or 1 time. -// So you don't need to worry about the race condition func GetProviderConfig() ProviderConfig { if providerConfig == nil { logger.Warnf("providerConfig is nil! we will try to create one") - configAccessMutex.Lock() - defer configAccessMutex.Unlock() if providerConfig == nil { - logger.Warnf("creating empty provider config. You should see this log only once.") return ProviderConfig{} } } @@ -299,11 +293,7 @@ func GetProviderConfig() ProviderConfig { // So you don't need to worry about the race condition func GetConsumerConfig() ConsumerConfig { if consumerConfig == nil { - logger.Warnf("consumerConfig is nil! we will try to create one") - configAccessMutex.Lock() - defer configAccessMutex.Unlock() if consumerConfig == nil { - logger.Warnf("creating empty consumer config. You should see this log only once.") return ConsumerConfig{} } } diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 4bc781a7f5..1ab7e4e7c3 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -130,7 +130,7 @@ func NewMetadataReport() (*MetadataReport, error) { scheduler := gocron.NewScheduler(time.UTC) _, err := scheduler.Every(1).Day().Do( func() { - logger.Info("start to publish all metadata in metadata report %s.", url.String()) + logger.Infof("start to publish all metadata in metadata report %s.", url.String()) bmr.allMetadataReportsLock.RLock() bmr.doHandlerMetadataCollection(bmr.allMetadataReports) bmr.allMetadataReportsLock.RUnlock() diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 33d22e7339..555513a444 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -38,6 +38,7 @@ import ( "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" + registryCommon "github.com/apache/dubbo-go/registry/common" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" @@ -113,7 +114,11 @@ func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { if !ok { return nil, perrors.Errorf("The service discovery with name: %s is not found", sdcName) } - return extension.GetServiceDiscovery(sdc.Protocol, sdcName) + originServiceDiscovery, err := extension.GetServiceDiscovery(sdc.Protocol, sdcName) + if err != nil { + return nil, perrors.WithMessage(err, "Create service discovery fialed") + } + return registryCommon.NewEventPublishingServiceDiscovery(originServiceDiscovery), nil } func parseServices(literalServices string) *gxset.HashSet { @@ -155,6 +160,7 @@ func (s *serviceDiscoveryRegistry) Register(url common.URL) error { return nil } ok, err := s.metaDataService.ExportURL(url) + s.metaDataService.PublishServiceDefinition(url) if err != nil { logger.Errorf("The URL[%s] registry catch error:%s!", url.String(), err.Error()) return err From e499d1c81b3aaadb0a1871caa3ace0900313d3c0 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 15:16:41 +0800 Subject: [PATCH 087/209] lock optimize --- registry/etcdv3/registry.go | 8 +++++++- registry/kubernetes/registry.go | 8 +++++++- registry/zookeeper/registry.go | 35 +++++++++++++++++++++++---------- remoting/zookeeper/client.go | 6 ------ 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index a65d090349..a94352c665 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -119,8 +119,14 @@ func (r *etcdV3Registry) DoUnregister(root string, node string) error { } func (r *etcdV3Registry) CloseAndNilClient() { - r.client.Close() + r.cltLock.Lock() + client := r.client r.client = nil + r.cltLock.Unlock() + if client == nil { + return + } + client.Close() } func (r *etcdV3Registry) CloseListener() { diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index 7ee0f6b0ee..4c59fc080b 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -81,8 +81,14 @@ func (r *kubernetesRegistry) SetClient(client *kubernetes.Client) { } func (r *kubernetesRegistry) CloseAndNilClient() { - r.client.Close() + r.cltLock.Lock() + client := r.client r.client = nil + r.cltLock.Unlock() + if client == nil { + return + } + client.Close() } func (r *kubernetesRegistry) CloseListener() { diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 5d5f9e0526..fd6ef86e77 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -156,12 +156,15 @@ func (r *zkRegistry) DoRegister(root string, node string) error { } func (r *zkRegistry) DoUnregister(root string, node string) error { - r.cltLock.Lock() - defer r.cltLock.Unlock() - if !r.ZkClient().ZkConnValid() { + client := r.client + if client == nil { + return perrors.New("zk Client is null, can not process registerTempZookeeperNode ") + } + + if !client.ZkConnValid() { return perrors.Errorf("zk client is not valid.") } - return r.ZkClient().Delete(path.Join(root, node)) + return client.Delete(path.Join(root, node)) } func (r *zkRegistry) DoSubscribe(conf *common.URL) (registry.Listener, error) { @@ -173,8 +176,15 @@ func (r *zkRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) } func (r *zkRegistry) CloseAndNilClient() { - r.client.Close() + r.cltLock.Lock() + client := r.client r.client = nil + r.cltLock.Unlock() + + if client == nil { + return + } + client.Close() } func (r *zkRegistry) ZkClient() *zookeeper.ZookeeperClient { @@ -202,22 +212,27 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { ) r.cltLock.Lock() - defer r.cltLock.Unlock() - err = r.client.Create(root) + client := r.client + r.cltLock.Unlock() + if client == nil { + return perrors.New("zk Client is null, can not process registerTempZookeeperNode ") + } + + err = client.Create(root) if err != nil { logger.Errorf("zk.Create(root{%s}) = err{%v}", root, perrors.WithStack(err)) return perrors.WithStack(err) } // try to register the node - zkPath, err = r.client.RegisterTemp(root, node) + zkPath, err = client.RegisterTemp(root, node) if err != nil { logger.Errorf("Register temp node(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err)) if perrors.Cause(err) == zk.ErrNodeExists { // should delete the old node logger.Info("Register temp node failed, try to delete the old and recreate (root{%s}, node{%s}) , ignore!", root, node) - if err = r.client.Delete(zkPath); err == nil { - _, err = r.client.RegisterTemp(root, node) + if err = client.Delete(zkPath); err == nil { + _, err = client.RegisterTemp(root, node) } if err != nil { logger.Errorf("Recreate the temp node failed, (root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err)) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index bd1da54776..59d976f5d8 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -419,9 +419,7 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { for _, str := range strings.Split(basePath, "/")[1:] { tmpPath = path.Join(tmpPath, "/", str) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { _, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll)) } @@ -446,9 +444,7 @@ func (z *ZookeeperClient) Delete(basePath string) error { ) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { err = conn.Delete(basePath, -1) } @@ -468,9 +464,7 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er err = errNilZkClientConn data = []byte("") zkPath = path.Join(basePath) + "/" + node - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } From 3ae2a82ec79f77273cfeff963702bd80fb1d2520 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 15:21:28 +0800 Subject: [PATCH 088/209] revert changes for CloseAndNilClient --- registry/etcdv3/registry.go | 8 +------- registry/kubernetes/registry.go | 8 +------- registry/zookeeper/registry.go | 9 +-------- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index a94352c665..a65d090349 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -119,14 +119,8 @@ func (r *etcdV3Registry) DoUnregister(root string, node string) error { } func (r *etcdV3Registry) CloseAndNilClient() { - r.cltLock.Lock() - client := r.client + r.client.Close() r.client = nil - r.cltLock.Unlock() - if client == nil { - return - } - client.Close() } func (r *etcdV3Registry) CloseListener() { diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go index 4c59fc080b..7ee0f6b0ee 100644 --- a/registry/kubernetes/registry.go +++ b/registry/kubernetes/registry.go @@ -81,14 +81,8 @@ func (r *kubernetesRegistry) SetClient(client *kubernetes.Client) { } func (r *kubernetesRegistry) CloseAndNilClient() { - r.cltLock.Lock() - client := r.client + r.client.Close() r.client = nil - r.cltLock.Unlock() - if client == nil { - return - } - client.Close() } func (r *kubernetesRegistry) CloseListener() { diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index fd6ef86e77..32f9fe7a29 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -176,15 +176,8 @@ func (r *zkRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error) } func (r *zkRegistry) CloseAndNilClient() { - r.cltLock.Lock() - client := r.client + r.client.Close() r.client = nil - r.cltLock.Unlock() - - if client == nil { - return - } - client.Close() } func (r *zkRegistry) ZkClient() *zookeeper.ZookeeperClient { From 977fffa8500d65720ab23e85a4e263c78b9a02e1 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 15:24:01 +0800 Subject: [PATCH 089/209] lock optimize --- registry/zookeeper/registry.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 32f9fe7a29..912f8c2669 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -204,9 +204,7 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { zkPath string ) - r.cltLock.Lock() client := r.client - r.cltLock.Unlock() if client == nil { return perrors.New("zk Client is null, can not process registerTempZookeeperNode ") } @@ -260,9 +258,7 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen zkListener = NewRegistryConfigurationListener(r.client, r, conf) if r.listener == nil { - r.cltLock.Lock() client := r.client - r.cltLock.Unlock() if client == nil { return nil, perrors.New("zk connection broken") } From 9c623ec6b16432f9b6ae773193f9cc3092d93a22 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 15:34:23 +0800 Subject: [PATCH 090/209] revert changes for registerTempZookeeperNode --- registry/zookeeper/registry.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 912f8c2669..b8f0cfb9f4 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -204,26 +204,23 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { zkPath string ) - client := r.client - if client == nil { - return perrors.New("zk Client is null, can not process registerTempZookeeperNode ") - } - - err = client.Create(root) + r.cltLock.Lock() + defer r.cltLock.Unlock() + err = r.client.Create(root) if err != nil { logger.Errorf("zk.Create(root{%s}) = err{%v}", root, perrors.WithStack(err)) return perrors.WithStack(err) } // try to register the node - zkPath, err = client.RegisterTemp(root, node) + zkPath, err = r.client.RegisterTemp(root, node) if err != nil { logger.Errorf("Register temp node(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err)) if perrors.Cause(err) == zk.ErrNodeExists { // should delete the old node logger.Info("Register temp node failed, try to delete the old and recreate (root{%s}, node{%s}) , ignore!", root, node) - if err = client.Delete(zkPath); err == nil { - _, err = client.RegisterTemp(root, node) + if err = r.client.Delete(zkPath); err == nil { + _, err = r.client.RegisterTemp(root, node) } if err != nil { logger.Errorf("Recreate the temp node failed, (root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err)) From f7ea5f2b3b38627bac995cec94fc4d5e8ec31c67 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 15:53:03 +0800 Subject: [PATCH 091/209] lock optimize --- remoting/zookeeper/client.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 59d976f5d8..fcf07d4666 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -487,9 +487,7 @@ func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, ) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { tmpPath, err = conn.Create( path.Join(basePath)+"/", @@ -520,9 +518,7 @@ func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, ) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { children, stat, watcher, err = conn.ChildrenW(path) } @@ -556,9 +552,7 @@ func (z *ZookeeperClient) GetChildren(path string) ([]string, error) { ) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { children, stat, err = conn.Children(path) } @@ -589,9 +583,7 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { ) err = errNilZkClientConn - z.Lock() conn := z.Conn - z.Unlock() if conn != nil { exist, _, watcher, err = conn.ExistsW(zkPath) } From db059d3db1eb88ca967ef78b1ca73082afa23501 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 23:13:09 +0800 Subject: [PATCH 092/209] lock optimize : change to rwlock --- registry/zookeeper/registry.go | 12 ++++++------ remoting/zookeeper/client.go | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index b8f0cfb9f4..cf442a1969 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -156,15 +156,13 @@ func (r *zkRegistry) DoRegister(root string, node string) error { } func (r *zkRegistry) DoUnregister(root string, node string) error { - client := r.client - if client == nil { - return perrors.New("zk Client is null, can not process registerTempZookeeperNode ") - } + r.cltLock.Lock() + defer r.cltLock.Unlock() - if !client.ZkConnValid() { + if !r.ZkClient().ZkConnValid() { return perrors.Errorf("zk client is not valid.") } - return client.Delete(path.Join(root, node)) + return r.ZkClient().Delete(path.Join(root, node)) } func (r *zkRegistry) DoSubscribe(conf *common.URL) (registry.Listener, error) { @@ -255,7 +253,9 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen zkListener = NewRegistryConfigurationListener(r.client, r, conf) if r.listener == nil { + r.cltLock.Lock() client := r.client + r.cltLock.Unlock() if client == nil { return nil, perrors.New("zk connection broken") } diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index fcf07d4666..cc34c76b42 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -51,7 +51,7 @@ var ( type ZookeeperClient struct { name string ZkAddrs []string - sync.Mutex // for conn + sync.RWMutex // for conn Conn *zk.Conn Timeout time.Duration exit chan struct{} @@ -419,7 +419,9 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { for _, str := range strings.Split(basePath, "/")[1:] { tmpPath = path.Join(tmpPath, "/", str) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { _, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll)) } @@ -444,7 +446,9 @@ func (z *ZookeeperClient) Delete(basePath string) error { ) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { err = conn.Delete(basePath, -1) } @@ -464,7 +468,9 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er err = errNilZkClientConn data = []byte("") zkPath = path.Join(basePath) + "/" + node + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } @@ -487,7 +493,9 @@ func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, ) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { tmpPath, err = conn.Create( path.Join(basePath)+"/", @@ -518,7 +526,9 @@ func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, ) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { children, stat, watcher, err = conn.ChildrenW(path) } @@ -552,7 +562,9 @@ func (z *ZookeeperClient) GetChildren(path string) ([]string, error) { ) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { children, stat, err = conn.Children(path) } @@ -583,7 +595,9 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { ) err = errNilZkClientConn + z.RLock() conn := z.Conn + z.RUnlock() if conn != nil { exist, _, watcher, err = conn.ExistsW(zkPath) } From 1d1bbe08088bbe704f79ffdbf3e19f0ef1fbda0d Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 1 Jun 2020 23:17:33 +0800 Subject: [PATCH 093/209] lock optimize : change to rwlock --- registry/zookeeper/registry.go | 1 - remoting/zookeeper/client.go | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index cf442a1969..5d5f9e0526 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -158,7 +158,6 @@ func (r *zkRegistry) DoRegister(root string, node string) error { func (r *zkRegistry) DoUnregister(root string, node string) error { r.cltLock.Lock() defer r.cltLock.Unlock() - if !r.ZkClient().ZkConnValid() { return perrors.Errorf("zk client is not valid.") } diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index cc34c76b42..c66bf4b673 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -278,7 +278,7 @@ LOOP: break LOOP case (int)(zk.EventNodeDataChanged), (int)(zk.EventNodeChildrenChanged): logger.Infof("zkClient{%s} get zk node changed event{path:%s}", z.name, event.Path) - z.Lock() + z.RLock() for p, a := range z.eventRegistry { if strings.HasPrefix(p, event.Path) { logger.Infof("send event{state:zk.EventNodeDataChange, Path:%s} notify event to path{%s} related listener", @@ -288,7 +288,7 @@ LOOP: } } } - z.Unlock() + z.RUnlock() case (int)(zk.StateConnecting), (int)(zk.StateConnected), (int)(zk.StateHasSession): if state == (int)(zk.StateHasSession) { continue @@ -371,11 +371,11 @@ func (z *ZookeeperClient) ZkConnValid() bool { } valid := true - z.Lock() + z.RLock() if z.Conn == nil { valid = false } - z.Unlock() + z.RUnlock() return valid } From 5f0084a4f2f1dcaead55fe72fab16c142fb90c34 Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 2 Jun 2020 11:46:42 +0800 Subject: [PATCH 094/209] Fix review --- metadata/report/nacos/report.go | 3 +++ metadata/report/nacos/report_test.go | 4 ++++ registry/nacos/base_registry.go | 5 +---- remoting/nacos/builder.go | 24 +++++++++++++++--------- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 9dbec51822..63ca7ec240 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -51,6 +51,7 @@ type nacosMetadataReport struct { } // StoreProviderMetadata will store the metadata +// metadata including the basic info of the server, provider info, and other user custom info func (n *nacosMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { return n.storeMetadata(vo.ConfigParam{ DataId: providerIdentifier.GetIdentifierKey(), @@ -60,6 +61,7 @@ func (n *nacosMetadataReport) StoreProviderMetadata(providerIdentifier *identifi } // StoreConsumerMetadata will store the metadata +// metadata including the basic info of the server, consumer info, and other user custom info func (n *nacosMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { return n.storeMetadata(vo.ConfigParam{ DataId: consumerMetadataIdentifier.GetIdentifierKey(), @@ -69,6 +71,7 @@ func (n *nacosMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier * } // SaveServiceMetadata will store the metadata +// metadata including the basic info of the server, service info, and other user custom info func (n *nacosMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { return n.storeMetadata(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 711e6281a2..19ca2e5a48 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -20,9 +20,13 @@ package nacos import ( "strconv" "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" diff --git a/registry/nacos/base_registry.go b/registry/nacos/base_registry.go index 636ffc302e..cb1c32dce5 100644 --- a/registry/nacos/base_registry.go +++ b/registry/nacos/base_registry.go @@ -17,16 +17,13 @@ package nacos -import ( - "github.com/apache/dubbo-go/remoting/nacos" -) - import ( "github.com/nacos-group/nacos-sdk-go/clients/naming_client" ) import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/remoting/nacos" ) // baseRegistry is the parent of both interface-level registry diff --git a/remoting/nacos/builder.go b/remoting/nacos/builder.go index bf89d4a7b9..4da309936a 100644 --- a/remoting/nacos/builder.go +++ b/remoting/nacos/builder.go @@ -70,7 +70,10 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { if err != nil { return nil, perrors.WithMessagef(err, "split [%s] ", addr) } - port, _ := strconv.Atoi(portStr) + port, err := strconv.Atoi(portStr) + if err != nil { + return configMap, perrors.WithMessage(err, "the port string is invalid. "+portStr) + } serverConfigs = append(serverConfigs, nacosConstant.ServerConfig{ IpAddr: ip, Port: uint64(port), @@ -78,18 +81,21 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { } configMap["serverConfigs"] = serverConfigs - var clientConfig nacosConstant.ClientConfig timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) if err != nil { return nil, err } - clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000) - clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs - clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") - clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") - clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") - clientConfig.NotLoadCacheAtStart = true - configMap["clientConfig"] = clientConfig + + timeoutMs := uint64(timeout.Nanoseconds() / constant.MsToNanoRate) + + configMap["clientConfig"] = nacosConstant.ClientConfig{ + TimeoutMs: timeoutMs, + ListenInterval: 2 * timeoutMs, + CacheDir: url.GetParam(constant.NACOS_CACHE_DIR_KEY, ""), + LogDir: url.GetParam(constant.NACOS_LOG_DIR_KEY, ""), + Endpoint: url.GetParam(constant.NACOS_ENDPOINT, ""), + NotLoadCacheAtStart: true, + } return configMap, nil } From b7606219ddf38d5d1e96439aa59e6c0f81653df8 Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 2 Jun 2020 11:36:07 +0800 Subject: [PATCH 095/209] Add events and eventListener --- common/constant/default.go | 4 ++ common/constant/key.go | 3 - .../extension/service_instance_customizer.go | 49 +++++++++++++++++ common/extension/service_name_mapping.go | 14 ++--- common/observer/event_listener.go | 1 + common/rpc_service_test.go | 6 +- config/application_config.go | 3 +- config/base_config.go | 5 +- config/config_loader.go | 14 ++++- config/metadata_report_config.go | 2 +- config/provider_config.go | 6 -- filter/rejected_execution_handler.go | 2 +- .../mapping/dynamic/service_name_mapping.go | 22 ++------ .../mapping/memory/service_name_mapping.go | 19 +------ metadata/service/inmemory/service.go | 6 +- metadata/service/remote/service.go | 53 +++++++++++------- metadata/service/service.go | 5 +- registry/base_registry.go | 2 +- registry/directory/directory_test.go | 2 +- .../customizable_service_instance_listener.go | 55 +++++++++++++++++++ ...vent_publishing_service_deiscovery_test.go | 2 +- .../event_publishing_service_discovery.go | 2 +- registry/event/log_event_listener.go | 48 ++++++++++++++++ registry/event/log_event_listener_test.go | 31 +++++++++++ .../protocol_ports_metadata_customizer.go | 52 ++++++++++++++++++ .../event/service_config_exported_event.go | 26 +++++++++ .../service_discovery_event.go | 2 +- .../service_instance_event.go | 2 +- .../event/service_name_mapping_listener.go | 48 ++++++++++++++++ registry/event_listener.go | 2 +- registry/nacos/service_discovery.go | 2 +- registry/registry.go | 2 +- registry/service_instance.go | 10 ++++ .../service_discovery_registry.go | 50 ++++++++++++++--- .../service_discovery_registry_test.go | 8 +-- test/integrate/dubbo/go-client/client.go | 2 +- test/integrate/dubbo/go-server/server.go | 2 +- 37 files changed, 452 insertions(+), 112 deletions(-) create mode 100644 common/extension/service_instance_customizer.go create mode 100644 registry/event/customizable_service_instance_listener.go rename registry/{common => event}/event_publishing_service_deiscovery_test.go (99%) rename registry/{common => event}/event_publishing_service_discovery.go (99%) create mode 100644 registry/event/log_event_listener.go create mode 100644 registry/event/log_event_listener_test.go create mode 100644 registry/event/protocol_ports_metadata_customizer.go create mode 100644 registry/event/service_config_exported_event.go rename registry/{common => event}/service_discovery_event.go (99%) rename registry/{common => event}/service_instance_event.go (99%) create mode 100644 registry/event/service_name_mapping_listener.go diff --git a/common/constant/default.go b/common/constant/default.go index 6b9d914c87..8442609c59 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -78,3 +78,7 @@ const ( const ( SIMPLE_METADATA_SERVICE_NAME = "MetadataService" ) + +const ( + SERVICE_DISCOVERY_DEFAULT_GROUP = "DEFAULT_GROUP" +) \ No newline at end of file diff --git a/common/constant/key.go b/common/constant/key.go index 15496628eb..394f2d8c04 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -273,9 +273,6 @@ const ( METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" - // used by URL - // SERVICE_NAME_MAPPING_KEY indicate that which service name mapping instance will be used - SERVICE_NAME_MAPPING_KEY = "name_mapping" // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" ) diff --git a/common/extension/service_instance_customizer.go b/common/extension/service_instance_customizer.go new file mode 100644 index 0000000000..40f8ca0c5d --- /dev/null +++ b/common/extension/service_instance_customizer.go @@ -0,0 +1,49 @@ +/* + * 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 ( + "sort" + + "github.com/apache/dubbo-go/registry" +) + +var ( + customizers = make([]registry.ServiceInstanceCustomizer, 0, 8) +) + +// AddCustomizers will put the customizer into slices and then sort them; +// this method will be invoked several time, so we sort them here. +func AddCustomizers(cus registry.ServiceInstanceCustomizer) { + customizers = append(customizers, cus) + sort.Stable(customizerSlice(customizers)) +} + +// GetCustomizers will return the sorted customizer +func GetCustomizers() []registry.ServiceInstanceCustomizer { + return customizers +} + +type customizerSlice []registry.ServiceInstanceCustomizer + +func (c customizerSlice) Len() int { + return len(c) +} + +func (c customizerSlice) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c customizerSlice) Less(i, j int) bool { return c[i].GetPriority() < c[j].GetPriority() } diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 2935f49d81..0330b8a4d3 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -20,17 +20,13 @@ package extension import "github.com/apache/dubbo-go/metadata/mapping" var ( - nameMappings = make(map[string]func() mapping.ServiceNameMapping) + globalNameMapping mapping.ServiceNameMapping ) -func SetServiceNameMapping(name string, creator func() mapping.ServiceNameMapping) { - nameMappings[name] = creator +func SetGlobalServiceNameMapping(nameMapping mapping.ServiceNameMapping) { + globalNameMapping = nameMapping } -func GetServiceNameMapping(name string) mapping.ServiceNameMapping { - creator, ok := nameMappings[name] - if !ok { - panic("Can not find the target service name mapping: " + name) - } - return creator() +func GetGlobalServiceNameMapping() mapping.ServiceNameMapping { + return globalNameMapping } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index fabad3a6ff..3f8eeffaf9 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -32,6 +32,7 @@ type EventListener interface { // OnEvent handle this event OnEvent(e Event) error // GetEventType listen which event type + // return nil if the implementation want to listen any event GetEventType() reflect.Type } diff --git a/common/rpc_service_test.go b/common/rpc_service_test.go index 2311205d0e..19a1d7b03b 100644 --- a/common/rpc_service_test.go +++ b/common/rpc_service_test.go @@ -137,7 +137,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType := suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) + assert.Equal(t, "func(*event.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) at := methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -151,7 +151,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) + assert.Equal(t, "func(*event.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -164,7 +164,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService) error", method.Type.String()) + assert.Equal(t, "func(*event.TestService) error", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, 0, len(at)) assert.Nil(t, methodType.CtxType()) diff --git a/config/application_config.go b/config/application_config.go index 33b47c81dd..af6637c4e0 100644 --- a/config/application_config.go +++ b/config/application_config.go @@ -33,7 +33,8 @@ type ApplicationConfig struct { Version string `yaml:"version" json:"version,omitempty" property:"version"` Owner string `yaml:"owner" json:"owner,omitempty" property:"owner"` Environment string `yaml:"environment" json:"environment,omitempty" property:"environment"` - MetadataType string `default:"local" yaml:"metadataType" json:"metadataType,omitempty" property:"metadataType"` //field for metadata report + // the metadata type. remote or local + MetadataType string `default:"local" yaml:"metadataType" json:"metadataType,omitempty" property:"metadataType"` } // Prefix ... diff --git a/config/base_config.go b/config/base_config.go index 2f51690d30..dad4d7f7ef 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -40,7 +40,7 @@ type multiConfiger interface { Prefix() string } -// BaseConfig is the common configuration for provider and consumer +// BaseConfig is the event configuration for provider and consumer type BaseConfig struct { ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` Remotes map[string]*RemoteConfig `yaml:"remote" json:"remote,omitempty"` @@ -51,7 +51,7 @@ type BaseConfig struct { configCenterUrl *common.URL prefix string fatherConfig interface{} - eventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"` + EventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"` MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"` fileStream *bytes.Buffer } @@ -376,7 +376,6 @@ func initializeStruct(t reflect.Type, v reflect.Value) { default: } } - } } } diff --git a/config/config_loader.go b/config/config_loader.go index a4dc62ffbd..4a293e7a9f 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -218,15 +218,23 @@ func Load() { // init router initRouter() + // event part + extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) + + // start the metadata report if config set + if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { + logger.Errorf("Provider starts metadata report error, and the error is {%#v}", err) + return + } + + logger.Debugf("provider config{%#v}\n", providerConfig) + // reference config loadConsumerConfig() // service config loadProviderConfig() - // common part - extension.SetAndInitGlobalDispatcher(providerConfig.eventDispatcherType) - // init the shutdown callback GracefulShutdownInit() } diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index 66b88d5e9a..9999371ab8 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -93,7 +93,7 @@ func (c *MetadataReportConfig) IsValid() bool { // StartMetadataReport: The entry of metadata report start func startMetadataReport(metadataType string, metadataReportConfig *MetadataReportConfig) error { - if metadataReportConfig == nil || metadataReportConfig.IsValid() { + if metadataReportConfig == nil || !metadataReportConfig.IsValid() { return nil } diff --git a/config/provider_config.go b/config/provider_config.go index f0d3c4cf7f..0f14c9f1d3 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -28,7 +28,6 @@ import ( import ( "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/yaml" ) @@ -95,11 +94,6 @@ func ProviderInit(confProFile string) error { n.InterfaceId = k } } - // start the metadata report if config set - if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { - return perrors.WithMessagef(err, "Provider starts metadata report error, and the error is {%#v}", err) - } - logger.Debugf("provider config{%#v}\n", providerConfig) return nil } diff --git a/filter/rejected_execution_handler.go b/filter/rejected_execution_handler.go index d02481b98d..9855bd5354 100644 --- a/filter/rejected_execution_handler.go +++ b/filter/rejected_execution_handler.go @@ -26,7 +26,7 @@ import ( * RejectedExecutionHandler * If the invocation cannot pass any validation in filter, like ExecuteLimitFilter and TpsLimitFilter, * the implementation will be used. - * The common case is that sometimes you want to return the default value when the request was rejected. + * The event 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. */ diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 3d502b6184..56ef2a0f0d 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -18,11 +18,10 @@ package dynamic import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/metadata/mapping" "strconv" - "sync" "time" + + "github.com/apache/dubbo-go/common/extension" ) import ( @@ -43,7 +42,8 @@ const ( ) func init() { - extension.SetServiceNameMapping("dynamic", GetServiceNameMappingInstance) + dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() + extension.SetGlobalServiceNameMapping(&DynamicConfigurationServiceNameMapping{dc: dc}) } // DynamicConfigurationServiceNameMapping is the implementation based on config center @@ -82,17 +82,3 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str // so other params are ignored and remove, including group string, version string, protocol string return defaultGroup + slash + serviceInterface } - -var ( - serviceNameMappingInstance *DynamicConfigurationServiceNameMapping - serviceNameMappingInitOnce sync.Once -) - -// GetServiceNameMappingInstance will return an instance of DynamicConfigurationServiceNameMapping -func GetServiceNameMappingInstance() mapping.ServiceNameMapping { - serviceNameMappingInitOnce.Do(func() { - dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() - serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc} - }) - return serviceNameMappingInstance -} diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go index 747753a140..293d97c842 100644 --- a/metadata/mapping/memory/service_name_mapping.go +++ b/metadata/mapping/memory/service_name_mapping.go @@ -17,11 +17,6 @@ package memory -import ( - "github.com/apache/dubbo-go/metadata/mapping" - "sync" -) - import ( gxset "github.com/dubbogo/gost/container/set" ) @@ -32,7 +27,7 @@ import ( ) func init() { - extension.SetServiceNameMapping("in-memory", GetInMemoryServiceNameMappingInstance) + extension.SetGlobalServiceNameMapping(&InMemoryServiceNameMapping{}) } type InMemoryServiceNameMapping struct{} @@ -44,15 +39,3 @@ func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, v func (i InMemoryServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { return gxset.NewSet(config.GetApplicationConfig().Name), nil } - -var ( - nameMappingInstance *InMemoryServiceNameMapping - nameMappingInitOnce sync.Once -) - -func GetInMemoryServiceNameMappingInstance() mapping.ServiceNameMapping { - nameMappingInitOnce.Do(func() { - nameMappingInstance = &InMemoryServiceNameMapping{} - }) - return nameMappingInstance -} diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 4b6f4330a1..31492a3224 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -175,12 +175,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { if len(interfaceName) > 0 && !isGeneric { //judge is consumer or provider //side := url.GetParam(constant.SIDE_KEY, "") - //var service common.RPCService + //var service event.RPCService service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - //if side == common.RoleType(common.CONSUMER).Role() { + //if side == event.RoleType(event.CONSUMER).Role() { // //TODO:generate the service definition and store it // - //} else if side == common.RoleType(common.PROVIDER).Role() { + //} else if side == event.RoleType(event.PROVIDER).Role() { // //TODO:generate the service definition and store it //} sd := definition.BuildServiceDefinition(*service, url) diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index cd8a2dc837..b616e2a4d4 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -18,6 +18,8 @@ package remote import ( + "sync" + "github.com/Workiva/go-datastructures/slice/skip" "go.uber.org/atomic" ) @@ -38,6 +40,7 @@ import ( const version = "1.0.0" // MetadataService is a implement of metadata service which will delegate the remote metadata report +// This is singleton type MetadataService struct { service.BaseMetadataService inMemoryMetadataService *inmemory.MetadataService @@ -46,16 +49,26 @@ type MetadataService struct { delegateReport *delegate.MetadataReport } +var ( + metadataServiceOnce sync.Once + metadataServiceInstance *MetadataService +) + // NewMetadataService will create a new remote MetadataService instance func NewMetadataService() (*MetadataService, error) { - mr, err := delegate.NewMetadataReport() - if err != nil { - return nil, err - } - return &MetadataService{ - inMemoryMetadataService: inmemory.NewMetadataService(), - delegateReport: mr, - }, nil + var err error + metadataServiceOnce.Do(func() { + var mr *delegate.MetadataReport + mr, err = delegate.NewMetadataReport() + if err != nil { + return + } + metadataServiceInstance = &MetadataService{ + inMemoryMetadataService: inmemory.NewMetadataService(), + delegateReport: mr, + } + }) + return metadataServiceInstance, err } // setInMemoryMetadataService will replace the in memory metadata service by the specific param @@ -90,39 +103,41 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { - service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - sd := definition.BuildServiceDefinition(*service, url) + sv := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + sd := definition.BuildServiceDefinition(*sv, url) id := &identifier.MetadataIdentifier{ BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ ServiceInterface: interfaceName, Version: url.GetParam(constant.VERSION_KEY, ""), - Group: url.GetParam(constant.GROUP_KEY, ""), + // Group: url.GetParam(constant.GROUP_KEY, constant.SERVICE_DISCOVERY_DEFAULT_GROUP), + Group: url.GetParam(constant.GROUP_KEY, "test"), }, } mts.delegateReport.StoreProviderMetadata(id, sd) + return nil } logger.Errorf("publishProvider interfaceName is empty . providerUrl:%v ", url) return nil } // GetExportedURLs will be implemented by in memory service -func (MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { - return nil, nil +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { + return mts.inMemoryMetadataService.GetExportedURLs(serviceInterface, group, version, protocol) } // GetSubscribedURLs will be implemented by in memory service -func (MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { - return nil, nil +func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { + return mts.inMemoryMetadataService.GetSubscribedURLs() } // GetServiceDefinition will be implemented by in memory service -func (MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { - return "", nil +func (mts *MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + return mts.inMemoryMetadataService.GetServiceDefinition(interfaceName, group, version) } // GetServiceDefinitionByServiceKey will be implemented by in memory service -func (MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { - return "", nil +func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + return mts.inMemoryMetadataService.GetServiceDefinitionByServiceKey(serviceKey) } // RefreshMetadata will refresh the exported & subscribed metadata to remote metadata report from the inmemory metadata service diff --git a/metadata/service/service.go b/metadata/service/service.go index 13464087ed..2f8a98d185 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -27,7 +27,8 @@ import ( "github.com/apache/dubbo-go/config" ) -// Metadataservice is used to define meta data related behaviors +// MetadataService is used to define meta data related behaviors +// usually the implementation should be singleton type MetadataService interface { common.RPCService // ServiceName will get the service's name in meta service , which is application name @@ -56,7 +57,7 @@ type MetadataService interface { Version() string } -// BaseMetadataService is used for the common logic for struct who will implement interface MetadataService +// BaseMetadataService is used for the event logic for struct who will implement interface MetadataService type BaseMetadataService struct { } diff --git a/registry/base_registry.go b/registry/base_registry.go index ad1a3b6174..504e087091 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -92,7 +92,7 @@ type FacadeBasedRegistry interface { InitListeners() } -// BaseRegistry is a common logic abstract for registry. It implement Registry interface. +// BaseRegistry is a event logic abstract for registry. It implement Registry interface. type BaseRegistry struct { context context.Context facadeBasedRegistry FacadeBasedRegistry diff --git a/registry/directory/directory_test.go b/registry/directory/directory_test.go index 04fae049d4..f2b2f8edd2 100644 --- a/registry/directory/directory_test.go +++ b/registry/directory/directory_test.go @@ -64,7 +64,7 @@ func TestSubscribe(t *testing.T) { // registryDirectory, mockRegistry := normalRegistryDir() // time.Sleep(1e9) // assert.Len(t, registryDirectory.cacheInvokers, 3) -// mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *common.NewURLWithOptions(common.WithPath("TEST0"), common.WithProtocol("dubbo"))}) +// mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *event.NewURLWithOptions(event.WithPath("TEST0"), event.WithProtocol("dubbo"))}) // time.Sleep(1e9) // assert.Len(t, registryDirectory.cacheInvokers, 2) //} diff --git a/registry/event/customizable_service_instance_listener.go b/registry/event/customizable_service_instance_listener.go new file mode 100644 index 0000000000..cd4a8d2db6 --- /dev/null +++ b/registry/event/customizable_service_instance_listener.go @@ -0,0 +1,55 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" +) + +func init() { + extension.AddEventListener(&customizableServiceInstanceListener{}) +} + +type customizableServiceInstanceListener struct { +} + +// GetPriority return priority 9999, +// 9999 is big enough to make sure it will be last invoked +func (c *customizableServiceInstanceListener) GetPriority() int { + return 9999 +} + +// OnEvent if the event is ServiceInstancePreRegisteredEvent +// it will iterate all ServiceInstanceCustomizer instances +// or it will do nothing +func (c *customizableServiceInstanceListener) OnEvent(e observer.Event) error { + if preRegEvent, ok := e.(*ServiceInstancePreRegisteredEvent); ok { + for _, cus := range extension.GetCustomizers() { + cus.Customize(preRegEvent.serviceInstance) + } + } + return nil +} + +// GetEventType will return ServiceInstancePreRegisteredEvent +func (c *customizableServiceInstanceListener) GetEventType() reflect.Type { + return reflect.TypeOf(&ServiceInstancePreRegisteredEvent{}) +} diff --git a/registry/common/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go similarity index 99% rename from registry/common/event_publishing_service_deiscovery_test.go rename to registry/event/event_publishing_service_deiscovery_test.go index 1e08335e04..27d2482d06 100644 --- a/registry/common/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "reflect" diff --git a/registry/common/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go similarity index 99% rename from registry/common/event_publishing_service_discovery.go rename to registry/event/event_publishing_service_discovery.go index f61dd84690..76fdf7237a 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( gxset "github.com/dubbogo/gost/container/set" diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go new file mode 100644 index 0000000000..282b18de79 --- /dev/null +++ b/registry/event/log_event_listener.go @@ -0,0 +1,48 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/common/observer" +) + +func init() { + extension.AddEventListener(&logEventListener{}) +} + +type logEventListener struct { + +} + +func (l *logEventListener) GetPriority() int { + return 0 +} + +func (l *logEventListener) OnEvent(e observer.Event) error { + logger.Info("Event happen: " + e.String()) + return nil +} + +func (l *logEventListener) GetEventType() reflect.Type { + return nil +} + diff --git a/registry/event/log_event_listener_test.go b/registry/event/log_event_listener_test.go new file mode 100644 index 0000000000..e7c0ba0df5 --- /dev/null +++ b/registry/event/log_event_listener_test.go @@ -0,0 +1,31 @@ +/* + * 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 event + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLogEventListener(t *testing.T) { + l := &logEventListener{} + assert.Equal(t, 0, l.GetPriority()) + assert.Nil(t, l.GetEventType()) + assert.Nil(t, l.OnEvent(&ServiceDiscoveryDestroyedEvent{})) +} diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go new file mode 100644 index 0000000000..5ae0ea91f6 --- /dev/null +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -0,0 +1,52 @@ +/* + * 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 event + +import ( + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +// ProtocolPortsMetadataCustomizer will update +type ProtocolPortsMetadataCustomizer struct { +} + +// GetPriority will return 0, which means it will be invoked at the beginning +func (p *ProtocolPortsMetadataCustomizer) GetPriority() int { + return 0 +} + +// Customize will +func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceInstance) { + metadataService, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("Could not init the MetadataService", err) + return + } + + // 4 is enough... + protocolMap := make(map[string]int, 4) + + list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE,constant.ANY_VALUE) + if err != nil { + logger.Errorf("Could", err) + return + } +} diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go new file mode 100644 index 0000000000..3d3b0c8f0e --- /dev/null +++ b/registry/event/service_config_exported_event.go @@ -0,0 +1,26 @@ +/* + * 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 event + +import ( + "github.com/apache/dubbo-go/common/observer" +) + +type ServiceConfigExportedEvent struct { + observer.BaseEvent +} diff --git a/registry/common/service_discovery_event.go b/registry/event/service_discovery_event.go similarity index 99% rename from registry/common/service_discovery_event.go rename to registry/event/service_discovery_event.go index a60ca56a39..74f6c5f19d 100644 --- a/registry/common/service_discovery_event.go +++ b/registry/event/service_discovery_event.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "github.com/apache/dubbo-go/common/observer" diff --git a/registry/common/service_instance_event.go b/registry/event/service_instance_event.go similarity index 99% rename from registry/common/service_instance_event.go rename to registry/event/service_instance_event.go index f70e7ee0ff..650b2e8e29 100644 --- a/registry/common/service_instance_event.go +++ b/registry/event/service_instance_event.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "github.com/apache/dubbo-go/common/observer" diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go new file mode 100644 index 0000000000..71abca6f87 --- /dev/null +++ b/registry/event/service_name_mapping_listener.go @@ -0,0 +1,48 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/metadata/mapping" +) + +func init() { + extension.AddEventListener(&serviceNameMappingListener{ + nameMapping: extension.GetGlobalServiceNameMapping(), + }) +} +type serviceNameMappingListener struct { + nameMapping mapping.ServiceNameMapping +} + +func (s *serviceNameMappingListener) GetPriority() int { + panic("implement me") +} + +func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { + // TODO + panic("implement me") +} + +func (s *serviceNameMappingListener) GetEventType() reflect.Type { + return reflect.TypeOf(&ServiceConfigExportedEvent{}) +} diff --git a/registry/event_listener.go b/registry/event_listener.go index 1cd5ad43a6..8a2bc88956 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -53,4 +53,4 @@ func (lstn *ServiceInstancesChangedListener) GetPriority() int { // get event type func (lstn *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) -} +} \ No newline at end of file diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index e9230195f6..6b1d3c23d1 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -40,7 +40,7 @@ import ( ) const ( - defaultGroup = "DEFAULT_GROUP" + defaultGroup = constant.SERVICE_DISCOVERY_DEFAULT_GROUP idKey = "id" ) diff --git a/registry/registry.go b/registry/registry.go index 74e63aa66e..ce214c4971 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -44,7 +44,7 @@ type Registry interface { //Will remove in dubbogo version v1.1.0 //mode1 : return Listener with Next function which can return subscribe service event from registry //Deprecated! - //subscribe(common.URL) (Listener, error) + //subscribe(event.URL) (Listener, error) //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). diff --git a/registry/service_instance.go b/registry/service_instance.go index 2cc229ee3b..f9fee9f452 100644 --- a/registry/service_instance.go +++ b/registry/service_instance.go @@ -17,6 +17,10 @@ package registry +import ( + gxsort "github.com/dubbogo/gost/sort" +) + type ServiceInstance interface { // GetId will return this instance's id. It should be unique. @@ -87,3 +91,9 @@ func (d *DefaultServiceInstance) IsHealthy() bool { func (d *DefaultServiceInstance) GetMetadata() map[string]string { return d.Metadata } + +type ServiceInstanceCustomizer interface { + gxsort.Prioritizer + + Customize(instance ServiceInstance) +} diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 949010431f..9525a7d419 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -26,6 +26,7 @@ import ( cm "github.com/Workiva/go-datastructures/common" gxset "github.com/dubbogo/gost/container/set" + gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" "github.com/apache/dubbo-go/common" @@ -38,7 +39,7 @@ import ( "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" - registryCommon "github.com/apache/dubbo-go/registry/common" + registryCommon "github.com/apache/dubbo-go/registry/event" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" @@ -77,7 +78,7 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { } subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() - serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) + serviceNameMapping := extension.GetGlobalServiceNameMapping() metaDataService, err := remote.NewMetadataService() if err != nil { return nil, perrors.WithMessage(err, "could not init metadata service") @@ -160,17 +161,52 @@ func (s *serviceDiscoveryRegistry) Register(url common.URL) error { return nil } ok, err := s.metaDataService.ExportURL(url) - s.metaDataService.PublishServiceDefinition(url) + if err != nil { logger.Errorf("The URL[%s] registry catch error:%s!", url.String(), err.Error()) return err } - if ok { - logger.Infof("The URL[%s] registry successfully!", url.String()) - } else { + if !ok { logger.Warnf("The URL[%s] has been registry!", url.String()) } - return nil + + // we try to register this instance. Dubbo do this in org.apache.dubbo.config.bootstrap.DubboBootstrap + // But we don't want to design a similar bootstrap class. + ins, err := createInstance(url) + if err != nil { + return perrors.WithMessage(err, "could not create servcie instance, please check your service url") + } + return s.serviceDiscovery.Register(ins) +} + +func createInstance(url common.URL) (registry.ServiceInstance, error) { + appConfig := config.GetApplicationConfig() + port, err := strconv.ParseInt(url.Port, 10, 32) + if err != nil { + return nil, perrors.WithMessage(err, "invalid port: "+url.Port) + } + + host := url.Ip + if len(host) == 0 { + host, err = gxnet.GetLocalIP() + if err != nil { + return nil, perrors.WithMessage(err, "could not get the local Ip") + } + } + + // usually we will add more metadata + metadata := make(map[string]string, 8) + metadata[constant.METADATA_STORAGE_TYPE_PROPERTY_NAME] = appConfig.MetadataType + + return ®istry.DefaultServiceInstance{ + ServiceName: appConfig.Name, + Host: host, + Port: int(port), + Id: host + constant.KEY_SEPARATOR + url.Port, + Enable: true, + Healthy: true, + Metadata: metadata, + }, nil } func shouldRegister(url common.URL) bool { diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index 90a8c0e257..4aa52f55ca 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -28,10 +28,10 @@ var ( ) func TestServiceDiscoveryRegistry_Register(t *testing.T) { - //registryURL,_:=common.NewURL("in-memory://localhost:12345", - // common.WithParamsValue("registry-type","service"), - // common.WithParamsValue("subscribed-services","a, b , c,d,e ,")) - //url,_:=common.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + + //registryURL,_:=event.NewURL("in-memory://localhost:12345", + // event.WithParamsValue("registry-type","service"), + // event.WithParamsValue("subscribed-services","a, b , c,d,e ,")) + //url,_:=event.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + // "?&application=" + GROUP + // "&interface=" + SERVICE_INTERFACE + // "&group=" + GROUP + diff --git a/test/integrate/dubbo/go-client/client.go b/test/integrate/dubbo/go-client/client.go index 4c62674d33..c075ec22c3 100644 --- a/test/integrate/dubbo/go-client/client.go +++ b/test/integrate/dubbo/go-client/client.go @@ -25,7 +25,7 @@ import ( import ( hessian "github.com/apache/dubbo-go-hessian2" - _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + _ "github.com/apache/dubbo-go/event/proxy/proxy_factory" "github.com/apache/dubbo-go/config" _ "github.com/apache/dubbo-go/protocol/dubbo" _ "github.com/apache/dubbo-go/registry/protocol" diff --git a/test/integrate/dubbo/go-server/server.go b/test/integrate/dubbo/go-server/server.go index 115bf0a4d7..4cc6c49083 100644 --- a/test/integrate/dubbo/go-server/server.go +++ b/test/integrate/dubbo/go-server/server.go @@ -25,7 +25,7 @@ import ( hessian "github.com/apache/dubbo-go-hessian2" _ "github.com/apache/dubbo-go/cluster/cluster_impl" _ "github.com/apache/dubbo-go/cluster/loadbalance" - _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + _ "github.com/apache/dubbo-go/event/proxy/proxy_factory" "github.com/apache/dubbo-go/config" _ "github.com/apache/dubbo-go/filter/filter_impl" _ "github.com/apache/dubbo-go/protocol/dubbo" From 9ae184fe7b0bf2531088b6a4cbe02f05ed50d074 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 2 Jun 2020 21:43:33 +0800 Subject: [PATCH 096/209] extract method for get zookeeper connection --- remoting/zookeeper/client.go | 45 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index c66bf4b673..a165d8a77c 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -416,15 +416,15 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { ) logger.Debugf("zookeeperClient.Create(basePath{%s})", basePath) + conn := z.getConn() + err = errNilZkClientConn + if conn == nil { + return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath) + } + for _, str := range strings.Split(basePath, "/")[1:] { tmpPath = path.Join(tmpPath, "/", str) - err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() - if conn != nil { - _, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll)) - } + _, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll)) if err != nil { if err == zk.ErrNodeExists { @@ -446,9 +446,7 @@ func (z *ZookeeperClient) Delete(basePath string) error { ) err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { err = conn.Delete(basePath, -1) } @@ -468,9 +466,7 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er err = errNilZkClientConn data = []byte("") zkPath = path.Join(basePath) + "/" + node - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } @@ -493,9 +489,7 @@ func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, ) err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { tmpPath, err = conn.Create( path.Join(basePath)+"/", @@ -526,9 +520,7 @@ func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, ) err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { children, stat, watcher, err = conn.ChildrenW(path) } @@ -562,9 +554,7 @@ func (z *ZookeeperClient) GetChildren(path string) ([]string, error) { ) err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { children, stat, err = conn.Children(path) } @@ -595,9 +585,7 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { ) err = errNilZkClientConn - z.RLock() - conn := z.Conn - z.RUnlock() + conn := z.getConn() if conn != nil { exist, _, watcher, err = conn.ExistsW(zkPath) } @@ -618,3 +606,10 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { func (z *ZookeeperClient) GetContent(zkPath string) ([]byte, *zk.Stat, error) { return z.Conn.Get(zkPath) } + +// getConn gets zookeeper connection safely +func (z *ZookeeperClient) getConn() *zk.Conn { + z.RLock() + defer z.RUnlock() + return z.Conn +} From ed6b59bbc74e121736d287599d99449388b791bc Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 2 Jun 2020 11:36:07 +0800 Subject: [PATCH 097/209] Add events and eventListener --- common/constant/default.go | 4 ++ common/constant/key.go | 3 - .../extension/service_instance_customizer.go | 49 +++++++++++++++++ common/extension/service_name_mapping.go | 14 ++--- common/observer/event_listener.go | 1 + common/rpc_service_test.go | 6 +- config/application_config.go | 3 +- config/base_config.go | 5 +- config/config_loader.go | 14 ++++- config/metadata_report_config.go | 2 +- config/provider_config.go | 6 -- filter/rejected_execution_handler.go | 2 +- .../mapping/dynamic/service_name_mapping.go | 22 ++------ .../mapping/memory/service_name_mapping.go | 19 +------ metadata/service/inmemory/service.go | 6 +- metadata/service/remote/service.go | 53 +++++++++++------- metadata/service/service.go | 5 +- registry/base_registry.go | 2 +- registry/directory/directory_test.go | 2 +- .../customizable_service_instance_listener.go | 55 +++++++++++++++++++ ...vent_publishing_service_deiscovery_test.go | 2 +- .../event_publishing_service_discovery.go | 2 +- registry/event/log_event_listener.go | 48 ++++++++++++++++ registry/event/log_event_listener_test.go | 31 +++++++++++ .../protocol_ports_metadata_customizer.go | 52 ++++++++++++++++++ .../event/service_config_exported_event.go | 26 +++++++++ .../service_discovery_event.go | 2 +- .../service_instance_event.go | 2 +- .../event/service_name_mapping_listener.go | 48 ++++++++++++++++ registry/event_listener.go | 2 +- registry/nacos/service_discovery.go | 2 +- registry/registry.go | 2 +- registry/service_instance.go | 10 ++++ .../service_discovery_registry.go | 50 ++++++++++++++--- .../service_discovery_registry_test.go | 8 +-- test/integrate/dubbo/go-client/client.go | 2 +- test/integrate/dubbo/go-server/server.go | 2 +- 37 files changed, 452 insertions(+), 112 deletions(-) create mode 100644 common/extension/service_instance_customizer.go create mode 100644 registry/event/customizable_service_instance_listener.go rename registry/{common => event}/event_publishing_service_deiscovery_test.go (99%) rename registry/{common => event}/event_publishing_service_discovery.go (99%) create mode 100644 registry/event/log_event_listener.go create mode 100644 registry/event/log_event_listener_test.go create mode 100644 registry/event/protocol_ports_metadata_customizer.go create mode 100644 registry/event/service_config_exported_event.go rename registry/{common => event}/service_discovery_event.go (99%) rename registry/{common => event}/service_instance_event.go (99%) create mode 100644 registry/event/service_name_mapping_listener.go diff --git a/common/constant/default.go b/common/constant/default.go index 6b9d914c87..8442609c59 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -78,3 +78,7 @@ const ( const ( SIMPLE_METADATA_SERVICE_NAME = "MetadataService" ) + +const ( + SERVICE_DISCOVERY_DEFAULT_GROUP = "DEFAULT_GROUP" +) \ No newline at end of file diff --git a/common/constant/key.go b/common/constant/key.go index 15496628eb..394f2d8c04 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -273,9 +273,6 @@ const ( METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" - // used by URL - // SERVICE_NAME_MAPPING_KEY indicate that which service name mapping instance will be used - SERVICE_NAME_MAPPING_KEY = "name_mapping" // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" ) diff --git a/common/extension/service_instance_customizer.go b/common/extension/service_instance_customizer.go new file mode 100644 index 0000000000..40f8ca0c5d --- /dev/null +++ b/common/extension/service_instance_customizer.go @@ -0,0 +1,49 @@ +/* + * 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 ( + "sort" + + "github.com/apache/dubbo-go/registry" +) + +var ( + customizers = make([]registry.ServiceInstanceCustomizer, 0, 8) +) + +// AddCustomizers will put the customizer into slices and then sort them; +// this method will be invoked several time, so we sort them here. +func AddCustomizers(cus registry.ServiceInstanceCustomizer) { + customizers = append(customizers, cus) + sort.Stable(customizerSlice(customizers)) +} + +// GetCustomizers will return the sorted customizer +func GetCustomizers() []registry.ServiceInstanceCustomizer { + return customizers +} + +type customizerSlice []registry.ServiceInstanceCustomizer + +func (c customizerSlice) Len() int { + return len(c) +} + +func (c customizerSlice) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c customizerSlice) Less(i, j int) bool { return c[i].GetPriority() < c[j].GetPriority() } diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 2935f49d81..0330b8a4d3 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -20,17 +20,13 @@ package extension import "github.com/apache/dubbo-go/metadata/mapping" var ( - nameMappings = make(map[string]func() mapping.ServiceNameMapping) + globalNameMapping mapping.ServiceNameMapping ) -func SetServiceNameMapping(name string, creator func() mapping.ServiceNameMapping) { - nameMappings[name] = creator +func SetGlobalServiceNameMapping(nameMapping mapping.ServiceNameMapping) { + globalNameMapping = nameMapping } -func GetServiceNameMapping(name string) mapping.ServiceNameMapping { - creator, ok := nameMappings[name] - if !ok { - panic("Can not find the target service name mapping: " + name) - } - return creator() +func GetGlobalServiceNameMapping() mapping.ServiceNameMapping { + return globalNameMapping } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index fabad3a6ff..3f8eeffaf9 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -32,6 +32,7 @@ type EventListener interface { // OnEvent handle this event OnEvent(e Event) error // GetEventType listen which event type + // return nil if the implementation want to listen any event GetEventType() reflect.Type } diff --git a/common/rpc_service_test.go b/common/rpc_service_test.go index 2311205d0e..19a1d7b03b 100644 --- a/common/rpc_service_test.go +++ b/common/rpc_service_test.go @@ -137,7 +137,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType := suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) + assert.Equal(t, "func(*event.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) at := methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -151,7 +151,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) + assert.Equal(t, "func(*event.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -164,7 +164,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*common.TestService) error", method.Type.String()) + assert.Equal(t, "func(*event.TestService) error", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, 0, len(at)) assert.Nil(t, methodType.CtxType()) diff --git a/config/application_config.go b/config/application_config.go index 33b47c81dd..af6637c4e0 100644 --- a/config/application_config.go +++ b/config/application_config.go @@ -33,7 +33,8 @@ type ApplicationConfig struct { Version string `yaml:"version" json:"version,omitempty" property:"version"` Owner string `yaml:"owner" json:"owner,omitempty" property:"owner"` Environment string `yaml:"environment" json:"environment,omitempty" property:"environment"` - MetadataType string `default:"local" yaml:"metadataType" json:"metadataType,omitempty" property:"metadataType"` //field for metadata report + // the metadata type. remote or local + MetadataType string `default:"local" yaml:"metadataType" json:"metadataType,omitempty" property:"metadataType"` } // Prefix ... diff --git a/config/base_config.go b/config/base_config.go index 2f51690d30..dad4d7f7ef 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -40,7 +40,7 @@ type multiConfiger interface { Prefix() string } -// BaseConfig is the common configuration for provider and consumer +// BaseConfig is the event configuration for provider and consumer type BaseConfig struct { ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` Remotes map[string]*RemoteConfig `yaml:"remote" json:"remote,omitempty"` @@ -51,7 +51,7 @@ type BaseConfig struct { configCenterUrl *common.URL prefix string fatherConfig interface{} - eventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"` + EventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"` MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"` fileStream *bytes.Buffer } @@ -376,7 +376,6 @@ func initializeStruct(t reflect.Type, v reflect.Value) { default: } } - } } } diff --git a/config/config_loader.go b/config/config_loader.go index a4dc62ffbd..4a293e7a9f 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -218,15 +218,23 @@ func Load() { // init router initRouter() + // event part + extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) + + // start the metadata report if config set + if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { + logger.Errorf("Provider starts metadata report error, and the error is {%#v}", err) + return + } + + logger.Debugf("provider config{%#v}\n", providerConfig) + // reference config loadConsumerConfig() // service config loadProviderConfig() - // common part - extension.SetAndInitGlobalDispatcher(providerConfig.eventDispatcherType) - // init the shutdown callback GracefulShutdownInit() } diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index 66b88d5e9a..9999371ab8 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -93,7 +93,7 @@ func (c *MetadataReportConfig) IsValid() bool { // StartMetadataReport: The entry of metadata report start func startMetadataReport(metadataType string, metadataReportConfig *MetadataReportConfig) error { - if metadataReportConfig == nil || metadataReportConfig.IsValid() { + if metadataReportConfig == nil || !metadataReportConfig.IsValid() { return nil } diff --git a/config/provider_config.go b/config/provider_config.go index f0d3c4cf7f..0f14c9f1d3 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -28,7 +28,6 @@ import ( import ( "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/yaml" ) @@ -95,11 +94,6 @@ func ProviderInit(confProFile string) error { n.InterfaceId = k } } - // start the metadata report if config set - if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { - return perrors.WithMessagef(err, "Provider starts metadata report error, and the error is {%#v}", err) - } - logger.Debugf("provider config{%#v}\n", providerConfig) return nil } diff --git a/filter/rejected_execution_handler.go b/filter/rejected_execution_handler.go index d02481b98d..9855bd5354 100644 --- a/filter/rejected_execution_handler.go +++ b/filter/rejected_execution_handler.go @@ -26,7 +26,7 @@ import ( * RejectedExecutionHandler * If the invocation cannot pass any validation in filter, like ExecuteLimitFilter and TpsLimitFilter, * the implementation will be used. - * The common case is that sometimes you want to return the default value when the request was rejected. + * The event 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. */ diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 3d502b6184..56ef2a0f0d 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -18,11 +18,10 @@ package dynamic import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/metadata/mapping" "strconv" - "sync" "time" + + "github.com/apache/dubbo-go/common/extension" ) import ( @@ -43,7 +42,8 @@ const ( ) func init() { - extension.SetServiceNameMapping("dynamic", GetServiceNameMappingInstance) + dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() + extension.SetGlobalServiceNameMapping(&DynamicConfigurationServiceNameMapping{dc: dc}) } // DynamicConfigurationServiceNameMapping is the implementation based on config center @@ -82,17 +82,3 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str // so other params are ignored and remove, including group string, version string, protocol string return defaultGroup + slash + serviceInterface } - -var ( - serviceNameMappingInstance *DynamicConfigurationServiceNameMapping - serviceNameMappingInitOnce sync.Once -) - -// GetServiceNameMappingInstance will return an instance of DynamicConfigurationServiceNameMapping -func GetServiceNameMappingInstance() mapping.ServiceNameMapping { - serviceNameMappingInitOnce.Do(func() { - dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() - serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc} - }) - return serviceNameMappingInstance -} diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go index 747753a140..293d97c842 100644 --- a/metadata/mapping/memory/service_name_mapping.go +++ b/metadata/mapping/memory/service_name_mapping.go @@ -17,11 +17,6 @@ package memory -import ( - "github.com/apache/dubbo-go/metadata/mapping" - "sync" -) - import ( gxset "github.com/dubbogo/gost/container/set" ) @@ -32,7 +27,7 @@ import ( ) func init() { - extension.SetServiceNameMapping("in-memory", GetInMemoryServiceNameMappingInstance) + extension.SetGlobalServiceNameMapping(&InMemoryServiceNameMapping{}) } type InMemoryServiceNameMapping struct{} @@ -44,15 +39,3 @@ func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, v func (i InMemoryServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { return gxset.NewSet(config.GetApplicationConfig().Name), nil } - -var ( - nameMappingInstance *InMemoryServiceNameMapping - nameMappingInitOnce sync.Once -) - -func GetInMemoryServiceNameMappingInstance() mapping.ServiceNameMapping { - nameMappingInitOnce.Do(func() { - nameMappingInstance = &InMemoryServiceNameMapping{} - }) - return nameMappingInstance -} diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 4b6f4330a1..31492a3224 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -175,12 +175,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { if len(interfaceName) > 0 && !isGeneric { //judge is consumer or provider //side := url.GetParam(constant.SIDE_KEY, "") - //var service common.RPCService + //var service event.RPCService service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - //if side == common.RoleType(common.CONSUMER).Role() { + //if side == event.RoleType(event.CONSUMER).Role() { // //TODO:generate the service definition and store it // - //} else if side == common.RoleType(common.PROVIDER).Role() { + //} else if side == event.RoleType(event.PROVIDER).Role() { // //TODO:generate the service definition and store it //} sd := definition.BuildServiceDefinition(*service, url) diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index cd8a2dc837..b616e2a4d4 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -18,6 +18,8 @@ package remote import ( + "sync" + "github.com/Workiva/go-datastructures/slice/skip" "go.uber.org/atomic" ) @@ -38,6 +40,7 @@ import ( const version = "1.0.0" // MetadataService is a implement of metadata service which will delegate the remote metadata report +// This is singleton type MetadataService struct { service.BaseMetadataService inMemoryMetadataService *inmemory.MetadataService @@ -46,16 +49,26 @@ type MetadataService struct { delegateReport *delegate.MetadataReport } +var ( + metadataServiceOnce sync.Once + metadataServiceInstance *MetadataService +) + // NewMetadataService will create a new remote MetadataService instance func NewMetadataService() (*MetadataService, error) { - mr, err := delegate.NewMetadataReport() - if err != nil { - return nil, err - } - return &MetadataService{ - inMemoryMetadataService: inmemory.NewMetadataService(), - delegateReport: mr, - }, nil + var err error + metadataServiceOnce.Do(func() { + var mr *delegate.MetadataReport + mr, err = delegate.NewMetadataReport() + if err != nil { + return + } + metadataServiceInstance = &MetadataService{ + inMemoryMetadataService: inmemory.NewMetadataService(), + delegateReport: mr, + } + }) + return metadataServiceInstance, err } // setInMemoryMetadataService will replace the in memory metadata service by the specific param @@ -90,39 +103,41 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { - service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - sd := definition.BuildServiceDefinition(*service, url) + sv := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) + sd := definition.BuildServiceDefinition(*sv, url) id := &identifier.MetadataIdentifier{ BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ ServiceInterface: interfaceName, Version: url.GetParam(constant.VERSION_KEY, ""), - Group: url.GetParam(constant.GROUP_KEY, ""), + // Group: url.GetParam(constant.GROUP_KEY, constant.SERVICE_DISCOVERY_DEFAULT_GROUP), + Group: url.GetParam(constant.GROUP_KEY, "test"), }, } mts.delegateReport.StoreProviderMetadata(id, sd) + return nil } logger.Errorf("publishProvider interfaceName is empty . providerUrl:%v ", url) return nil } // GetExportedURLs will be implemented by in memory service -func (MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { - return nil, nil +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { + return mts.inMemoryMetadataService.GetExportedURLs(serviceInterface, group, version, protocol) } // GetSubscribedURLs will be implemented by in memory service -func (MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { - return nil, nil +func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { + return mts.inMemoryMetadataService.GetSubscribedURLs() } // GetServiceDefinition will be implemented by in memory service -func (MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { - return "", nil +func (mts *MetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + return mts.inMemoryMetadataService.GetServiceDefinition(interfaceName, group, version) } // GetServiceDefinitionByServiceKey will be implemented by in memory service -func (MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { - return "", nil +func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + return mts.inMemoryMetadataService.GetServiceDefinitionByServiceKey(serviceKey) } // RefreshMetadata will refresh the exported & subscribed metadata to remote metadata report from the inmemory metadata service diff --git a/metadata/service/service.go b/metadata/service/service.go index 13464087ed..2f8a98d185 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -27,7 +27,8 @@ import ( "github.com/apache/dubbo-go/config" ) -// Metadataservice is used to define meta data related behaviors +// MetadataService is used to define meta data related behaviors +// usually the implementation should be singleton type MetadataService interface { common.RPCService // ServiceName will get the service's name in meta service , which is application name @@ -56,7 +57,7 @@ type MetadataService interface { Version() string } -// BaseMetadataService is used for the common logic for struct who will implement interface MetadataService +// BaseMetadataService is used for the event logic for struct who will implement interface MetadataService type BaseMetadataService struct { } diff --git a/registry/base_registry.go b/registry/base_registry.go index ad1a3b6174..504e087091 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -92,7 +92,7 @@ type FacadeBasedRegistry interface { InitListeners() } -// BaseRegistry is a common logic abstract for registry. It implement Registry interface. +// BaseRegistry is a event logic abstract for registry. It implement Registry interface. type BaseRegistry struct { context context.Context facadeBasedRegistry FacadeBasedRegistry diff --git a/registry/directory/directory_test.go b/registry/directory/directory_test.go index 04fae049d4..f2b2f8edd2 100644 --- a/registry/directory/directory_test.go +++ b/registry/directory/directory_test.go @@ -64,7 +64,7 @@ func TestSubscribe(t *testing.T) { // registryDirectory, mockRegistry := normalRegistryDir() // time.Sleep(1e9) // assert.Len(t, registryDirectory.cacheInvokers, 3) -// mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *common.NewURLWithOptions(common.WithPath("TEST0"), common.WithProtocol("dubbo"))}) +// mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *event.NewURLWithOptions(event.WithPath("TEST0"), event.WithProtocol("dubbo"))}) // time.Sleep(1e9) // assert.Len(t, registryDirectory.cacheInvokers, 2) //} diff --git a/registry/event/customizable_service_instance_listener.go b/registry/event/customizable_service_instance_listener.go new file mode 100644 index 0000000000..cd4a8d2db6 --- /dev/null +++ b/registry/event/customizable_service_instance_listener.go @@ -0,0 +1,55 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" +) + +func init() { + extension.AddEventListener(&customizableServiceInstanceListener{}) +} + +type customizableServiceInstanceListener struct { +} + +// GetPriority return priority 9999, +// 9999 is big enough to make sure it will be last invoked +func (c *customizableServiceInstanceListener) GetPriority() int { + return 9999 +} + +// OnEvent if the event is ServiceInstancePreRegisteredEvent +// it will iterate all ServiceInstanceCustomizer instances +// or it will do nothing +func (c *customizableServiceInstanceListener) OnEvent(e observer.Event) error { + if preRegEvent, ok := e.(*ServiceInstancePreRegisteredEvent); ok { + for _, cus := range extension.GetCustomizers() { + cus.Customize(preRegEvent.serviceInstance) + } + } + return nil +} + +// GetEventType will return ServiceInstancePreRegisteredEvent +func (c *customizableServiceInstanceListener) GetEventType() reflect.Type { + return reflect.TypeOf(&ServiceInstancePreRegisteredEvent{}) +} diff --git a/registry/common/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go similarity index 99% rename from registry/common/event_publishing_service_deiscovery_test.go rename to registry/event/event_publishing_service_deiscovery_test.go index 1e08335e04..27d2482d06 100644 --- a/registry/common/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "reflect" diff --git a/registry/common/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go similarity index 99% rename from registry/common/event_publishing_service_discovery.go rename to registry/event/event_publishing_service_discovery.go index f61dd84690..76fdf7237a 100644 --- a/registry/common/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( gxset "github.com/dubbogo/gost/container/set" diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go new file mode 100644 index 0000000000..282b18de79 --- /dev/null +++ b/registry/event/log_event_listener.go @@ -0,0 +1,48 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/common/observer" +) + +func init() { + extension.AddEventListener(&logEventListener{}) +} + +type logEventListener struct { + +} + +func (l *logEventListener) GetPriority() int { + return 0 +} + +func (l *logEventListener) OnEvent(e observer.Event) error { + logger.Info("Event happen: " + e.String()) + return nil +} + +func (l *logEventListener) GetEventType() reflect.Type { + return nil +} + diff --git a/registry/event/log_event_listener_test.go b/registry/event/log_event_listener_test.go new file mode 100644 index 0000000000..e7c0ba0df5 --- /dev/null +++ b/registry/event/log_event_listener_test.go @@ -0,0 +1,31 @@ +/* + * 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 event + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLogEventListener(t *testing.T) { + l := &logEventListener{} + assert.Equal(t, 0, l.GetPriority()) + assert.Nil(t, l.GetEventType()) + assert.Nil(t, l.OnEvent(&ServiceDiscoveryDestroyedEvent{})) +} diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go new file mode 100644 index 0000000000..5ae0ea91f6 --- /dev/null +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -0,0 +1,52 @@ +/* + * 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 event + +import ( + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +// ProtocolPortsMetadataCustomizer will update +type ProtocolPortsMetadataCustomizer struct { +} + +// GetPriority will return 0, which means it will be invoked at the beginning +func (p *ProtocolPortsMetadataCustomizer) GetPriority() int { + return 0 +} + +// Customize will +func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceInstance) { + metadataService, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("Could not init the MetadataService", err) + return + } + + // 4 is enough... + protocolMap := make(map[string]int, 4) + + list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE,constant.ANY_VALUE) + if err != nil { + logger.Errorf("Could", err) + return + } +} diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go new file mode 100644 index 0000000000..3d3b0c8f0e --- /dev/null +++ b/registry/event/service_config_exported_event.go @@ -0,0 +1,26 @@ +/* + * 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 event + +import ( + "github.com/apache/dubbo-go/common/observer" +) + +type ServiceConfigExportedEvent struct { + observer.BaseEvent +} diff --git a/registry/common/service_discovery_event.go b/registry/event/service_discovery_event.go similarity index 99% rename from registry/common/service_discovery_event.go rename to registry/event/service_discovery_event.go index a60ca56a39..74f6c5f19d 100644 --- a/registry/common/service_discovery_event.go +++ b/registry/event/service_discovery_event.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "github.com/apache/dubbo-go/common/observer" diff --git a/registry/common/service_instance_event.go b/registry/event/service_instance_event.go similarity index 99% rename from registry/common/service_instance_event.go rename to registry/event/service_instance_event.go index f70e7ee0ff..650b2e8e29 100644 --- a/registry/common/service_instance_event.go +++ b/registry/event/service_instance_event.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package common +package event import ( "github.com/apache/dubbo-go/common/observer" diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go new file mode 100644 index 0000000000..71abca6f87 --- /dev/null +++ b/registry/event/service_name_mapping_listener.go @@ -0,0 +1,48 @@ +/* + * 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 event + +import ( + "reflect" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/metadata/mapping" +) + +func init() { + extension.AddEventListener(&serviceNameMappingListener{ + nameMapping: extension.GetGlobalServiceNameMapping(), + }) +} +type serviceNameMappingListener struct { + nameMapping mapping.ServiceNameMapping +} + +func (s *serviceNameMappingListener) GetPriority() int { + panic("implement me") +} + +func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { + // TODO + panic("implement me") +} + +func (s *serviceNameMappingListener) GetEventType() reflect.Type { + return reflect.TypeOf(&ServiceConfigExportedEvent{}) +} diff --git a/registry/event_listener.go b/registry/event_listener.go index 1cd5ad43a6..8a2bc88956 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -53,4 +53,4 @@ func (lstn *ServiceInstancesChangedListener) GetPriority() int { // get event type func (lstn *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) -} +} \ No newline at end of file diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index e9230195f6..6b1d3c23d1 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -40,7 +40,7 @@ import ( ) const ( - defaultGroup = "DEFAULT_GROUP" + defaultGroup = constant.SERVICE_DISCOVERY_DEFAULT_GROUP idKey = "id" ) diff --git a/registry/registry.go b/registry/registry.go index 74e63aa66e..ce214c4971 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -44,7 +44,7 @@ type Registry interface { //Will remove in dubbogo version v1.1.0 //mode1 : return Listener with Next function which can return subscribe service event from registry //Deprecated! - //subscribe(common.URL) (Listener, error) + //subscribe(event.URL) (Listener, error) //Will relace mode1 in dubbogo version v1.1.0 //mode2 : callback mode, subscribe with notify(notify listener). diff --git a/registry/service_instance.go b/registry/service_instance.go index 2cc229ee3b..f9fee9f452 100644 --- a/registry/service_instance.go +++ b/registry/service_instance.go @@ -17,6 +17,10 @@ package registry +import ( + gxsort "github.com/dubbogo/gost/sort" +) + type ServiceInstance interface { // GetId will return this instance's id. It should be unique. @@ -87,3 +91,9 @@ func (d *DefaultServiceInstance) IsHealthy() bool { func (d *DefaultServiceInstance) GetMetadata() map[string]string { return d.Metadata } + +type ServiceInstanceCustomizer interface { + gxsort.Prioritizer + + Customize(instance ServiceInstance) +} diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 949010431f..9525a7d419 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -26,6 +26,7 @@ import ( cm "github.com/Workiva/go-datastructures/common" gxset "github.com/dubbogo/gost/container/set" + gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" "github.com/apache/dubbo-go/common" @@ -38,7 +39,7 @@ import ( "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" - registryCommon "github.com/apache/dubbo-go/registry/common" + registryCommon "github.com/apache/dubbo-go/registry/event" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" @@ -77,7 +78,7 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { } subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() - serviceNameMapping := extension.GetServiceNameMapping(url.GetParam(constant.SERVICE_NAME_MAPPING_KEY, "")) + serviceNameMapping := extension.GetGlobalServiceNameMapping() metaDataService, err := remote.NewMetadataService() if err != nil { return nil, perrors.WithMessage(err, "could not init metadata service") @@ -160,17 +161,52 @@ func (s *serviceDiscoveryRegistry) Register(url common.URL) error { return nil } ok, err := s.metaDataService.ExportURL(url) - s.metaDataService.PublishServiceDefinition(url) + if err != nil { logger.Errorf("The URL[%s] registry catch error:%s!", url.String(), err.Error()) return err } - if ok { - logger.Infof("The URL[%s] registry successfully!", url.String()) - } else { + if !ok { logger.Warnf("The URL[%s] has been registry!", url.String()) } - return nil + + // we try to register this instance. Dubbo do this in org.apache.dubbo.config.bootstrap.DubboBootstrap + // But we don't want to design a similar bootstrap class. + ins, err := createInstance(url) + if err != nil { + return perrors.WithMessage(err, "could not create servcie instance, please check your service url") + } + return s.serviceDiscovery.Register(ins) +} + +func createInstance(url common.URL) (registry.ServiceInstance, error) { + appConfig := config.GetApplicationConfig() + port, err := strconv.ParseInt(url.Port, 10, 32) + if err != nil { + return nil, perrors.WithMessage(err, "invalid port: "+url.Port) + } + + host := url.Ip + if len(host) == 0 { + host, err = gxnet.GetLocalIP() + if err != nil { + return nil, perrors.WithMessage(err, "could not get the local Ip") + } + } + + // usually we will add more metadata + metadata := make(map[string]string, 8) + metadata[constant.METADATA_STORAGE_TYPE_PROPERTY_NAME] = appConfig.MetadataType + + return ®istry.DefaultServiceInstance{ + ServiceName: appConfig.Name, + Host: host, + Port: int(port), + Id: host + constant.KEY_SEPARATOR + url.Port, + Enable: true, + Healthy: true, + Metadata: metadata, + }, nil } func shouldRegister(url common.URL) bool { diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index 90a8c0e257..4aa52f55ca 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -28,10 +28,10 @@ var ( ) func TestServiceDiscoveryRegistry_Register(t *testing.T) { - //registryURL,_:=common.NewURL("in-memory://localhost:12345", - // common.WithParamsValue("registry-type","service"), - // common.WithParamsValue("subscribed-services","a, b , c,d,e ,")) - //url,_:=common.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + + //registryURL,_:=event.NewURL("in-memory://localhost:12345", + // event.WithParamsValue("registry-type","service"), + // event.WithParamsValue("subscribed-services","a, b , c,d,e ,")) + //url,_:=event.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + // "?&application=" + GROUP + // "&interface=" + SERVICE_INTERFACE + // "&group=" + GROUP + diff --git a/test/integrate/dubbo/go-client/client.go b/test/integrate/dubbo/go-client/client.go index 4c62674d33..c075ec22c3 100644 --- a/test/integrate/dubbo/go-client/client.go +++ b/test/integrate/dubbo/go-client/client.go @@ -25,7 +25,7 @@ import ( import ( hessian "github.com/apache/dubbo-go-hessian2" - _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + _ "github.com/apache/dubbo-go/event/proxy/proxy_factory" "github.com/apache/dubbo-go/config" _ "github.com/apache/dubbo-go/protocol/dubbo" _ "github.com/apache/dubbo-go/registry/protocol" diff --git a/test/integrate/dubbo/go-server/server.go b/test/integrate/dubbo/go-server/server.go index 115bf0a4d7..4cc6c49083 100644 --- a/test/integrate/dubbo/go-server/server.go +++ b/test/integrate/dubbo/go-server/server.go @@ -25,7 +25,7 @@ import ( hessian "github.com/apache/dubbo-go-hessian2" _ "github.com/apache/dubbo-go/cluster/cluster_impl" _ "github.com/apache/dubbo-go/cluster/loadbalance" - _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + _ "github.com/apache/dubbo-go/event/proxy/proxy_factory" "github.com/apache/dubbo-go/config" _ "github.com/apache/dubbo-go/filter/filter_impl" _ "github.com/apache/dubbo-go/protocol/dubbo" From e2da137bd9b6ee15e9336e1af277916af9465f0d Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 3 Jun 2020 22:53:16 +0800 Subject: [PATCH 098/209] Add customizer --- common/constant/default.go | 2 +- common/constant/key.go | 22 ++-- .../extension/service_instance_customizer.go | 2 +- common/observer/event_listener.go | 1 - common/url.go | 14 ++ metadata/service/inmemory/service.go | 38 +++--- metadata/service/remote/service.go | 39 ++---- metadata/service/service.go | 10 +- registry/event/log_event_listener.go | 4 +- .../metadata_service_url_params_customizer.go | 96 ++++++++++++++ .../protocol_ports_metadata_customizer.go | 49 ++++++- .../event/service_name_mapping_listener.go | 1 + registry/event/service_revision_customizer.go | 122 ++++++++++++++++++ registry/event_listener.go | 2 +- registry/service_instance.go | 8 +- .../service_discovery_registry.go | 11 +- 16 files changed, 337 insertions(+), 84 deletions(-) create mode 100644 registry/event/metadata_service_url_params_customizer.go create mode 100644 registry/event/service_revision_customizer.go diff --git a/common/constant/default.go b/common/constant/default.go index 8442609c59..211bfc06bd 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -81,4 +81,4 @@ const ( const ( SERVICE_DISCOVERY_DEFAULT_GROUP = "DEFAULT_GROUP" -) \ No newline at end of file +) diff --git a/common/constant/key.go b/common/constant/key.go index 394f2d8c04..f57dcdb77d 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -22,6 +22,7 @@ const ( ) const ( + PORT_KEY = "port" GROUP_KEY = "group" VERSION_KEY = "version" INTERFACE_KEY = "interface" @@ -262,16 +263,17 @@ const ( // service discovery const ( - SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" - PROVIDER_BY = "provided-by" - EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" - SERVICE_INSTANCE_SELECTOR = "service-instance-selector" - METADATA_STORAGE_TYPE_PROPERTY_NAME = "dubbo.metadata.storage-type" - DEFAULT_METADATA_STORAGE_TYPE = "local" - SERVICE_INSTANCE_ENDPOINTS = "dubbo.endpoints" - METADATA_SERVICE_PREFIX = "dubbo.metadata-service." - METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" - METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" + SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" + PROVIDER_BY = "provided-by" + EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" + SUBSCRIBED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.subscribed-services.revision" + SERVICE_INSTANCE_SELECTOR = "service-instance-selector" + METADATA_STORAGE_TYPE_PROPERTY_NAME = "dubbo.metadata.storage-type" + DEFAULT_METADATA_STORAGE_TYPE = "local" + SERVICE_INSTANCE_ENDPOINTS = "dubbo.endpoints" + METADATA_SERVICE_PREFIX = "dubbo.metadata-service." + METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" + METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" diff --git a/common/extension/service_instance_customizer.go b/common/extension/service_instance_customizer.go index 40f8ca0c5d..a0e443aff5 100644 --- a/common/extension/service_instance_customizer.go +++ b/common/extension/service_instance_customizer.go @@ -29,7 +29,7 @@ var ( // AddCustomizers will put the customizer into slices and then sort them; // this method will be invoked several time, so we sort them here. -func AddCustomizers(cus registry.ServiceInstanceCustomizer) { +func AddCustomizers(cus registry.ServiceInstanceCustomizer) { customizers = append(customizers, cus) sort.Stable(customizerSlice(customizers)) } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index 3f8eeffaf9..fabad3a6ff 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -32,7 +32,6 @@ type EventListener interface { // OnEvent handle this event OnEvent(e Event) error // GetEventType listen which event type - // return nil if the implementation want to listen any event GetEventType() reflect.Type } diff --git a/common/url.go b/common/url.go index 1cfa47ae28..10bbf8ff21 100644 --- a/common/url.go +++ b/common/url.go @@ -650,3 +650,17 @@ func mergeNormalParam(mergedUrl *URL, referenceUrl *URL, paramKeys []string) []f } return methodConfigMergeFcn } + +type URLSlice []URL + +func (s URLSlice) Len() int { + return len(s) +} + +func (s URLSlice) Less(i, j int) bool { + return s[i].String() < s[j].String() +} + +func (s URLSlice) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 31492a3224..f7b7466a3d 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -17,6 +17,7 @@ package inmemory import ( + "sort" "sync" ) @@ -89,7 +90,7 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { mts.lock.RUnlock() } mts.lock.Lock() - //double chk + // double chk wantedUrl := urlSet.(*skip.SkipList).Get(Comparator(*url)) if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.Unlock() @@ -115,35 +116,38 @@ func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { } // getAllService can return all the exportedUrlString except for metadataService -func (mts *MetadataService) getAllService(services *sync.Map) *skip.SkipList { - skipList := skip.New(uint64(0)) +func (mts *MetadataService) getAllService(services *sync.Map) []common.URL { + // using skip list to dedup and sorting + res := make([]common.URL, 0) services.Range(func(key, value interface{}) bool { urls := value.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) if url.GetParam(constant.INTERFACE_KEY, url.Path) != constant.SIMPLE_METADATA_SERVICE_NAME { - skipList.Insert(Comparator(url)) + res = append(res, url) } } return true }) - return skipList + sort.Sort(common.URLSlice(res)) + return res } // getSpecifiedService can return specified service url by serviceKey -func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) *skip.SkipList { - skipList := skip.New(uint64(0)) +func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) []common.URL { + res := make([]common.URL, 0) serviceList, loaded := services.Load(serviceKey) if loaded { urls := serviceList.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) if len(protocol) == 0 || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { - skipList.Insert(Comparator(url)) + res = append(res, url) } } + sort.Stable(common.URLSlice(res)) } - return skipList + return res } // ExportURL can store the in memory @@ -173,16 +177,16 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { - //judge is consumer or provider - //side := url.GetParam(constant.SIDE_KEY, "") - //var service event.RPCService + // judge is consumer or provider + // side := url.GetParam(constant.SIDE_KEY, "") + // var service event.RPCService service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - //if side == event.RoleType(event.CONSUMER).Role() { + // if side == event.RoleType(event.CONSUMER).Role() { // //TODO:generate the service definition and store it // - //} else if side == event.RoleType(event.PROVIDER).Role() { + // } else if side == event.RoleType(event.PROVIDER).Role() { // //TODO:generate the service definition and store it - //} + // } sd := definition.BuildServiceDefinition(*service, url) data, err := sd.ToBytes() if err != nil { @@ -196,7 +200,7 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs get all exported urls -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { if serviceInterface == constant.ANY_VALUE { return mts.getAllService(mts.exportedServiceURLs), nil } else { @@ -206,7 +210,7 @@ func (mts *MetadataService) GetExportedURLs(serviceInterface string, group strin } // GetSubscribedURLs get all subscribedUrl -func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { +func (mts *MetadataService) GetSubscribedURLs() ([]common.URL, error) { return mts.getAllService(mts.subscribedServiceURLs), nil } diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index b616e2a4d4..6726b1000a 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -20,7 +20,6 @@ package remote import ( "sync" - "github.com/Workiva/go-datastructures/slice/skip" "go.uber.org/atomic" ) @@ -121,12 +120,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs will be implemented by in memory service -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { return mts.inMemoryMetadataService.GetExportedURLs(serviceInterface, group, version, protocol) } // GetSubscribedURLs will be implemented by in memory service -func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { +func (mts *MetadataService) GetSubscribedURLs() ([]common.URL, error) { return mts.inMemoryMetadataService.GetSubscribedURLs() } @@ -150,16 +149,11 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } - iterator := urls.Iter(inmemory.Comparator{}) - logger.Infof("urls length = %v", urls.Len()) - for { - if !iterator.Next() { - break - } - url := iterator.Value().(inmemory.Comparator) - id := identifier.NewServiceMetadataIdentifier(common.URL(url)) + logger.Infof("urls length = %v", len(urls)) + for _, u := range urls { + id := identifier.NewServiceMetadataIdentifier(u) id.Revision = mts.exportedRevision.Load() - if err := mts.delegateReport.SaveServiceMetadata(id, common.URL(url)); err != nil { + if err := mts.delegateReport.SaveServiceMetadata(id, u); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } @@ -173,14 +167,14 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v+", err) result = false } - if urls != nil && urls.Len() > 0 { + if urls != nil && len(urls) > 0 { id := &identifier.SubscriberMetadataIdentifier{ MetadataIdentifier: identifier.MetadataIdentifier{ Application: config.GetApplicationConfig().Name, }, Revision: subscribedRevision, } - if err := mts.delegateReport.SaveSubscribedData(id, convertUrls(urls)); err != nil { + if err := mts.delegateReport.SaveSubscribedData(id, urls); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } @@ -193,20 +187,3 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR func (MetadataService) Version() string { return version } - -// convertUrls will convert the skip list to slice -func convertUrls(list *skip.SkipList) []common.URL { - urls := make([]common.URL, list.Len()) - iterator := list.Iter(inmemory.Comparator{}) - for { - if iterator.Value() == nil { - break - } - url := iterator.Value().(inmemory.Comparator) - urls = append(urls, common.URL(url)) - if !iterator.Next() { - break - } - } - return urls -} diff --git a/metadata/service/service.go b/metadata/service/service.go index 2f8a98d185..af9528c68b 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -17,10 +17,6 @@ package service -import ( - "github.com/Workiva/go-datastructures/slice/skip" -) - import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -44,9 +40,11 @@ type MetadataService interface { // PublishServiceDefinition will generate the target url's code info PublishServiceDefinition(url common.URL) error // GetExportedURLs will get the target exported url in metadata - GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) + // the url should be unique + GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) // GetExportedURLs will get the target subscribed url in metadata - GetSubscribedURLs() (*skip.SkipList, error) + // the url should be unique + GetSubscribedURLs() ([]common.URL, error) // GetServiceDefinition will get the target service info store in metadata GetServiceDefinition(interfaceName string, group string, version string) (string, error) // GetServiceDefinition will get the target service info store in metadata by service key diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go index 282b18de79..c52b02a785 100644 --- a/registry/event/log_event_listener.go +++ b/registry/event/log_event_listener.go @@ -30,7 +30,6 @@ func init() { } type logEventListener struct { - } func (l *logEventListener) GetPriority() int { @@ -43,6 +42,5 @@ func (l *logEventListener) OnEvent(e observer.Event) error { } func (l *logEventListener) GetEventType() reflect.Type { - return nil + return reflect.TypeOf(&observer.BaseEvent{}) } - diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go new file mode 100644 index 0000000000..c9c636448c --- /dev/null +++ b/registry/event/metadata_service_url_params_customizer.go @@ -0,0 +1,96 @@ +/* + * 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 event + +import ( + "encoding/json" + + gxset "github.com/dubbogo/gost/container/set" + + "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/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +func init() { + exceptKeys := gxset.NewSet( + // remove APPLICATION_KEY because service name must be present + constant.APPLICATION_KEY, + // remove GROUP_KEY, always uses service name. + constant.GROUP_KEY, + // remove TIMESTAMP_KEY because it's nonsense + constant.TIMESTAMP_KEY) + extension.AddCustomizers(&metadataServiceURLParamsMetadataCustomizer{exceptKeys: exceptKeys}) + +} + +type metadataServiceURLParamsMetadataCustomizer struct { + exceptKeys *gxset.HashSet +} + +// GetPriority will return 0 so that it will be invoked in front of user defining Customizer +func (m *metadataServiceURLParamsMetadataCustomizer) GetPriority() int { + return 0 +} + +func (m *metadataServiceURLParamsMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not find the metadata service", err) + return + } + serviceName := constant.METADATA_SERVICE_NAME + version := ms.Version() + group := instance.GetServiceName() + urls, err := ms.GetExportedURLs(serviceName, group, version, constant.ANY_VALUE) + if err != nil || len(urls) == 0 { + logger.Errorf("could not find the exported urls", err) + return + } + ps := m.convertToParams(urls) + str, err := json.Marshal(ps) + if err != nil { + logger.Errorf("could not transfer the map to json", err) + return + } + instance.GetMetadata()[constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME] = string(str) +} + +func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []common.URL) map[string]map[string]string { + + // usually there will be only one protocol + res := make(map[string]map[string]string, 1) + // those keys are useless + + for _, u := range urls { + p := make(map[string]string, len(u.GetParams())) + for k, v := range u.GetParams() { + // we will ignore that + if m.exceptKeys.Contains(k) || len(v) == 0 { + continue + } + p[k] = v[0] + } + p[constant.PORT_KEY] = u.Port + res[u.Protocol] = p + } + return res +} diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index 5ae0ea91f6..975463fe3e 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -18,6 +18,9 @@ package event import ( + "encoding/json" + "strconv" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/metadata/service/remote" @@ -44,9 +47,49 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns // 4 is enough... protocolMap := make(map[string]int, 4) - list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE,constant.ANY_VALUE) - if err != nil { - logger.Errorf("Could", err) + list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + if err != nil || list == nil { + logger.Errorf("Could not find exported urls", err) return } + + for _, u := range list { + if len(u.Protocol) == 0 { + continue + } + + port, err := strconv.Atoi(u.Port) + if err != nil { + logger.Errorf("Could not customize the metadata of port. ", err) + } + protocolMap[u.Protocol] = port + } + + instance.GetMetadata()[constant.SERVICE_INSTANCE_ENDPOINTS] = endpointsStr(protocolMap) +} + +func endpointsStr(protocolMap map[string]int) string { + if len(protocolMap) == 0 { + return "" + } + + endpoints := make([]endpoint, 0, len(protocolMap)) + for k, v := range protocolMap { + endpoints = append(endpoints, endpoint{ + port: v, + protocol: k, + }) + } + + str, err := json.Marshal(endpoints) + if err != nil { + logger.Errorf("could not convert the endpoints to json", err) + return "" + } + return string(str) +} + +type endpoint struct { + port int + protocol string } diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go index 71abca6f87..06cd68d053 100644 --- a/registry/event/service_name_mapping_listener.go +++ b/registry/event/service_name_mapping_listener.go @@ -30,6 +30,7 @@ func init() { nameMapping: extension.GetGlobalServiceNameMapping(), }) } + type serviceNameMappingListener struct { nameMapping mapping.ServiceNameMapping } diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go new file mode 100644 index 0000000000..51475d06c4 --- /dev/null +++ b/registry/event/service_revision_customizer.go @@ -0,0 +1,122 @@ +/* + * 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 event + +import ( + "fmt" + "hash/crc32" + "sort" + + "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/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +const defaultRevision = "N/A" + +func init() { + extension.AddCustomizers(&exportedServicesRevisionMetadataCustomizer{}) + extension.AddCustomizers(&subscribedServicesRevisionMetadataCustomizer{}) +} + +type exportedServicesRevisionMetadataCustomizer struct { +} + +// GetPriority will return 1 so that it will be invoked in front of user defining Customizer +func (e *exportedServicesRevisionMetadataCustomizer) GetPriority() int { + return 1 +} + +func (e *exportedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not get metadata service", err) + return + } + + urls, err := ms.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + + if err != nil { + logger.Errorf("could not find the exported url", err) + } + + revision := resolveRevision(urls) + if len(revision) == 0 { + revision = defaultRevision + } + instance.GetMetadata()[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] = revision +} + +type subscribedServicesRevisionMetadataCustomizer struct { +} + +// GetPriority will return 2 so that it will be invoked in front of user defining Customizer +func (e *subscribedServicesRevisionMetadataCustomizer) GetPriority() int { + return 2 +} + +func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not get metadata service", err) + return + } + + urls, err := ms.GetSubscribedURLs() + + if err != nil { + logger.Errorf("could not find the subscribed url", err) + } + + revision := resolveRevision(urls) + if len(revision) == 0 { + revision = defaultRevision + } + instance.GetMetadata()[constant.SUBSCRIBED_SERVICES_REVISION_PROPERTY_NAME] = revision +} + +// resolveRevision is different from Dubbo because golang doesn't support overload +// so that we could use interface + method name as identifier and ignore the method params +// per my understanding, it's enough because Dubbo actually ignore the url params. +// please refer org.apache.dubbo.common.URL#toParameterString(java.lang.String...) +func resolveRevision(urls []common.URL) string { + if len(urls) == 0 { + return "" + } + candidates := make([]string, 0, len(urls)) + + for _, u := range urls { + sk := u.GetParam(constant.INTERFACE_KEY, "") + for _, m := range u.Methods { + // methods are part of candidates + candidates = append(candidates, sk+constant.KEY_SEPARATOR+m) + } + // append url params if we need it + } + sort.Sort(sort.StringSlice(candidates)) + + // it's nearly impossible to be overflow + res := uint64(0) + for _, c := range candidates { + res += uint64(crc32.ChecksumIEEE([]byte(c))) + } + return fmt.Sprint(res) +} diff --git a/registry/event_listener.go b/registry/event_listener.go index 8a2bc88956..1cd5ad43a6 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -53,4 +53,4 @@ func (lstn *ServiceInstancesChangedListener) GetPriority() int { // get event type func (lstn *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) -} \ No newline at end of file +} diff --git a/registry/service_instance.go b/registry/service_instance.go index f9fee9f452..08ca79ecbf 100644 --- a/registry/service_instance.go +++ b/registry/service_instance.go @@ -87,11 +87,17 @@ func (d *DefaultServiceInstance) IsHealthy() bool { return d.Healthy } -// GetMetadata will return the metadata +// GetMetadata will return the metadata, it will never return nil func (d *DefaultServiceInstance) GetMetadata() map[string]string { + if d.Metadata == nil { + d.Metadata = make(map[string]string, 0) + } return d.Metadata } +// ServiceInstanceCustomizer is an extension point which allow user using custom logic to modify instance +// Be careful of priority. Usually you should use number between [100, 9000] +// other number will be thought as system reserve number type ServiceInstanceCustomizer interface { gxsort.Prioritizer diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 9525a7d419..379578ddc6 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -399,19 +399,12 @@ func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registr if metadataService == nil { return urls } - result, err := metadataService.GetExportedURLs("*", "", "", "") + result, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) if err != nil { logger.Errorf("get exported urls catch error:%s,instance:%+v", err.Error(), serviceInstance) return urls } - if result == nil { - logger.Errorf("get empty exported urls,instance:%+v", serviceInstance) - return urls - } - for i := uint64(0); i < result.Len(); i++ { - urls = append(urls, common.URL(result.ByPosition(i).(comparator))) - } - return urls + return result } func (s *serviceDiscoveryRegistry) prepareServiceRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { From 59eee390bda1b2c6b566928f7d50a58c272c0929 Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 3 Jun 2020 22:53:16 +0800 Subject: [PATCH 099/209] Add customizer --- common/constant/default.go | 2 +- common/constant/key.go | 22 ++-- .../extension/service_instance_customizer.go | 2 +- common/observer/event_listener.go | 3 +- common/url.go | 14 ++ metadata/report/nacos/report.go | 1 + metadata/service/inmemory/service.go | 38 +++--- metadata/service/remote/service.go | 39 ++---- metadata/service/service.go | 10 +- registry/event/log_event_listener.go | 4 +- .../metadata_service_url_params_customizer.go | 96 ++++++++++++++ .../protocol_ports_metadata_customizer.go | 49 ++++++- .../event/service_config_exported_event.go | 2 + .../event/service_name_mapping_listener.go | 10 +- registry/event/service_revision_customizer.go | 122 ++++++++++++++++++ registry/event_listener.go | 2 +- registry/service_instance.go | 8 +- .../service_discovery_registry.go | 11 +- 18 files changed, 348 insertions(+), 87 deletions(-) create mode 100644 registry/event/metadata_service_url_params_customizer.go create mode 100644 registry/event/service_revision_customizer.go diff --git a/common/constant/default.go b/common/constant/default.go index 8442609c59..211bfc06bd 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -81,4 +81,4 @@ const ( const ( SERVICE_DISCOVERY_DEFAULT_GROUP = "DEFAULT_GROUP" -) \ No newline at end of file +) diff --git a/common/constant/key.go b/common/constant/key.go index 394f2d8c04..f57dcdb77d 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -22,6 +22,7 @@ const ( ) const ( + PORT_KEY = "port" GROUP_KEY = "group" VERSION_KEY = "version" INTERFACE_KEY = "interface" @@ -262,16 +263,17 @@ const ( // service discovery const ( - SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" - PROVIDER_BY = "provided-by" - EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" - SERVICE_INSTANCE_SELECTOR = "service-instance-selector" - METADATA_STORAGE_TYPE_PROPERTY_NAME = "dubbo.metadata.storage-type" - DEFAULT_METADATA_STORAGE_TYPE = "local" - SERVICE_INSTANCE_ENDPOINTS = "dubbo.endpoints" - METADATA_SERVICE_PREFIX = "dubbo.metadata-service." - METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" - METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" + SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services" + PROVIDER_BY = "provided-by" + EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.exported-services.revision" + SUBSCRIBED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.subscribed-services.revision" + SERVICE_INSTANCE_SELECTOR = "service-instance-selector" + METADATA_STORAGE_TYPE_PROPERTY_NAME = "dubbo.metadata.storage-type" + DEFAULT_METADATA_STORAGE_TYPE = "local" + SERVICE_INSTANCE_ENDPOINTS = "dubbo.endpoints" + METADATA_SERVICE_PREFIX = "dubbo.metadata-service." + METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "url-params" + METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_PREFIX + "urls" // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" diff --git a/common/extension/service_instance_customizer.go b/common/extension/service_instance_customizer.go index 40f8ca0c5d..a0e443aff5 100644 --- a/common/extension/service_instance_customizer.go +++ b/common/extension/service_instance_customizer.go @@ -29,7 +29,7 @@ var ( // AddCustomizers will put the customizer into slices and then sort them; // this method will be invoked several time, so we sort them here. -func AddCustomizers(cus registry.ServiceInstanceCustomizer) { +func AddCustomizers(cus registry.ServiceInstanceCustomizer) { customizers = append(customizers, cus) sort.Stable(customizerSlice(customizers)) } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index 3f8eeffaf9..f4423d7dd7 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -27,12 +27,13 @@ import ( // EventListener is an new interface used to align with dubbo 2.7.5 // It contains the Prioritized means that the listener has its priority +// Usually the priority of your custom implementation should be between [100, 9000] +// the number outside the range will be though as system reserve number type EventListener interface { gxsort.Prioritizer // OnEvent handle this event OnEvent(e Event) error // GetEventType listen which event type - // return nil if the implementation want to listen any event GetEventType() reflect.Type } diff --git a/common/url.go b/common/url.go index 1cfa47ae28..10bbf8ff21 100644 --- a/common/url.go +++ b/common/url.go @@ -650,3 +650,17 @@ func mergeNormalParam(mergedUrl *URL, referenceUrl *URL, paramKeys []string) []f } return methodConfigMergeFcn } + +type URLSlice []URL + +func (s URLSlice) Len() int { + return len(s) +} + +func (s URLSlice) Less(i, j int) bool { + return s[i].String() < s[j].String() +} + +func (s URLSlice) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 9dbec51822..5eaee7bb2b 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -171,6 +171,7 @@ func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) []string { decodeCfg, err := url.QueryUnescape(cfg) if err != nil { logger.Errorf("The config is invalid: %s", cfg) + return res } res = append(res, decodeCfg) return res diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 31492a3224..f7b7466a3d 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -17,6 +17,7 @@ package inmemory import ( + "sort" "sync" ) @@ -89,7 +90,7 @@ func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool { mts.lock.RUnlock() } mts.lock.Lock() - //double chk + // double chk wantedUrl := urlSet.(*skip.SkipList).Get(Comparator(*url)) if len(wantedUrl) > 0 && wantedUrl[0] != nil { mts.lock.Unlock() @@ -115,35 +116,38 @@ func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) { } // getAllService can return all the exportedUrlString except for metadataService -func (mts *MetadataService) getAllService(services *sync.Map) *skip.SkipList { - skipList := skip.New(uint64(0)) +func (mts *MetadataService) getAllService(services *sync.Map) []common.URL { + // using skip list to dedup and sorting + res := make([]common.URL, 0) services.Range(func(key, value interface{}) bool { urls := value.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) if url.GetParam(constant.INTERFACE_KEY, url.Path) != constant.SIMPLE_METADATA_SERVICE_NAME { - skipList.Insert(Comparator(url)) + res = append(res, url) } } return true }) - return skipList + sort.Sort(common.URLSlice(res)) + return res } // getSpecifiedService can return specified service url by serviceKey -func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) *skip.SkipList { - skipList := skip.New(uint64(0)) +func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) []common.URL { + res := make([]common.URL, 0) serviceList, loaded := services.Load(serviceKey) if loaded { urls := serviceList.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) if len(protocol) == 0 || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { - skipList.Insert(Comparator(url)) + res = append(res, url) } } + sort.Stable(common.URLSlice(res)) } - return skipList + return res } // ExportURL can store the in memory @@ -173,16 +177,16 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { - //judge is consumer or provider - //side := url.GetParam(constant.SIDE_KEY, "") - //var service event.RPCService + // judge is consumer or provider + // side := url.GetParam(constant.SIDE_KEY, "") + // var service event.RPCService service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - //if side == event.RoleType(event.CONSUMER).Role() { + // if side == event.RoleType(event.CONSUMER).Role() { // //TODO:generate the service definition and store it // - //} else if side == event.RoleType(event.PROVIDER).Role() { + // } else if side == event.RoleType(event.PROVIDER).Role() { // //TODO:generate the service definition and store it - //} + // } sd := definition.BuildServiceDefinition(*service, url) data, err := sd.ToBytes() if err != nil { @@ -196,7 +200,7 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs get all exported urls -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { if serviceInterface == constant.ANY_VALUE { return mts.getAllService(mts.exportedServiceURLs), nil } else { @@ -206,7 +210,7 @@ func (mts *MetadataService) GetExportedURLs(serviceInterface string, group strin } // GetSubscribedURLs get all subscribedUrl -func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { +func (mts *MetadataService) GetSubscribedURLs() ([]common.URL, error) { return mts.getAllService(mts.subscribedServiceURLs), nil } diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index b616e2a4d4..6726b1000a 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -20,7 +20,6 @@ package remote import ( "sync" - "github.com/Workiva/go-datastructures/slice/skip" "go.uber.org/atomic" ) @@ -121,12 +120,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs will be implemented by in memory service -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { return mts.inMemoryMetadataService.GetExportedURLs(serviceInterface, group, version, protocol) } // GetSubscribedURLs will be implemented by in memory service -func (mts *MetadataService) GetSubscribedURLs() (*skip.SkipList, error) { +func (mts *MetadataService) GetSubscribedURLs() ([]common.URL, error) { return mts.inMemoryMetadataService.GetSubscribedURLs() } @@ -150,16 +149,11 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } - iterator := urls.Iter(inmemory.Comparator{}) - logger.Infof("urls length = %v", urls.Len()) - for { - if !iterator.Next() { - break - } - url := iterator.Value().(inmemory.Comparator) - id := identifier.NewServiceMetadataIdentifier(common.URL(url)) + logger.Infof("urls length = %v", len(urls)) + for _, u := range urls { + id := identifier.NewServiceMetadataIdentifier(u) id.Revision = mts.exportedRevision.Load() - if err := mts.delegateReport.SaveServiceMetadata(id, common.URL(url)); err != nil { + if err := mts.delegateReport.SaveServiceMetadata(id, u); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } @@ -173,14 +167,14 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v+", err) result = false } - if urls != nil && urls.Len() > 0 { + if urls != nil && len(urls) > 0 { id := &identifier.SubscriberMetadataIdentifier{ MetadataIdentifier: identifier.MetadataIdentifier{ Application: config.GetApplicationConfig().Name, }, Revision: subscribedRevision, } - if err := mts.delegateReport.SaveSubscribedData(id, convertUrls(urls)); err != nil { + if err := mts.delegateReport.SaveSubscribedData(id, urls); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) result = false } @@ -193,20 +187,3 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR func (MetadataService) Version() string { return version } - -// convertUrls will convert the skip list to slice -func convertUrls(list *skip.SkipList) []common.URL { - urls := make([]common.URL, list.Len()) - iterator := list.Iter(inmemory.Comparator{}) - for { - if iterator.Value() == nil { - break - } - url := iterator.Value().(inmemory.Comparator) - urls = append(urls, common.URL(url)) - if !iterator.Next() { - break - } - } - return urls -} diff --git a/metadata/service/service.go b/metadata/service/service.go index 2f8a98d185..af9528c68b 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -17,10 +17,6 @@ package service -import ( - "github.com/Workiva/go-datastructures/slice/skip" -) - import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -44,9 +40,11 @@ type MetadataService interface { // PublishServiceDefinition will generate the target url's code info PublishServiceDefinition(url common.URL) error // GetExportedURLs will get the target exported url in metadata - GetExportedURLs(serviceInterface string, group string, version string, protocol string) (*skip.SkipList, error) + // the url should be unique + GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) // GetExportedURLs will get the target subscribed url in metadata - GetSubscribedURLs() (*skip.SkipList, error) + // the url should be unique + GetSubscribedURLs() ([]common.URL, error) // GetServiceDefinition will get the target service info store in metadata GetServiceDefinition(interfaceName string, group string, version string) (string, error) // GetServiceDefinition will get the target service info store in metadata by service key diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go index 282b18de79..c52b02a785 100644 --- a/registry/event/log_event_listener.go +++ b/registry/event/log_event_listener.go @@ -30,7 +30,6 @@ func init() { } type logEventListener struct { - } func (l *logEventListener) GetPriority() int { @@ -43,6 +42,5 @@ func (l *logEventListener) OnEvent(e observer.Event) error { } func (l *logEventListener) GetEventType() reflect.Type { - return nil + return reflect.TypeOf(&observer.BaseEvent{}) } - diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go new file mode 100644 index 0000000000..c9c636448c --- /dev/null +++ b/registry/event/metadata_service_url_params_customizer.go @@ -0,0 +1,96 @@ +/* + * 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 event + +import ( + "encoding/json" + + gxset "github.com/dubbogo/gost/container/set" + + "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/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +func init() { + exceptKeys := gxset.NewSet( + // remove APPLICATION_KEY because service name must be present + constant.APPLICATION_KEY, + // remove GROUP_KEY, always uses service name. + constant.GROUP_KEY, + // remove TIMESTAMP_KEY because it's nonsense + constant.TIMESTAMP_KEY) + extension.AddCustomizers(&metadataServiceURLParamsMetadataCustomizer{exceptKeys: exceptKeys}) + +} + +type metadataServiceURLParamsMetadataCustomizer struct { + exceptKeys *gxset.HashSet +} + +// GetPriority will return 0 so that it will be invoked in front of user defining Customizer +func (m *metadataServiceURLParamsMetadataCustomizer) GetPriority() int { + return 0 +} + +func (m *metadataServiceURLParamsMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not find the metadata service", err) + return + } + serviceName := constant.METADATA_SERVICE_NAME + version := ms.Version() + group := instance.GetServiceName() + urls, err := ms.GetExportedURLs(serviceName, group, version, constant.ANY_VALUE) + if err != nil || len(urls) == 0 { + logger.Errorf("could not find the exported urls", err) + return + } + ps := m.convertToParams(urls) + str, err := json.Marshal(ps) + if err != nil { + logger.Errorf("could not transfer the map to json", err) + return + } + instance.GetMetadata()[constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME] = string(str) +} + +func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []common.URL) map[string]map[string]string { + + // usually there will be only one protocol + res := make(map[string]map[string]string, 1) + // those keys are useless + + for _, u := range urls { + p := make(map[string]string, len(u.GetParams())) + for k, v := range u.GetParams() { + // we will ignore that + if m.exceptKeys.Contains(k) || len(v) == 0 { + continue + } + p[k] = v[0] + } + p[constant.PORT_KEY] = u.Port + res[u.Protocol] = p + } + return res +} diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index 5ae0ea91f6..975463fe3e 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -18,6 +18,9 @@ package event import ( + "encoding/json" + "strconv" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/metadata/service/remote" @@ -44,9 +47,49 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns // 4 is enough... protocolMap := make(map[string]int, 4) - list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE,constant.ANY_VALUE) - if err != nil { - logger.Errorf("Could", err) + list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + if err != nil || list == nil { + logger.Errorf("Could not find exported urls", err) return } + + for _, u := range list { + if len(u.Protocol) == 0 { + continue + } + + port, err := strconv.Atoi(u.Port) + if err != nil { + logger.Errorf("Could not customize the metadata of port. ", err) + } + protocolMap[u.Protocol] = port + } + + instance.GetMetadata()[constant.SERVICE_INSTANCE_ENDPOINTS] = endpointsStr(protocolMap) +} + +func endpointsStr(protocolMap map[string]int) string { + if len(protocolMap) == 0 { + return "" + } + + endpoints := make([]endpoint, 0, len(protocolMap)) + for k, v := range protocolMap { + endpoints = append(endpoints, endpoint{ + port: v, + protocol: k, + }) + } + + str, err := json.Marshal(endpoints) + if err != nil { + logger.Errorf("could not convert the endpoints to json", err) + return "" + } + return string(str) +} + +type endpoint struct { + port int + protocol string } diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go index 3d3b0c8f0e..371f72d0db 100644 --- a/registry/event/service_config_exported_event.go +++ b/registry/event/service_config_exported_event.go @@ -19,8 +19,10 @@ package event import ( "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/config" ) type ServiceConfigExportedEvent struct { observer.BaseEvent + ServiceConfig config.ServiceConfig } diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go index 71abca6f87..9ec7392b17 100644 --- a/registry/event/service_name_mapping_listener.go +++ b/registry/event/service_name_mapping_listener.go @@ -30,17 +30,21 @@ func init() { nameMapping: extension.GetGlobalServiceNameMapping(), }) } + type serviceNameMappingListener struct { nameMapping mapping.ServiceNameMapping } +// GetPriority return 3, which ensure that this listener will be invoked after log listener func (s *serviceNameMappingListener) GetPriority() int { - panic("implement me") + return 3 } func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { - // TODO - panic("implement me") + if ex, ok := e.(*ServiceConfigExportedEvent); ok { + sc := ex.ServiceConfig + } + return nil } func (s *serviceNameMappingListener) GetEventType() reflect.Type { diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go new file mode 100644 index 0000000000..51475d06c4 --- /dev/null +++ b/registry/event/service_revision_customizer.go @@ -0,0 +1,122 @@ +/* + * 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 event + +import ( + "fmt" + "hash/crc32" + "sort" + + "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/metadata/service/remote" + "github.com/apache/dubbo-go/registry" +) + +const defaultRevision = "N/A" + +func init() { + extension.AddCustomizers(&exportedServicesRevisionMetadataCustomizer{}) + extension.AddCustomizers(&subscribedServicesRevisionMetadataCustomizer{}) +} + +type exportedServicesRevisionMetadataCustomizer struct { +} + +// GetPriority will return 1 so that it will be invoked in front of user defining Customizer +func (e *exportedServicesRevisionMetadataCustomizer) GetPriority() int { + return 1 +} + +func (e *exportedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not get metadata service", err) + return + } + + urls, err := ms.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + + if err != nil { + logger.Errorf("could not find the exported url", err) + } + + revision := resolveRevision(urls) + if len(revision) == 0 { + revision = defaultRevision + } + instance.GetMetadata()[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] = revision +} + +type subscribedServicesRevisionMetadataCustomizer struct { +} + +// GetPriority will return 2 so that it will be invoked in front of user defining Customizer +func (e *subscribedServicesRevisionMetadataCustomizer) GetPriority() int { + return 2 +} + +func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { + ms, err := remote.NewMetadataService() + if err != nil { + logger.Errorf("could not get metadata service", err) + return + } + + urls, err := ms.GetSubscribedURLs() + + if err != nil { + logger.Errorf("could not find the subscribed url", err) + } + + revision := resolveRevision(urls) + if len(revision) == 0 { + revision = defaultRevision + } + instance.GetMetadata()[constant.SUBSCRIBED_SERVICES_REVISION_PROPERTY_NAME] = revision +} + +// resolveRevision is different from Dubbo because golang doesn't support overload +// so that we could use interface + method name as identifier and ignore the method params +// per my understanding, it's enough because Dubbo actually ignore the url params. +// please refer org.apache.dubbo.common.URL#toParameterString(java.lang.String...) +func resolveRevision(urls []common.URL) string { + if len(urls) == 0 { + return "" + } + candidates := make([]string, 0, len(urls)) + + for _, u := range urls { + sk := u.GetParam(constant.INTERFACE_KEY, "") + for _, m := range u.Methods { + // methods are part of candidates + candidates = append(candidates, sk+constant.KEY_SEPARATOR+m) + } + // append url params if we need it + } + sort.Sort(sort.StringSlice(candidates)) + + // it's nearly impossible to be overflow + res := uint64(0) + for _, c := range candidates { + res += uint64(crc32.ChecksumIEEE([]byte(c))) + } + return fmt.Sprint(res) +} diff --git a/registry/event_listener.go b/registry/event_listener.go index 8a2bc88956..1cd5ad43a6 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -53,4 +53,4 @@ func (lstn *ServiceInstancesChangedListener) GetPriority() int { // get event type func (lstn *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) -} \ No newline at end of file +} diff --git a/registry/service_instance.go b/registry/service_instance.go index f9fee9f452..08ca79ecbf 100644 --- a/registry/service_instance.go +++ b/registry/service_instance.go @@ -87,11 +87,17 @@ func (d *DefaultServiceInstance) IsHealthy() bool { return d.Healthy } -// GetMetadata will return the metadata +// GetMetadata will return the metadata, it will never return nil func (d *DefaultServiceInstance) GetMetadata() map[string]string { + if d.Metadata == nil { + d.Metadata = make(map[string]string, 0) + } return d.Metadata } +// ServiceInstanceCustomizer is an extension point which allow user using custom logic to modify instance +// Be careful of priority. Usually you should use number between [100, 9000] +// other number will be thought as system reserve number type ServiceInstanceCustomizer interface { gxsort.Prioritizer diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 9525a7d419..379578ddc6 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -399,19 +399,12 @@ func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registr if metadataService == nil { return urls } - result, err := metadataService.GetExportedURLs("*", "", "", "") + result, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) if err != nil { logger.Errorf("get exported urls catch error:%s,instance:%+v", err.Error(), serviceInstance) return urls } - if result == nil { - logger.Errorf("get empty exported urls,instance:%+v", serviceInstance) - return urls - } - for i := uint64(0); i < result.Len(); i++ { - urls = append(urls, common.URL(result.ByPosition(i).(comparator))) - } - return urls + return result } func (s *serviceDiscoveryRegistry) prepareServiceRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { From d997d51e8ad6636a871a8fb1027891fd029927ce Mon Sep 17 00:00:00 2001 From: flycash Date: Thu, 4 Jun 2020 23:23:47 +0800 Subject: [PATCH 100/209] fix review --- metadata/report/nacos/report.go | 1 + 1 file changed, 1 insertion(+) diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 63ca7ec240..8f29c7de0f 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -174,6 +174,7 @@ func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) []string { decodeCfg, err := url.QueryUnescape(cfg) if err != nil { logger.Errorf("The config is invalid: %s", cfg) + return res } res = append(res, decodeCfg) return res From b815070651955ceb2fa500281d3925bc8076fdfa Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 5 Jun 2020 21:40:04 +0800 Subject: [PATCH 101/209] code clean --- remoting/zookeeper/client.go | 47 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index a165d8a77c..ba4ea24239 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -42,7 +42,7 @@ const ( ) var ( - errNilZkClientConn = perrors.New("zookeeperclient{conn} is nil") + errNilZkClientConn = perrors.New("zookeeper client{conn} is nil") errNilChildren = perrors.Errorf("has none children") errNilNode = perrors.Errorf("node does not exist") ) @@ -114,12 +114,11 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { var ( err error ) - opions := &Options{} + options := &Options{} for _, opt := range opts { - opt(opions) + opt(options) } connected := false - err = nil lock := container.ZkClientLock() url := container.GetUrl() @@ -128,7 +127,7 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { defer lock.Unlock() if container.ZkClient() == nil { - //in dubbo ,every registry only connect one node ,so this is []string{r.Address} + // in dubbo, every registry only connect one node, so this is []string{r.Address} timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) if err != nil { logger.Errorf("timeout config %v is invalid ,err is %v", @@ -136,10 +135,10 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location) } zkAddresses := strings.Split(url.Location, ",") - newClient, err := newZookeeperClient(opions.zkName, zkAddresses, timeout) + newClient, err := newZookeeperClient(options.zkName, zkAddresses, timeout) if err != nil { logger.Warnf("newZookeeperClient(name{%s}, zk address{%v}, timeout{%d}) = error{%v}", - opions.zkName, url.Location, timeout.String(), err) + options.zkName, url.Location, timeout.String(), err) return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location) } container.SetZkClient(newClient) @@ -157,8 +156,8 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { } if connected { - logger.Info("Connect to zookeeper successfully, name{%s}, zk address{%v}", opions.zkName, url.Location) - container.WaitGroup().Add(1) //zk client start successful, then registry wg +1 + logger.Info("Connect to zookeeper successfully, name{%s}, zk address{%v}", options.zkName, url.Location) + container.WaitGroup().Add(1) // zk client start successful, then registry wg +1 } return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.PrimitiveURL) @@ -214,14 +213,14 @@ func NewMockZookeeperClient(name string, timeout time.Duration, opts ...Option) eventRegistry: make(map[string][]*chan struct{}), } - opions := &Options{} + options := &Options{} for _, opt := range opts { - opt(opions) + opt(options) } // connect to zookeeper - if opions.ts != nil { - ts = opions.ts + if options.ts != nil { + ts = options.ts } else { ts, err = zk.StartTestCluster(1, nil, nil) if err != nil { @@ -229,16 +228,10 @@ func NewMockZookeeperClient(name string, timeout time.Duration, opts ...Option) } } - //callbackChan := make(chan zk.Event) - //f := func(event zk.Event) { - // callbackChan <- event - //} - z.Conn, event, err = ts.ConnectWithOptions(timeout) if err != nil { return nil, nil, nil, perrors.WithMessagef(err, "zk.Connect") } - //z.wait.Add(1) return ts, z, event, nil } @@ -255,11 +248,10 @@ func (z *ZookeeperClient) HandleZkEvent(session <-chan zk.Event) { logger.Infof("zk{path:%v, name:%s} connection goroutine game over.", z.ZkAddrs, z.name) }() -LOOP: for { select { case <-z.exit: - break LOOP + return case event = <-session: logger.Warnf("client{%s} get a zookeeper event{type:%s, server:%s, path:%s, state:%d-%s, err:%v}", z.name, event.Type, event.Server, event.Path, event.State, StateToString(event.State), event.Err) @@ -274,8 +266,7 @@ LOOP: if conn != nil { conn.Close() } - - break LOOP + return case (int)(zk.EventNodeDataChanged), (int)(zk.EventNodeChildrenChanged): logger.Infof("zkClient{%s} get zk node changed event{path:%s}", z.name, event.Path) z.RLock() @@ -441,11 +432,7 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { // Delete ... func (z *ZookeeperClient) Delete(basePath string) error { - var ( - err error - ) - - err = errNilZkClientConn + err := errNilZkClientConn conn := z.getConn() if conn != nil { err = conn.Delete(basePath, -1) @@ -464,14 +451,12 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er ) err = errNilZkClientConn - data = []byte("") zkPath = path.Join(basePath) + "/" + node conn := z.getConn() if conn != nil { - tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) + tmpPath, err = conn.Create(zkPath, []byte(""), zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } - //if err != nil && err != zk.ErrNodeExists { if err != nil { logger.Warnf("conn.Create(\"%s\", zk.FlagEphemeral) = error(%v)\n", zkPath, perrors.WithStack(err)) return zkPath, perrors.WithStack(err) From efd2305ff24fe637857dcc304f7e69cc7c105efc Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 5 Jun 2020 21:43:34 +0800 Subject: [PATCH 102/209] fix --- remoting/zookeeper/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index ba4ea24239..8b0c20fc36 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -445,7 +445,6 @@ func (z *ZookeeperClient) Delete(basePath string) error { func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, error) { var ( err error - data []byte zkPath string tmpPath string ) From 2398d2093a3ec4a1565b7e0532a531cb17e7e936 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 5 Jun 2020 22:22:41 +0800 Subject: [PATCH 103/209] fix log --- remoting/zookeeper/client.go | 16 ++++++++-------- remoting/zookeeper/client_test.go | 7 +++++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 8b0c20fc36..9c70b0b8c0 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -384,11 +384,11 @@ func (z *ZookeeperClient) Close() { z.Conn = nil z.Unlock() if conn != nil { - logger.Warnf("zkClient Conn{name:%s, zk addr:%s} exit now.", z.name, conn.SessionID()) + logger.Infof("zkClient Conn{name:%s, zk addr:%d} exit now.", z.name, conn.SessionID()) conn.Close() } - logger.Warnf("zkClient{name:%s, zk addr:%s} exit now.", z.name, z.ZkAddrs) + logger.Infof("zkClient{name:%s, zk addr:%s} exit now.", z.name, z.ZkAddrs) } // Create will create the node recursively, which means that if the parent node is absent, @@ -419,9 +419,9 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { if err != nil { if err == zk.ErrNodeExists { - logger.Debugf("zk.create(\"%s\") exists\n", tmpPath) + logger.Debugf("zk.create(\"%s\") exists", tmpPath) } else { - logger.Errorf("zk.create(\"%s\") error(%v)\n", tmpPath, perrors.WithStack(err)) + logger.Errorf("zk.create(\"%s\") error(%v)", tmpPath, perrors.WithStack(err)) return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath) } } @@ -457,10 +457,10 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er } if err != nil { - logger.Warnf("conn.Create(\"%s\", zk.FlagEphemeral) = error(%v)\n", zkPath, perrors.WithStack(err)) + logger.Warnf("conn.Create(\"%s\", zk.FlagEphemeral) = error(%v)", zkPath, perrors.WithStack(err)) return zkPath, perrors.WithStack(err) } - logger.Debugf("zkClient{%s} create a temp zookeeper node:%s\n", z.name, tmpPath) + logger.Debugf("zkClient{%s} create a temp zookeeper node:%s", z.name, tmpPath) return tmpPath, nil } @@ -485,11 +485,11 @@ func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, logger.Debugf("zookeeperClient.RegisterTempSeq(basePath{%s}) = tempPath{%s}", basePath, tmpPath) if err != nil && err != zk.ErrNodeExists { - logger.Errorf("zkClient{%s} conn.Create(\"%s\", \"%s\", zk.FlagEphemeral|zk.FlagSequence) error(%v)\n", + logger.Errorf("zkClient{%s} conn.Create(\"%s\", \"%s\", zk.FlagEphemeral|zk.FlagSequence) error(%v)", z.name, basePath, string(data), err) return "", perrors.WithStack(err) } - logger.Debugf("zkClient{%s} create a temp zookeeper node:%s\n", z.name, tmpPath) + logger.Debugf("zkClient{%s} create a temp zookeeper node:%s", z.name, tmpPath) return tmpPath, nil } diff --git a/remoting/zookeeper/client_test.go b/remoting/zookeeper/client_test.go index cb41eb326b..9be6c4644a 100644 --- a/remoting/zookeeper/client_test.go +++ b/remoting/zookeeper/client_test.go @@ -18,7 +18,6 @@ package zookeeper import ( - "fmt" "testing" "time" ) @@ -28,6 +27,10 @@ import ( "github.com/stretchr/testify/assert" ) +import ( + "github.com/apache/dubbo-go/common/logger" +) + func verifyEventStateOrder(t *testing.T, c <-chan zk.Event, expectedStates []zk.State, source string) { for _, state := range expectedStates { for { @@ -35,7 +38,7 @@ func verifyEventStateOrder(t *testing.T, c <-chan zk.Event, expectedStates []zk. if !ok { t.Fatalf("unexpected channel close for %s", source) } - fmt.Println(event) + logger.Debug(event) if event.Type != zk.EventSession { continue } From 2997c11dee8f91d76f283319b6ffb0af3b7a2866 Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 5 Jun 2020 23:34:27 +0800 Subject: [PATCH 104/209] refactor MetadataService --- common/extension/metadata_service.go | 42 +++++++++++++++++++ common/rpc_service_test.go | 6 +-- config/service_config.go | 4 +- .../mapping/dynamic/service_name_mapping.go | 5 ++- .../dynamic/service_name_mapping_test.go | 2 +- metadata/report/nacos/report.go | 2 +- metadata/report/nacos/report_test.go | 2 +- .../service/exporter/configurable/exporter.go | 21 +++++----- .../exporter/configurable/exporter_test.go | 2 +- metadata/service/inmemory/service.go | 20 ++++++--- metadata/service/inmemory/service_test.go | 15 +++---- metadata/service/remote/service.go | 32 ++++++++------ metadata/service/remote/service_test.go | 8 ++-- metadata/service/service.go | 14 +++++-- .../event_publishing_service_discovery.go | 7 ++++ registry/event/log_event_listener_test.go | 1 - .../metadata_service_url_params_customizer.go | 8 ++-- .../protocol_ports_metadata_customizer.go | 3 +- .../event/service_config_exported_event.go | 15 ++++++- .../event/service_name_mapping_listener.go | 14 +++++++ registry/event/service_revision_customizer.go | 5 +-- .../service_discovery_registry.go | 35 ++++++++++++++-- .../service_discovery_registry_test.go | 4 +- 23 files changed, 196 insertions(+), 71 deletions(-) create mode 100644 common/extension/metadata_service.go diff --git a/common/extension/metadata_service.go b/common/extension/metadata_service.go new file mode 100644 index 0000000000..c6a165c487 --- /dev/null +++ b/common/extension/metadata_service.go @@ -0,0 +1,42 @@ +/* + * 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 ( + "fmt" + + "github.com/apache/dubbo-go/metadata/service" +) + +var ( + // there will be two types: local or remote + metadataServiceInsMap = make(map[string]func() (service.MetadataService, error), 2) +) + +func SetMetadataService(msType string, creator func() (service.MetadataService, error)) { + metadataServiceInsMap[msType] = creator +} + +func GetMetadataService(msType string) (service.MetadataService, error) { + if creator, ok := metadataServiceInsMap[msType]; ok { + return creator() + } + panic(fmt.Sprintf("could not find the creator for metadataType: %s, please check whether you have imported relative packages, \n"+ + "local - github.com/apache/dubbo-go/metadata/service/inmemory, \n"+ + "remote - github.com/apache/dubbo-go/metadata/service/remote", msType)) +} diff --git a/common/rpc_service_test.go b/common/rpc_service_test.go index 19a1d7b03b..2311205d0e 100644 --- a/common/rpc_service_test.go +++ b/common/rpc_service_test.go @@ -137,7 +137,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType := suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*event.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) + assert.Equal(t, "func(*common.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) at := methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -151,7 +151,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*event.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) + assert.Equal(t, "func(*common.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, "interface {}", at[0].String()) assert.Equal(t, "interface {}", at[1].String()) @@ -164,7 +164,7 @@ func TestSuiteMethod(t *testing.T) { assert.True(t, ok) methodType = suiteMethod(method) method = methodType.Method() - assert.Equal(t, "func(*event.TestService) error", method.Type.String()) + assert.Equal(t, "func(*common.TestService) error", method.Type.String()) at = methodType.ArgsType() assert.Equal(t, 0, len(at)) assert.Nil(t, methodType.CtxType()) diff --git a/config/service_config.go b/config/service_config.go index 2b1e5a1a3f..43c53bc9c2 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -44,7 +44,9 @@ import ( "github.com/apache/dubbo-go/protocol/protocolwrapper" ) -// ServiceConfig ... +// 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 type ServiceConfig struct { context context.Context id string diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 56ef2a0f0d..9f65adf739 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -21,7 +21,9 @@ import ( "strconv" "time" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" ) import ( @@ -55,7 +57,8 @@ type DynamicConfigurationServiceNameMapping struct { func (d *DynamicConfigurationServiceNameMapping) Map(serviceInterface string, group string, version string, protocol string) error { // metadata service is admin service, should not be mapped if constant.METADATA_SERVICE_NAME == serviceInterface { - return perrors.New("try to map the metadata service, will be ignored") + logger.Info("try to map the metadata service, will be ignored") + return nil } appName := config.GetApplicationConfig().Name diff --git a/metadata/mapping/dynamic/service_name_mapping_test.go b/metadata/mapping/dynamic/service_name_mapping_test.go index 647a15ae78..2896b0fd4a 100644 --- a/metadata/mapping/dynamic/service_name_mapping_test.go +++ b/metadata/mapping/dynamic/service_name_mapping_test.go @@ -48,7 +48,7 @@ func TestDynamicConfigurationServiceNameMapping(t *testing.T) { protocol := "myProtocol" err = mapping.Map(intf, group, version, protocol) - assert.NotNil(t, err) + assert.Nil(t, err) intf = "MyService" err = mapping.Map(intf, group, version, protocol) assert.Nil(t, err) diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 5eaee7bb2b..6b838187b7 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -181,7 +181,7 @@ func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) []string { func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) string { cfg, err := n.client.GetConfig(param) if err != nil { - logger.Errorf("Finding the configuration failed: %v", param) + logger.Errorf("Finding the configuration failed: %v, err: %v", param, err) } return cfg } diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 711e6281a2..f23ed8a8da 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -44,7 +44,7 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { assert.Nil(t, err) serviceMi := newServiceMetadataIdentifier() - serviceUrl, _ := common.NewURL("registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + serviceUrl, _ := common.NewURL("registry://localhost:8848", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) err = rpt.SaveServiceMetadata(serviceMi, serviceUrl) assert.Nil(t, err) diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index ec3f8ec2d0..1d134bdb3d 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -33,7 +33,7 @@ import ( // MetadataServiceExporter is the ConfigurableMetadataServiceExporter which implement MetadataServiceExporter interface type MetadataServiceExporter struct { - serviceConfig *config.ServiceConfig + ServiceConfig *config.ServiceConfig lock sync.RWMutex metadataService service.MetadataService } @@ -56,42 +56,43 @@ func (exporter *MetadataServiceExporter) Export() error { } serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME serviceConfig.Group = config.GetApplicationConfig().Name - serviceConfig.Version = exporter.metadataService.Version() + // now the error will always be nil + serviceConfig.Version, _ = exporter.metadataService.Version() var err error func() { exporter.lock.Lock() defer exporter.lock.Unlock() - exporter.serviceConfig = serviceConfig - exporter.serviceConfig.Implement(exporter.metadataService) - err = exporter.serviceConfig.Export() + exporter.ServiceConfig = serviceConfig + exporter.ServiceConfig.Implement(exporter.metadataService) + err = exporter.ServiceConfig.Export() }() - logger.Infof("The MetadataService exports urls : %v ", exporter.serviceConfig.GetExportedUrls()) + logger.Infof("The MetadataService exports urls : %v ", exporter.ServiceConfig.GetExportedUrls()) return err } - logger.Warnf("The MetadataService has been exported : %v ", exporter.serviceConfig.GetExportedUrls()) + logger.Warnf("The MetadataService has been exported : %v ", exporter.ServiceConfig.GetExportedUrls()) return nil } // Unexport will unexport the metadataService func (exporter *MetadataServiceExporter) Unexport() { if exporter.IsExported() { - exporter.serviceConfig.Unexport() + exporter.ServiceConfig.Unexport() } } // GetExportedURLs will return the urls that export use. // Notice!The exported url is not same as url in registry , for example it lack the ip. func (exporter *MetadataServiceExporter) GetExportedURLs() []*common.URL { - return exporter.serviceConfig.GetExportedUrls() + return exporter.ServiceConfig.GetExportedUrls() } // isExported will return is metadataServiceExporter exported or not func (exporter *MetadataServiceExporter) IsExported() bool { exporter.lock.RLock() defer exporter.lock.RUnlock() - return exporter.serviceConfig != nil && exporter.serviceConfig.IsExport() + return exporter.ServiceConfig != nil && exporter.ServiceConfig.IsExport() } // generateMetadataProtocol will return a default ProtocolConfig diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index 364169b317..20a80ef708 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -53,7 +53,7 @@ func TestConfigurableExporter(t *testing.T) { SessionName: "server", }}) mockInitProviderWithSingleRegistry() - metadataService := inmemory.NewMetadataService() + metadataService, _ := inmemory.NewMetadataService() exported := NewMetadataServiceExporter(metadataService) assert.Equal(t, false, exported.IsExported()) assert.NoError(t, exported.Export()) diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index f7b7466a3d..4327304ad3 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -19,6 +19,9 @@ package inmemory import ( "sort" "sync" + + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/config" ) import ( @@ -34,6 +37,10 @@ import ( "github.com/apache/dubbo-go/metadata/service" ) +func init() { + extension.SetMetadataService("local", NewMetadataService) +} + // version will be used by Version func const version = "1.0.0" @@ -47,13 +54,14 @@ type MetadataService struct { } // NewMetadataService: initiate a metadata service -func NewMetadataService() *MetadataService { +func NewMetadataService() (service.MetadataService, error) { return &MetadataService{ + BaseMetadataService: service.NewBaseMetadataService(config.GetApplicationConfig().Name), exportedServiceURLs: &sync.Map{}, subscribedServiceURLs: &sync.Map{}, serviceDefinitions: &sync.Map{}, lock: &sync.RWMutex{}, - } + }, nil } // Comparator is defined as Comparator for skip list to compare the URL @@ -228,11 +236,11 @@ func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) } // RefreshMetadata will always return true because it will be implement by remote service -func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { - return true +func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { + return true, nil } // Version will return the version of metadata service -func (mts *MetadataService) Version() string { - return version +func (mts *MetadataService) Version() (string, error) { + return version, nil } diff --git a/metadata/service/inmemory/service_test.go b/metadata/service/inmemory/service_test.go index fc0410ecca..048c286fdf 100644 --- a/metadata/service/inmemory/service_test.go +++ b/metadata/service/inmemory/service_test.go @@ -32,7 +32,7 @@ import ( ) func TestMetadataService(t *testing.T) { - mts := NewMetadataService() + mts, _ := NewMetadataService() serviceName := "com.ikurento.user.UserProvider" group := "group1" version := "0.0.1" @@ -66,25 +66,20 @@ func TestMetadataService(t *testing.T) { assert.NoError(t, err) mts.ExportURL(u) list, _ := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, uint64(3), list.Len()) - iter := list.IterAtPosition(0) - for iter.Next() { - comparator := iter.Value() - fmt.Println(comparator) - } + assert.Equal(t, 3, len(list)) mts.SubscribeURL(u) mts.SubscribeURL(u) list2, _ := mts.GetSubscribedURLs() - assert.Equal(t, uint64(1), list2.Len()) + assert.Equal(t, 1, len(list2)) mts.UnexportURL(u) list3, _ := mts.GetExportedURLs(serviceName, group, version, protocol) - assert.Equal(t, uint64(2), list3.Len()) + assert.Equal(t, 2, len(list3)) mts.UnsubscribeURL(u) list4, _ := mts.GetSubscribedURLs() - assert.Equal(t, uint64(0), list4.Len()) + assert.Equal(t, 0, len(list4)) userProvider := &definition.UserProvider{} common.ServiceMap.Register(serviceName, protocol, userProvider) diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index 6726b1000a..2e8f66444f 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -21,6 +21,8 @@ import ( "sync" "go.uber.org/atomic" + + "github.com/apache/dubbo-go/common/extension" ) import ( @@ -38,6 +40,10 @@ import ( // version will be used by Version func const version = "1.0.0" +func init() { + extension.SetMetadataService("remote", newMetadataService) +} + // MetadataService is a implement of metadata service which will delegate the remote metadata report // This is singleton type MetadataService struct { @@ -53,8 +59,8 @@ var ( metadataServiceInstance *MetadataService ) -// NewMetadataService will create a new remote MetadataService instance -func NewMetadataService() (*MetadataService, error) { +// newMetadataService will create a new remote MetadataService instance +func newMetadataService() (service.MetadataService, error) { var err error metadataServiceOnce.Do(func() { var mr *delegate.MetadataReport @@ -62,8 +68,11 @@ func NewMetadataService() (*MetadataService, error) { if err != nil { return } + // it will never return error + inms, _ := inmemory.NewMetadataService() metadataServiceInstance = &MetadataService{ - inMemoryMetadataService: inmemory.NewMetadataService(), + BaseMetadataService: service.NewBaseMetadataService(config.GetApplicationConfig().Name), + inMemoryMetadataService: inms.(*inmemory.MetadataService), delegateReport: mr, } }) @@ -140,14 +149,13 @@ func (mts *MetadataService) GetServiceDefinitionByServiceKey(serviceKey string) } // RefreshMetadata will refresh the exported & subscribed metadata to remote metadata report from the inmemory metadata service -func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) bool { - result := true +func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { if len(exportedRevision) != 0 && exportedRevision != mts.exportedRevision.Load() { mts.exportedRevision.Store(exportedRevision) urls, err := mts.inMemoryMetadataService.GetExportedURLs(constant.ANY_VALUE, "", "", "") if err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) - result = false + return false, err } logger.Infof("urls length = %v", len(urls)) for _, u := range urls { @@ -155,7 +163,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR id.Revision = mts.exportedRevision.Load() if err := mts.delegateReport.SaveServiceMetadata(id, u); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) - result = false + return false, err } } } @@ -165,7 +173,7 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR urls, err := mts.inMemoryMetadataService.GetSubscribedURLs() if err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %v+", err) - result = false + return false, err } if urls != nil && len(urls) > 0 { id := &identifier.SubscriberMetadataIdentifier{ @@ -176,14 +184,14 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR } if err := mts.delegateReport.SaveSubscribedData(id, urls); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) - result = false + return false, err } } } - return result + return true, nil } // Version will return the remote service version -func (MetadataService) Version() string { - return version +func (MetadataService) Version() (string, error) { + return version, nil } diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 308c631e41..2bf1c4c6c0 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -97,16 +97,16 @@ func TestMetadataService(t *testing.T) { "mock://127.0.0.1:20000/?sync.report=true")) assert.NoError(t, err) instance.GetMetadataReportInstance(&u) - mts, err := NewMetadataService() + mts, err := newMetadataService() assert.NoError(t, err) - mts.setInMemoryMetadataService(mockInmemoryProc(t)) + mts.(*MetadataService).setInMemoryMetadataService(mockInmemoryProc(t)) mts.RefreshMetadata("0.0.1", "0.0.1") assert.Equal(t, 1, len(serviceMetadata)) assert.Equal(t, 1, len(subscribedMetadata)) } func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { - mts := inmemory.NewMetadataService() + mts, _ := inmemory.NewMetadataService() serviceName := "com.ikurento.user.UserProvider" group := "group1" version := "0.0.1" @@ -135,5 +135,5 @@ func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { serviceKey := definition.ServiceDescriperBuild(serviceName, group, version) def2, _ := mts.GetServiceDefinitionByServiceKey(serviceKey) assert.Equal(t, expected, def2) - return mts + return mts.(*inmemory.MetadataService) } diff --git a/metadata/service/service.go b/metadata/service/service.go index af9528c68b..e05b634f8c 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -20,7 +20,6 @@ package service import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/config" ) // MetadataService is used to define meta data related behaviors @@ -50,18 +49,25 @@ type MetadataService interface { // GetServiceDefinition will get the target service info store in metadata by service key GetServiceDefinitionByServiceKey(serviceKey string) (string, error) // RefreshMetadata will refresh the metadata - RefreshMetadata(exportedRevision string, subscribedRevision string) bool + RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) // Version will return the metadata service version - Version() string + Version() (string, error) } // BaseMetadataService is used for the event logic for struct who will implement interface MetadataService type BaseMetadataService struct { + serviceName string +} + +func NewBaseMetadataService(serviceName string) BaseMetadataService { + return BaseMetadataService{ + serviceName: serviceName, + } } // ServiceName can get the service's name in meta service , which is application name func (mts *BaseMetadataService) ServiceName() (string, error) { - return config.GetApplicationConfig().Name, nil + return mts.serviceName, nil } // Version will return the version of metadata service diff --git a/registry/event/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go index 76fdf7237a..496eb9b4a5 100644 --- a/registry/event/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -20,6 +20,9 @@ package event import ( gxset "github.com/dubbogo/gost/container/set" gxpage "github.com/dubbogo/gost/page" + + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata/service" ) import ( @@ -139,3 +142,7 @@ func (epsd *EventPublishingServiceDiscovery) executeWithEvents(beforeEvent obser } return nil } + +func getMetadataService() (service.MetadataService, error) { + return extension.GetMetadataService(config.GetApplicationConfig().MetadataType) +} diff --git a/registry/event/log_event_listener_test.go b/registry/event/log_event_listener_test.go index e7c0ba0df5..f142168b65 100644 --- a/registry/event/log_event_listener_test.go +++ b/registry/event/log_event_listener_test.go @@ -26,6 +26,5 @@ import ( func TestLogEventListener(t *testing.T) { l := &logEventListener{} assert.Equal(t, 0, l.GetPriority()) - assert.Nil(t, l.GetEventType()) assert.Nil(t, l.OnEvent(&ServiceDiscoveryDestroyedEvent{})) } diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go index c9c636448c..e5ff2bc26f 100644 --- a/registry/event/metadata_service_url_params_customizer.go +++ b/registry/event/metadata_service_url_params_customizer.go @@ -26,7 +26,6 @@ import ( "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/metadata/service/remote" "github.com/apache/dubbo-go/registry" ) @@ -52,17 +51,18 @@ func (m *metadataServiceURLParamsMetadataCustomizer) GetPriority() int { } func (m *metadataServiceURLParamsMetadataCustomizer) Customize(instance registry.ServiceInstance) { - ms, err := remote.NewMetadataService() + ms, err := getMetadataService() if err != nil { logger.Errorf("could not find the metadata service", err) return } serviceName := constant.METADATA_SERVICE_NAME - version := ms.Version() + // error always is nil + version, _ := ms.Version() group := instance.GetServiceName() urls, err := ms.GetExportedURLs(serviceName, group, version, constant.ANY_VALUE) if err != nil || len(urls) == 0 { - logger.Errorf("could not find the exported urls", err) + logger.Info("could not find the exported urls", err) return } ps := m.convertToParams(urls) diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index 975463fe3e..be2e381194 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -23,7 +23,6 @@ import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" - "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" ) @@ -38,7 +37,7 @@ func (p *ProtocolPortsMetadataCustomizer) GetPriority() int { // Customize will func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceInstance) { - metadataService, err := remote.NewMetadataService() + metadataService, err := getMetadataService() if err != nil { logger.Errorf("Could not init the MetadataService", err) return diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go index 371f72d0db..c3d8eee920 100644 --- a/registry/event/service_config_exported_event.go +++ b/registry/event/service_config_exported_event.go @@ -18,11 +18,24 @@ package event import ( + "time" + "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/config" ) type ServiceConfigExportedEvent struct { observer.BaseEvent - ServiceConfig config.ServiceConfig + ServiceConfig *config.ServiceConfig +} + +func NewServiceConfigExportedEvent(serviceConfig *config.ServiceConfig) *ServiceConfigExportedEvent { + return &ServiceConfigExportedEvent{ + BaseEvent: observer.BaseEvent{ + Source:serviceConfig, + Timestamp:time.Now(), + }, + ServiceConfig: serviceConfig, + } } + diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go index 9ec7392b17..480c51cc55 100644 --- a/registry/event/service_name_mapping_listener.go +++ b/registry/event/service_name_mapping_listener.go @@ -20,6 +20,9 @@ package event import ( "reflect" + perrors "github.com/pkg/errors" + + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/metadata/mapping" @@ -43,6 +46,17 @@ func (s *serviceNameMappingListener) GetPriority() int { func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { if ex, ok := e.(*ServiceConfigExportedEvent); ok { sc := ex.ServiceConfig + urls := sc.GetExportedUrls() + + for _, u := range urls { + err := s.nameMapping.Map(u.GetParam(constant.INTERFACE_KEY, ""), + u.GetParam(constant.GROUP_KEY, ""), + u.GetParam(constant.Version, ""), + u.Protocol) + if err != nil { + return perrors.WithMessage(err, "could not map the service: "+u.String()) + } + } } return nil } diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go index 51475d06c4..f51a955810 100644 --- a/registry/event/service_revision_customizer.go +++ b/registry/event/service_revision_customizer.go @@ -26,7 +26,6 @@ import ( "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/metadata/service/remote" "github.com/apache/dubbo-go/registry" ) @@ -46,7 +45,7 @@ func (e *exportedServicesRevisionMetadataCustomizer) GetPriority() int { } func (e *exportedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { - ms, err := remote.NewMetadataService() + ms, err := getMetadataService() if err != nil { logger.Errorf("could not get metadata service", err) return @@ -74,7 +73,7 @@ func (e *subscribedServicesRevisionMetadataCustomizer) GetPriority() int { } func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { - ms, err := remote.NewMetadataService() + ms, err := getMetadataService() if err != nil { logger.Errorf("could not get metadata service", err) return diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 379578ddc6..39b2b1c28b 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -37,9 +37,10 @@ import ( "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/metadata/mapping" "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/metadata/service/exporter/configurable" "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" - registryCommon "github.com/apache/dubbo-go/registry/event" + "github.com/apache/dubbo-go/registry/event" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" @@ -72,6 +73,15 @@ type serviceDiscoveryRegistry struct { } func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { + + // the metadata service is exported in DubboBootstrap of Java Dubbo + // but I don't want to introduce similar structure because we has less logic to do + // so I codes the related logic here. + // If necessary we need to think about moving there codes to somewhere else. + + // init and expose metadata service + initMetadataService() + serviceDiscovery, err := creatServiceDiscovery(url) if err != nil { return nil, err @@ -119,7 +129,7 @@ func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { if err != nil { return nil, perrors.WithMessage(err, "Create service discovery fialed") } - return registryCommon.NewEventPublishingServiceDiscovery(originServiceDiscovery), nil + return event.NewEventPublishingServiceDiscovery(originServiceDiscovery), nil } func parseServices(literalServices string) *gxset.HashSet { @@ -176,7 +186,14 @@ func (s *serviceDiscoveryRegistry) Register(url common.URL) error { if err != nil { return perrors.WithMessage(err, "could not create servcie instance, please check your service url") } - return s.serviceDiscovery.Register(ins) + err = s.serviceDiscovery.Register(ins) + if err != nil { + return perrors.WithMessage(err, "register the service failed") + } + return s.serviceNameMapping.Map(url.GetParam(constant.INTERFACE_KEY, ""), + url.GetParam(constant.GROUP_KEY, ""), + url.GetParam(constant.Version, ""), + url.Protocol) } func createInstance(url common.URL) (registry.ServiceInstance, error) { @@ -642,5 +659,17 @@ func (icn *InstanceChangeNotify) Notify(event observer.Event) { sdr := icn.serviceDiscoveryRegistry sdr.subscribe(sdr.url, icn.notify, se.ServiceName, se.Instances) } +} +func initMetadataService() { + ms, err := extension.GetMetadataService(config.GetApplicationConfig().MetadataType) + if err != nil { + logger.Errorf("could not init metadata service", err) + } + expt := configurable.NewMetadataServiceExporter(ms) + err = expt.Export() + if err != nil { + logger.Errorf("could not export the metadata service", err) + } + extension.GetGlobalDispatcher().Dispatch(event.NewServiceConfigExportedEvent(expt.(*configurable.MetadataServiceExporter).ServiceConfig)) } diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index 4aa52f55ca..247cfd65eb 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -28,10 +28,10 @@ var ( ) func TestServiceDiscoveryRegistry_Register(t *testing.T) { - //registryURL,_:=event.NewURL("in-memory://localhost:12345", + // registryURL,_:=event.NewURL("in-memory://localhost:12345", // event.WithParamsValue("registry-type","service"), // event.WithParamsValue("subscribed-services","a, b , c,d,e ,")) - //url,_:=event.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + + // url,_:=event.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + // "?&application=" + GROUP + // "&interface=" + SERVICE_INTERFACE + // "&group=" + GROUP + From 4f382b037f92ab158d7034afdbd25f7679154398 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 6 Jun 2020 11:56:58 +0800 Subject: [PATCH 105/209] test: assert --> require to use fail now --- remoting/zookeeper/client.go | 6 ++--- remoting/zookeeper/client_test.go | 44 +++++++++++++++++-------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 9c70b0b8c0..5044d54eeb 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -302,12 +302,11 @@ func (z *ZookeeperClient) RegisterEvent(zkPath string, event *chan struct{}) { } z.Lock() + defer z.Unlock() a := z.eventRegistry[zkPath] a = append(a, event) - z.eventRegistry[zkPath] = a logger.Debugf("zkClient{%s} register event{path:%s, ptr:%p}", z.name, zkPath, event) - z.Unlock() } // UnregisterEvent ... @@ -323,8 +322,7 @@ func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) { } for i, e := range infoList { if e == event { - arr := infoList - infoList = append(arr[:i], arr[i+1:]...) + infoList = append(infoList[:i], infoList[i+1:]...) logger.Infof("zkClient{%s} unregister event{path:%s, event:%p}", z.name, zkPath, event) } } diff --git a/remoting/zookeeper/client_test.go b/remoting/zookeeper/client_test.go index 9be6c4644a..abd0badd04 100644 --- a/remoting/zookeeper/client_test.go +++ b/remoting/zookeeper/client_test.go @@ -24,7 +24,7 @@ import ( import ( "github.com/dubbogo/go-zookeeper/zk" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) import ( @@ -80,7 +80,7 @@ func verifyEventStateOrder(t *testing.T, c <-chan zk.Event, expectedStates []zk. func Test_newMockZookeeperClient(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - assert.NoError(t, err) + require.NoError(t, err) defer ts.Stop() states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") @@ -90,49 +90,53 @@ func Test_newMockZookeeperClient(t *testing.T) { } func TestCreate(t *testing.T) { - ts, z, event, _ := NewMockZookeeperClient("test", 15*time.Second) + ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) + require.NoError(t, err) defer ts.Stop() - err := z.Create("test1/test2/test3/test4") - assert.NoError(t, err) + err = z.Create("test1/test2/test3/test4") + require.NoError(t, err) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") } func TestCreateDelete(t *testing.T) { - ts, z, event, _ := NewMockZookeeperClient("test", 15*time.Second) + ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) + require.NoError(t, err) defer ts.Stop() states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") - err := z.Create("/test1/test2/test3/test4") - assert.NoError(t, err) - err2 := z.Delete("/test1/test2/test3/test4") - assert.NoError(t, err2) + err = z.Create("/test1/test2/test3/test4") + require.NoError(t, err) + err = z.Delete("/test1/test2/test3/test4") + require.NoError(t, err) //verifyEventOrder(t, event, []zk.EventType{zk.EventNodeCreated}, "event channel") } func TestRegisterTemp(t *testing.T) { - ts, z, event, _ := NewMockZookeeperClient("test", 15*time.Second) + ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) + require.NoError(t, err) defer ts.Stop() - err := z.Create("/test1/test2/test3") - assert.NoError(t, err) + err = z.Create("/test1/test2/test3") + require.NoError(t, err) tmpath, err := z.RegisterTemp("/test1/test2/test3", "test4") - assert.NoError(t, err) - assert.Equal(t, "/test1/test2/test3/test4", tmpath) + require.NoError(t, err) + require.Equal(t, "/test1/test2/test3/test4", tmpath) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") } func TestRegisterTempSeq(t *testing.T) { - ts, z, event, _ := NewMockZookeeperClient("test", 15*time.Second) + ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) + require.NoError(t, err) defer ts.Stop() - err := z.Create("/test1/test2/test3") - assert.NoError(t, err) + err = z.Create("/test1/test2/test3") + require.NoError(t, err) tmpath, err := z.RegisterTempSeq("/test1/test2/test3", []byte("test")) - assert.NoError(t, err) - assert.Equal(t, "/test1/test2/test3/0000000000", tmpath) + require.NoError(t, err) + require.Equal(t, "/test1/test2/test3/0000000000", tmpath) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") } From a7c2c8b78a7bd3954a8423f9a0b21b44429216c4 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 6 Jun 2020 14:48:32 +0800 Subject: [PATCH 106/209] add lock for event registry map to avoid concurrent read write --- remoting/zookeeper/client.go | 33 ++++++++++++++++++------------- remoting/zookeeper/client_test.go | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 5044d54eeb..7904dc74e8 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -49,14 +49,16 @@ var ( // ZookeeperClient ... type ZookeeperClient struct { - name string - ZkAddrs []string - sync.RWMutex // for conn - Conn *zk.Conn - Timeout time.Duration - exit chan struct{} - Wait sync.WaitGroup - eventRegistry map[string][]*chan struct{} + name string + ZkAddrs []string + sync.RWMutex // for conn + Conn *zk.Conn + Timeout time.Duration + exit chan struct{} + Wait sync.WaitGroup + + eventRegistry map[string][]*chan struct{} + eventRegistryLock sync.RWMutex } // StateToString ... @@ -269,7 +271,7 @@ func (z *ZookeeperClient) HandleZkEvent(session <-chan zk.Event) { return case (int)(zk.EventNodeDataChanged), (int)(zk.EventNodeChildrenChanged): logger.Infof("zkClient{%s} get zk node changed event{path:%s}", z.name, event.Path) - z.RLock() + z.eventRegistryLock.RLock() for p, a := range z.eventRegistry { if strings.HasPrefix(p, event.Path) { logger.Infof("send event{state:zk.EventNodeDataChange, Path:%s} notify event to path{%s} related listener", @@ -279,16 +281,18 @@ func (z *ZookeeperClient) HandleZkEvent(session <-chan zk.Event) { } } } - z.RUnlock() + z.eventRegistryLock.RUnlock() case (int)(zk.StateConnecting), (int)(zk.StateConnected), (int)(zk.StateHasSession): if state == (int)(zk.StateHasSession) { continue } + z.eventRegistryLock.RLock() if a, ok := z.eventRegistry[event.Path]; ok && 0 < len(a) { for _, e := range a { *e <- struct{}{} } } + z.eventRegistryLock.RUnlock() } state = (int)(event.State) } @@ -301,8 +305,8 @@ func (z *ZookeeperClient) RegisterEvent(zkPath string, event *chan struct{}) { return } - z.Lock() - defer z.Unlock() + z.eventRegistryLock.Lock() + defer z.eventRegistryLock.Unlock() a := z.eventRegistry[zkPath] a = append(a, event) z.eventRegistry[zkPath] = a @@ -314,8 +318,9 @@ func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) { if zkPath == "" { return } - z.Lock() - defer z.Unlock() + + z.eventRegistryLock.Lock() + defer z.eventRegistryLock.Unlock() infoList, ok := z.eventRegistry[zkPath] if !ok { return diff --git a/remoting/zookeeper/client_test.go b/remoting/zookeeper/client_test.go index abd0badd04..d2f231c6b0 100644 --- a/remoting/zookeeper/client_test.go +++ b/remoting/zookeeper/client_test.go @@ -111,7 +111,7 @@ func TestCreateDelete(t *testing.T) { require.NoError(t, err) err = z.Delete("/test1/test2/test3/test4") require.NoError(t, err) - //verifyEventOrder(t, event, []zk.EventType{zk.EventNodeCreated}, "event channel") + // verifyEventOrder(t, event, []zk.EventType{zk.EventNodeCreated}, "event channel") } func TestRegisterTemp(t *testing.T) { From 16b650049f2a711e7c582406c3ba96f6be25f588 Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 7 Jun 2020 22:57:39 +0800 Subject: [PATCH 107/209] it can be found by java consumer --- common/extension/event_dispatcher.go | 18 +++++++++---- common/extension/service_name_mapping.go | 8 +++--- common/observer/event_listener.go | 1 + .../mapping/dynamic/service_name_mapping.go | 20 ++++++++++++--- .../mapping/memory/service_name_mapping.go | 16 +++++++++++- metadata/report/nacos/report_test.go | 6 ----- metadata/service/inmemory/service.go | 25 +++++++++++++------ .../customizable_service_instance_listener.go | 14 ++++++++++- ...vent_publishing_service_deiscovery_test.go | 16 ++++++++++-- registry/event/log_event_listener.go | 14 ++++++++++- .../metadata_service_url_params_customizer.go | 2 +- .../event/service_config_exported_event.go | 7 +++--- .../event/service_name_mapping_listener.go | 19 +++++++++++--- registry/nacos/service_discovery.go | 10 +++++--- .../service_discovery_registry.go | 3 +-- 15 files changed, 133 insertions(+), 46 deletions(-) diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go index 2d33528259..a543910cc1 100644 --- a/common/extension/event_dispatcher.go +++ b/common/extension/event_dispatcher.go @@ -18,13 +18,16 @@ package extension import ( + "sync" + "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" ) var ( globalEventDispatcher observer.EventDispatcher - initEventListeners []observer.EventListener + initEventListeners []func() observer.EventListener + initEventOnce sync.Once ) var ( @@ -48,15 +51,20 @@ func SetAndInitGlobalDispatcher(name string) { panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") } globalEventDispatcher = dispatchers[name]() - globalEventDispatcher.AddEventListeners(initEventListeners) } -// GetGlobalDispatcher +// GetGlobalDispatcher will init all listener and then return dispatcher func GetGlobalDispatcher() observer.EventDispatcher { + initEventOnce.Do(func() { + // we should delay to add the listeners to avoid some listeners left + for _, l := range initEventListeners { + globalEventDispatcher.AddEventListener(l()) + } + }) return globalEventDispatcher } // AddEventListener it will be added in global event dispatcher -func AddEventListener(listener observer.EventListener) { - initEventListeners = append(initEventListeners, listener) +func AddEventListener(creator func() observer.EventListener) { + initEventListeners = append(initEventListeners, creator) } diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 0330b8a4d3..cd2630198e 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -20,13 +20,13 @@ package extension import "github.com/apache/dubbo-go/metadata/mapping" var ( - globalNameMapping mapping.ServiceNameMapping + globalNameMappingCreator func() mapping.ServiceNameMapping ) -func SetGlobalServiceNameMapping(nameMapping mapping.ServiceNameMapping) { - globalNameMapping = nameMapping +func SetGlobalServiceNameMapping(nameMappingCreator func() mapping.ServiceNameMapping) { + globalNameMappingCreator = nameMappingCreator } func GetGlobalServiceNameMapping() mapping.ServiceNameMapping { - return globalNameMapping + return globalNameMappingCreator() } diff --git a/common/observer/event_listener.go b/common/observer/event_listener.go index f4423d7dd7..faa8705a42 100644 --- a/common/observer/event_listener.go +++ b/common/observer/event_listener.go @@ -29,6 +29,7 @@ import ( // It contains the Prioritized means that the listener has its priority // Usually the priority of your custom implementation should be between [100, 9000] // the number outside the range will be though as system reserve number +// usually implementation should be singleton type EventListener interface { gxsort.Prioritizer // OnEvent handle this event diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 9f65adf739..9a8d8299a9 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -19,11 +19,12 @@ package dynamic 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 ( @@ -39,16 +40,16 @@ import ( ) const ( - defaultGroup = config_center.DEFAULT_GROUP + defaultGroup = "mapping" slash = "/" ) func init() { - dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() - extension.SetGlobalServiceNameMapping(&DynamicConfigurationServiceNameMapping{dc: dc}) + extension.SetGlobalServiceNameMapping(GetNameMappingInstance) } // DynamicConfigurationServiceNameMapping is the implementation based on config center +// it's a singleton type DynamicConfigurationServiceNameMapping struct { dc config_center.DynamicConfiguration } @@ -85,3 +86,14 @@ func (d *DynamicConfigurationServiceNameMapping) buildGroup(serviceInterface str // so other params are ignored and remove, including group string, version string, protocol string return defaultGroup + slash + serviceInterface } + +var serviceNameMappingInstance *DynamicConfigurationServiceNameMapping +var serviceNameMappingOnce sync.Once + +func GetNameMappingInstance() mapping.ServiceNameMapping { + serviceNameMappingOnce.Do(func() { + dc := common_cfg.GetEnvInstance().GetDynamicConfiguration() + serviceNameMappingInstance = &DynamicConfigurationServiceNameMapping{dc: dc} + }) + return serviceNameMappingInstance +} diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go index 293d97c842..ef2e5fa06c 100644 --- a/metadata/mapping/memory/service_name_mapping.go +++ b/metadata/mapping/memory/service_name_mapping.go @@ -18,7 +18,11 @@ package memory import ( + "sync" + gxset "github.com/dubbogo/gost/container/set" + + "github.com/apache/dubbo-go/metadata/mapping" ) import ( @@ -27,7 +31,7 @@ import ( ) func init() { - extension.SetGlobalServiceNameMapping(&InMemoryServiceNameMapping{}) + extension.SetGlobalServiceNameMapping(GetNameMappingInstance) } type InMemoryServiceNameMapping struct{} @@ -39,3 +43,13 @@ func (i InMemoryServiceNameMapping) Map(serviceInterface string, group string, v func (i InMemoryServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { return gxset.NewSet(config.GetApplicationConfig().Name), nil } + +var serviceNameMappingInstance *InMemoryServiceNameMapping +var serviceNameMappingOnce sync.Once + +func GetNameMappingInstance() mapping.ServiceNameMapping { + serviceNameMappingOnce.Do(func() { + serviceNameMappingInstance = &InMemoryServiceNameMapping{} + }) + return serviceNameMappingInstance +} diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index f23ed8a8da..88aec72a0b 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -49,18 +49,12 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { err = rpt.SaveServiceMetadata(serviceMi, serviceUrl) assert.Nil(t, err) - exportedUrls := rpt.GetExportedURLs(serviceMi) - assert.Equal(t, 1, len(exportedUrls)) - subMi := newSubscribeMetadataIdentifier() urlList := make([]common.URL, 0, 1) urlList = append(urlList, serviceUrl) err = rpt.SaveSubscribedData(subMi, urlList) assert.Nil(t, err) - subscribeUrl := rpt.GetSubscribedURLs(subMi) - assert.Equal(t, 1, len(subscribeUrl)) - err = rpt.RemoveServiceMetadata(serviceMi) assert.Nil(t, err) diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 4327304ad3..c9d2ed47b2 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -53,15 +53,24 @@ type MetadataService struct { lock *sync.RWMutex } +var ( + metadataServiceInstance *MetadataService + metadataServiceInitOnce sync.Once +) + // NewMetadataService: initiate a metadata service +// it should be singleton func NewMetadataService() (service.MetadataService, error) { - return &MetadataService{ - BaseMetadataService: service.NewBaseMetadataService(config.GetApplicationConfig().Name), - exportedServiceURLs: &sync.Map{}, - subscribedServiceURLs: &sync.Map{}, - serviceDefinitions: &sync.Map{}, - lock: &sync.RWMutex{}, - }, nil + metadataServiceInitOnce.Do(func() { + metadataServiceInstance = &MetadataService{ + BaseMetadataService: service.NewBaseMetadataService(config.GetApplicationConfig().Name), + exportedServiceURLs: &sync.Map{}, + subscribedServiceURLs: &sync.Map{}, + serviceDefinitions: &sync.Map{}, + lock: &sync.RWMutex{}, + } + }) + return metadataServiceInstance, nil } // Comparator is defined as Comparator for skip list to compare the URL @@ -149,7 +158,7 @@ func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey s urls := serviceList.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) - if len(protocol) == 0 || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { + if len(protocol) == 0 || protocol == constant.ANY_VALUE || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol { res = append(res, url) } } diff --git a/registry/event/customizable_service_instance_listener.go b/registry/event/customizable_service_instance_listener.go index cd4a8d2db6..89d1621974 100644 --- a/registry/event/customizable_service_instance_listener.go +++ b/registry/event/customizable_service_instance_listener.go @@ -19,15 +19,17 @@ package event import ( "reflect" + "sync" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" ) func init() { - extension.AddEventListener(&customizableServiceInstanceListener{}) + extension.AddEventListener(GetCustomizableServiceInstanceListener) } +// customizableServiceInstanceListener is singleton type customizableServiceInstanceListener struct { } @@ -53,3 +55,13 @@ func (c *customizableServiceInstanceListener) OnEvent(e observer.Event) error { func (c *customizableServiceInstanceListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancePreRegisteredEvent{}) } + +var customizableServiceInstanceListenerInstance *customizableServiceInstanceListener +var customizableServiceInstanceListenerOnce sync.Once + +func GetCustomizableServiceInstanceListener() observer.EventListener { + customizableServiceInstanceListenerOnce.Do(func() { + customizableServiceInstanceListenerInstance = &customizableServiceInstanceListener{} + }) + return customizableServiceInstanceListenerInstance +} diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index 27d2482d06..ea6a97a322 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -20,6 +20,9 @@ package event import ( "reflect" "testing" + + "github.com/apache/dubbo-go/config" + _ "github.com/apache/dubbo-go/metadata/service/inmemory" ) import ( @@ -37,13 +40,22 @@ import ( ) func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { + + // extension.SetMetadataService("local", inmemory.NewMetadataService) + + config.GetApplicationConfig().MetadataType = "local" + dc := NewEventPublishingServiceDiscovery(&ServiceDiscoveryA{}) tsd := &TestServiceDiscoveryDestroyingEventListener{} tsd.SetT(t) tsi := &TestServiceInstancePreRegisteredEventListener{} tsi.SetT(t) - extension.AddEventListener(tsd) - extension.AddEventListener(tsi) + extension.AddEventListener(func() observer.EventListener { + return tsd + }) + extension.AddEventListener(func() observer.EventListener { + return tsi + }) extension.SetEventDispatcher("direct", dispatcher2.NewDirectEventDispatcher) extension.SetAndInitGlobalDispatcher("direct") err := dc.Destroy() diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go index c52b02a785..a06d5e4499 100644 --- a/registry/event/log_event_listener.go +++ b/registry/event/log_event_listener.go @@ -19,6 +19,7 @@ package event import ( "reflect" + "sync" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" @@ -26,9 +27,10 @@ import ( ) func init() { - extension.AddEventListener(&logEventListener{}) + extension.AddEventListener(GetLogEventListener) } +// logEventListener is singleton type logEventListener struct { } @@ -44,3 +46,13 @@ func (l *logEventListener) OnEvent(e observer.Event) error { func (l *logEventListener) GetEventType() reflect.Type { return reflect.TypeOf(&observer.BaseEvent{}) } + +var logEventListenerInstance *logEventListener +var logEventListenerOnce sync.Once + +func GetLogEventListener() observer.EventListener { + logEventListenerOnce.Do(func() { + logEventListenerInstance = &logEventListener{} + }) + return logEventListenerInstance +} diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go index e5ff2bc26f..811d9308ee 100644 --- a/registry/event/metadata_service_url_params_customizer.go +++ b/registry/event/metadata_service_url_params_customizer.go @@ -84,7 +84,7 @@ func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []comm p := make(map[string]string, len(u.GetParams())) for k, v := range u.GetParams() { // we will ignore that - if m.exceptKeys.Contains(k) || len(v) == 0 { + if m.exceptKeys.Contains(k) || len(v) == 0 || len(v[0]) == 0 { continue } p[k] = v[0] diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go index c3d8eee920..7946609acd 100644 --- a/registry/event/service_config_exported_event.go +++ b/registry/event/service_config_exported_event.go @@ -31,11 +31,10 @@ type ServiceConfigExportedEvent struct { func NewServiceConfigExportedEvent(serviceConfig *config.ServiceConfig) *ServiceConfigExportedEvent { return &ServiceConfigExportedEvent{ - BaseEvent: observer.BaseEvent{ - Source:serviceConfig, - Timestamp:time.Now(), + BaseEvent: observer.BaseEvent{ + Source: serviceConfig, + Timestamp: time.Now(), }, ServiceConfig: serviceConfig, } } - diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go index 480c51cc55..68cf588c66 100644 --- a/registry/event/service_name_mapping_listener.go +++ b/registry/event/service_name_mapping_listener.go @@ -19,6 +19,7 @@ package event import ( "reflect" + "sync" perrors "github.com/pkg/errors" @@ -29,9 +30,7 @@ import ( ) func init() { - extension.AddEventListener(&serviceNameMappingListener{ - nameMapping: extension.GetGlobalServiceNameMapping(), - }) + extension.AddEventListener(GetCustomizableServiceInstanceListener) } type serviceNameMappingListener struct { @@ -64,3 +63,17 @@ func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { func (s *serviceNameMappingListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceConfigExportedEvent{}) } + +var ( + serviceNameMappingListenerInstance *serviceNameMappingListener + serviceNameMappingListenerOnce sync.Once +) + +func GetServiceNameMappingListener() observer.EventListener { + serviceNameMappingListenerOnce.Do(func() { + serviceNameMappingListenerInstance = &serviceNameMappingListener{ + nameMapping: extension.GetGlobalServiceNameMapping(), + } + }) + return serviceNameMappingListenerInstance +} diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 6b1d3c23d1..5b952e2541 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -264,10 +264,12 @@ func (n *nacosServiceDiscovery) toRegisterInstance(instance registry.ServiceInst Ip: instance.GetHost(), Port: uint64(instance.GetPort()), Metadata: metadata, - Enable: instance.IsEnable(), - Healthy: instance.IsHealthy(), - GroupName: n.group, - Ephemeral: true, + // We must specify the weight since Java nacos client will ignore the instance whose weight is 0 + Weight: 1, + Enable: instance.IsEnable(), + Healthy: instance.IsHealthy(), + GroupName: n.group, + Ephemeral: true, } } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 39b2b1c28b..aad4b26416 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -38,7 +38,6 @@ import ( "github.com/apache/dubbo-go/metadata/mapping" "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/exporter/configurable" - "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/event" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" @@ -89,7 +88,7 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { subscribedServices := parseServices(url.GetParam(constant.SUBSCRIBED_SERVICE_NAMES_KEY, "")) subscribedURLsSynthesizers := synthesizer.GetAllSynthesizer() serviceNameMapping := extension.GetGlobalServiceNameMapping() - metaDataService, err := remote.NewMetadataService() + metaDataService, err := extension.GetMetadataService(config.GetApplicationConfig().MetadataType) if err != nil { return nil, perrors.WithMessage(err, "could not init metadata service") } From 066dcdd45bb107cf1af54db627c74e7e60e29a24 Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 8 Jun 2020 23:59:31 +0800 Subject: [PATCH 108/209] Add metadata service factory --- common/constant/default.go | 1 + common/extension/metadata_service.go | 2 +- .../metadata_service_proxy_factory.go | 41 +++++ config/base_config.go | 4 + config/config_loader.go | 10 +- config/consumer_config.go | 2 - config/provider_config.go | 2 - config/reference_config.go | 2 + config_center/nacos/impl.go | 2 +- .../metadata_service_proxy_factory.go | 35 ++++ metadata/service/inmemory/service.go | 11 +- .../remote/metadata_service_proxy_factory.go | 30 ++++ metadata/service/remote/service.go | 7 +- metadata/service/remote/service_proxy.go | 153 ++++++++++++++++++ metadata/service/service.go | 34 ++++ .../proxy/metadata_service_proxy_factory.go | 14 +- .../servicediscovery/proxy/service_proxy.go | 11 -- .../service_discovery_registry.go | 14 +- 18 files changed, 333 insertions(+), 42 deletions(-) create mode 100644 common/extension/metadata_service_proxy_factory.go create mode 100644 metadata/service/inmemory/metadata_service_proxy_factory.go create mode 100644 metadata/service/remote/metadata_service_proxy_factory.go create mode 100644 metadata/service/remote/service_proxy.go diff --git a/common/constant/default.go b/common/constant/default.go index 211bfc06bd..45fc38f13e 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -77,6 +77,7 @@ const ( const ( SIMPLE_METADATA_SERVICE_NAME = "MetadataService" + DEFAULT_REVIESION = "N/A" ) const ( diff --git a/common/extension/metadata_service.go b/common/extension/metadata_service.go index c6a165c487..93ff40aa76 100644 --- a/common/extension/metadata_service.go +++ b/common/extension/metadata_service.go @@ -36,7 +36,7 @@ func GetMetadataService(msType string) (service.MetadataService, error) { if creator, ok := metadataServiceInsMap[msType]; ok { return creator() } - panic(fmt.Sprintf("could not find the creator for metadataType: %s, please check whether you have imported relative packages, \n"+ + panic(fmt.Sprintf("could not find the metadata service creator for metadataType: %s, please check whether you have imported relative packages, \n"+ "local - github.com/apache/dubbo-go/metadata/service/inmemory, \n"+ "remote - github.com/apache/dubbo-go/metadata/service/remote", msType)) } diff --git a/common/extension/metadata_service_proxy_factory.go b/common/extension/metadata_service_proxy_factory.go new file mode 100644 index 0000000000..35f63c5fa9 --- /dev/null +++ b/common/extension/metadata_service_proxy_factory.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 extension + +import ( + "fmt" + + "github.com/apache/dubbo-go/metadata/service" +) + +var ( + metadataServiceProxyFactoryMap = make(map[string]func() service.MetadataServiceProxyFactory) +) + +func SetMetadataServiceProxyFactory(name string, creator func() service.MetadataServiceProxyFactory) { + metadataServiceProxyFactoryMap[name] = creator +} + +func GetMetadataServiceProxyFactory(name string) service.MetadataServiceProxyFactory { + if f, ok := metadataServiceProxyFactoryMap[name]; ok { + return f() + } + panic(fmt.Sprintf("could not find the metadata service factory creator for name: %s, please check whether you have imported relative packages, \n"+ + "local - github.com/apache/dubbo-go/metadata/service/inmemory, \n"+ + "remote - github.com/apache/dubbo-go/metadata/service/remote", name)) +} diff --git a/config/base_config.go b/config/base_config.go index dad4d7f7ef..f04a09f498 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -45,6 +45,10 @@ type BaseConfig struct { ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` Remotes map[string]*RemoteConfig `yaml:"remote" json:"remote,omitempty"` ServiceDiscoveries map[string]*ServiceDiscoveryConfig `yaml:"service_discovery" json:"service_discovery,omitempty"` + + Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` + Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` + // application config ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"` diff --git a/config/config_loader.go b/config/config_loader.go index 4a293e7a9f..7d279ff083 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -148,7 +148,7 @@ func loadConsumerConfig() { if count > maxWait { errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) logger.Error(errMsg) - panic(errMsg) + // panic(errMsg) } time.Sleep(time.Second * 1) break @@ -222,13 +222,11 @@ func Load() { extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) // start the metadata report if config set - if err := startMetadataReport(providerConfig.ApplicationConfig.MetadataType, providerConfig.MetadataReportConfig); err != nil { + if err := startMetadataReport(GetApplicationConfig().MetadataType, GetProviderConfig().MetadataReportConfig); err != nil { logger.Errorf("Provider starts metadata report error, and the error is {%#v}", err) return } - logger.Debugf("provider config{%#v}\n", providerConfig) - // reference config loadConsumerConfig() @@ -323,3 +321,7 @@ func GetBaseConfig() *BaseConfig { } return baseConfig } + +func IsProvider() bool { + return providerConfig != nil +} diff --git a/config/consumer_config.go b/config/consumer_config.go index bee9b1e3fc..fd3d30e6fc 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -51,8 +51,6 @@ type ConsumerConfig struct { ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` Check *bool `yaml:"check" json:"check,omitempty" property:"check"` - Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"` ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"` FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" ` diff --git a/config/provider_config.go b/config/provider_config.go index 0f14c9f1d3..99c532a383 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -42,8 +42,6 @@ type ProviderConfig struct { ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` // metadata-report MetadataReportConfig *MetadataReportConfig `yaml:"metadata_report" json:"metadata_report,omitempty" property:"metadata_report"` - Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"` ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" ` diff --git a/config/reference_config.go b/config/reference_config.go index f343a9a236..e935c7646d 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -55,6 +55,7 @@ type ReferenceConfig struct { Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` Group string `yaml:"group" json:"group,omitempty" property:"group"` Version string `yaml:"version" json:"version,omitempty" property:"version"` + ProvideBy string `yaml:"provide_by" json:"provide_by,omitempty" property:"provide_by"` Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` Async bool `yaml:"async" json:"async,omitempty" property:"async"` Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` @@ -190,6 +191,7 @@ func (c *ReferenceConfig) getUrlMap() url.Values { urlMap.Set(constant.VERSION_KEY, c.Version) urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(c.Generic)) urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)) + urlMap.Set(constant.PROVIDER_BY, c.ProvideBy) urlMap.Set(constant.RELEASE_KEY, "dubbo-golang-"+constant.Version) urlMap.Set(constant.SIDE_KEY, (common.RoleType(common.CONSUMER)).Role()) diff --git a/config_center/nacos/impl.go b/config_center/nacos/impl.go index 0b8aceb23c..b4a7a54679 100644 --- a/config_center/nacos/impl.go +++ b/config_center/nacos/impl.go @@ -125,7 +125,7 @@ func (n *nacosDynamicConfiguration) GetConfigKeysByGroup(group string) (*gxset.H return result, perrors.WithMessage(err, "can not find the client config") } for _, itm := range page.PageItems { - result.Add(itm.Content) + result.Add(itm.Appname) } return result, nil } diff --git a/metadata/service/inmemory/metadata_service_proxy_factory.go b/metadata/service/inmemory/metadata_service_proxy_factory.go new file mode 100644 index 0000000000..813ed75136 --- /dev/null +++ b/metadata/service/inmemory/metadata_service_proxy_factory.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 inmemory + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" +) + +func init() { + factory := service.NewBaseMetadataServiceProxyFactory(createProxy) + extension.SetMetadataServiceProxyFactory(local, func() service.MetadataServiceProxyFactory { + return factory + }) +} + +func createProxy(ins registry.ServiceInstance) service.MetadataService { + return nil +} diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index c9d2ed47b2..b0782fa3de 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -37,13 +37,16 @@ import ( "github.com/apache/dubbo-go/metadata/service" ) +// version will be used by Version func +const ( + version = "1.0.0" + local = "local" +) + func init() { - extension.SetMetadataService("local", NewMetadataService) + extension.SetMetadataService(local, NewMetadataService) } -// version will be used by Version func -const version = "1.0.0" - // MetadataService is store and query the metadata info in memory when each service registry type MetadataService struct { service.BaseMetadataService diff --git a/metadata/service/remote/metadata_service_proxy_factory.go b/metadata/service/remote/metadata_service_proxy_factory.go new file mode 100644 index 0000000000..a1a8594282 --- /dev/null +++ b/metadata/service/remote/metadata_service_proxy_factory.go @@ -0,0 +1,30 @@ +/* + * 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 remote + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/metadata/service" +) + +func init() { + factory := service.NewBaseMetadataServiceProxyFactory(newMetadataServiceProxy) + extension.SetMetadataServiceProxyFactory(remote, func() service.MetadataServiceProxyFactory { + return factory + }) +} diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index 2e8f66444f..19f0c021d3 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -38,10 +38,13 @@ import ( ) // version will be used by Version func -const version = "1.0.0" +const ( + version = "1.0.0" + remote = "remote" +) func init() { - extension.SetMetadataService("remote", newMetadataService) + extension.SetMetadataService(remote, newMetadataService) } // MetadataService is a implement of metadata service which will delegate the remote metadata report diff --git a/metadata/service/remote/service_proxy.go b/metadata/service/remote/service_proxy.go new file mode 100644 index 0000000000..090e8edc3d --- /dev/null +++ b/metadata/service/remote/service_proxy.go @@ -0,0 +1,153 @@ +/* + * 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 remote + +import ( + "strings" + + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/config/instance" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" +) + +type metadataServiceProxy struct { + serviceName string + revision string + report report.MetadataReport +} + +func (m *metadataServiceProxy) Reference() string { + return constant.METADATA_SERVICE_NAME +} + +func (m *metadataServiceProxy) ServiceName() (string, error) { + return m.serviceName, nil +} + +func (m *metadataServiceProxy) ExportURL(url common.URL) (bool, error) { + logger.Errorf("you should never invoke this implementation") + return true, nil +} + +func (m *metadataServiceProxy) UnexportURL(url common.URL) error { + logger.Errorf("you should never invoke this implementation") + return nil +} + +func (m *metadataServiceProxy) SubscribeURL(url common.URL) (bool, error) { + logger.Errorf("you should never invoke this implementation") + return true, nil +} + +func (m *metadataServiceProxy) UnsubscribeURL(url common.URL) error { + logger.Errorf("you should never invoke this implementation") + return nil +} + +func (m *metadataServiceProxy) PublishServiceDefinition(url common.URL) error { + logger.Errorf("you should never invoke this implementation") + return nil +} + +func (m *metadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { + urls := m.report.GetExportedURLs(&identifier.ServiceMetadataIdentifier{ + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: serviceInterface, + Version: version, + Group: group, + Side: constant.PROVIDER_PROTOCOL, + }, + Revision: m.revision, + Protocol: protocol, + }) + res := make([]common.URL, 0, len(urls)) + for _, s := range urls { + u, err := common.NewURL(s) + if err != nil { + logger.Errorf("could not parse the url string to URL structure", err) + continue + } + res = append(res, u) + } + return res, nil +} + +func (m *metadataServiceProxy) GetSubscribedURLs() ([]common.URL, error) { + logger.Errorf("you should never invoke this implementation") + return []common.URL{}, nil +} + +func (m *metadataServiceProxy) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + return m.report.GetServiceDefinition(&identifier.MetadataIdentifier{ + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: interfaceName, + Group: group, + Version: version, + Side: constant.PROVIDER_PROTOCOL, + }, + Application: m.serviceName, + }), nil +} + +func (m *metadataServiceProxy) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + params := parse(serviceKey) + return m.GetServiceDefinition(params[0], params[1], params[2]) +} + +func (m *metadataServiceProxy) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { + logger.Errorf("you should never invoke this implementation") + return true, nil +} + +func (m metadataServiceProxy) Version() (string, error) { + return version, nil +} + +func newMetadataServiceProxy(ins registry.ServiceInstance) service.MetadataService { + revision := ins.GetMetadata()[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] + if len(revision) == 0 { + revision = constant.DEFAULT_REVIESION + } + + return &metadataServiceProxy{ + serviceName: ins.GetServiceName(), + revision: revision, + report: instance.GetMetadataReportInstance(), + } +} + +func parse(key string) []string { + arr := make([]string, 0, 3) + tmp := strings.SplitN(key, "/", 2) + if len(tmp) > 1 { + arr[0] = tmp[0] + key = tmp[1] + } + tmp = strings.SplitN(key, "/", 2) + if len(tmp) > 1 { + arr[2] = tmp[1] + key = tmp[0] + } + arr[1] = key + return arr +} diff --git a/metadata/service/service.go b/metadata/service/service.go index e05b634f8c..fc76eca68f 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -18,8 +18,11 @@ package service import ( + "sync" + "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/registry" ) // MetadataService is used to define meta data related behaviors @@ -74,3 +77,34 @@ func (mts *BaseMetadataService) ServiceName() (string, error) { func (mts *BaseMetadataService) Reference() string { return constant.SIMPLE_METADATA_SERVICE_NAME } + +type MetadataServiceProxyFactory interface { + GetProxy(ins registry.ServiceInstance) MetadataService +} + +type MetadataServiceProxyCreator func(ins registry.ServiceInstance) MetadataService + +type BaseMetadataServiceProxyFactory struct { + proxies sync.Map + creator MetadataServiceProxyCreator +} + +func NewBaseMetadataServiceProxyFactory(creator MetadataServiceProxyCreator) *BaseMetadataServiceProxyFactory { + return &BaseMetadataServiceProxyFactory{ + creator: creator, + } +} + +func (b *BaseMetadataServiceProxyFactory) GetProxy(ins registry.ServiceInstance) MetadataService { + key := ins.GetServiceName() + "##" + getExportedServicesRevision(ins) + if proxy, ok := b.proxies.Load(key); ok { + return proxy.(MetadataService) + } + v, _ := b.proxies.LoadOrStore(key, b.creator(ins)) + return v.(MetadataService) +} + +func getExportedServicesRevision(serviceInstance registry.ServiceInstance) string { + metaData := serviceInstance.GetMetadata() + return metaData[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] +} diff --git a/registry/servicediscovery/proxy/metadata_service_proxy_factory.go b/registry/servicediscovery/proxy/metadata_service_proxy_factory.go index 7e8d891bf3..6851f4bb7c 100644 --- a/registry/servicediscovery/proxy/metadata_service_proxy_factory.go +++ b/registry/servicediscovery/proxy/metadata_service_proxy_factory.go @@ -17,15 +17,7 @@ package proxy -var ( - serviceProxy = make(map[string]func() BaseMetadataServiceProxy) +import ( + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" ) - -func SetMetadataServiceProxy(name string, creator func() BaseMetadataServiceProxy) { - //TODO -} - -func GetMetadataServiceProxy(name string) BaseMetadataServiceProxy { - //TODO - return nil -} diff --git a/registry/servicediscovery/proxy/service_proxy.go b/registry/servicediscovery/proxy/service_proxy.go index 7a14201fdd..6555874dd6 100644 --- a/registry/servicediscovery/proxy/service_proxy.go +++ b/registry/servicediscovery/proxy/service_proxy.go @@ -16,14 +16,3 @@ */ package proxy - -import ( - "github.com/apache/dubbo-go/metadata/service" - "github.com/apache/dubbo-go/registry" -) - -type BaseMetadataServiceProxy interface { - GetProxy(serviceInstance registry.ServiceInstance) service.MetadataService - - CreateProxy(serviceInstance registry.ServiceInstance) service.MetadataService -} diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index aad4b26416..133827d5eb 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -40,7 +40,6 @@ import ( "github.com/apache/dubbo-go/metadata/service/exporter/configurable" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/registry/event" - "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" ) @@ -407,11 +406,11 @@ func (c comparator) Compare(comp cm.Comparator) int { func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registry.ServiceInstance) []common.URL { var urls []common.URL metadataStorageType := getExportedStoreType(serviceInstance) - metadataProxy := proxy.GetMetadataServiceProxy(metadataStorageType) - if metadataProxy == nil { + proxyFactory := extension.GetMetadataServiceProxyFactory(metadataStorageType) + if proxyFactory == nil { return urls } - metadataService := metadataProxy.GetProxy(serviceInstance) + metadataService := proxyFactory.GetProxy(serviceInstance) if metadataService == nil { return urls } @@ -665,7 +664,14 @@ func initMetadataService() { if err != nil { logger.Errorf("could not init metadata service", err) } + + // we don't need to expose the metadata service since this is a pure consumer application + if !config.IsProvider() { + return + } + expt := configurable.NewMetadataServiceExporter(ms) + err = expt.Export() if err != nil { logger.Errorf("could not export the metadata service", err) From 9d5d9e3b32b6f20bd1bdbaaa90c650dce919daac Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 10 Jun 2020 22:53:23 +0800 Subject: [PATCH 109/209] Invoke dubbo client success --- config/config_loader.go | 2 +- .../metadata_service_proxy_factory.go | 56 +++++++- .../metadata_service_proxy_factory_test.go | 15 ++- metadata/service/inmemory/service_proxy.go | 122 ++++++++++++++++++ protocol/dubbo/client.go | 2 +- .../servicediscovery/proxy/service_proxy.go | 18 --- .../service_discovery_registry.go | 8 +- 7 files changed, 197 insertions(+), 26 deletions(-) rename registry/servicediscovery/proxy/metadata_service_proxy_factory.go => metadata/service/inmemory/metadata_service_proxy_factory_test.go (68%) create mode 100644 metadata/service/inmemory/service_proxy.go delete mode 100644 registry/servicediscovery/proxy/service_proxy.go diff --git a/config/config_loader.go b/config/config_loader.go index 7d279ff083..049687924a 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -148,7 +148,7 @@ func loadConsumerConfig() { if count > maxWait { errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) logger.Error(errMsg) - // panic(errMsg) + panic(errMsg) } time.Sleep(time.Second * 1) break diff --git a/metadata/service/inmemory/metadata_service_proxy_factory.go b/metadata/service/inmemory/metadata_service_proxy_factory.go index 813ed75136..de30d1b089 100644 --- a/metadata/service/inmemory/metadata_service_proxy_factory.go +++ b/metadata/service/inmemory/metadata_service_proxy_factory.go @@ -18,7 +18,12 @@ package inmemory import ( + "encoding/json" + + "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/metadata/service" "github.com/apache/dubbo-go/registry" ) @@ -31,5 +36,54 @@ func init() { } func createProxy(ins registry.ServiceInstance) service.MetadataService { - return nil + urls := buildStandardMetadataServiceURL(ins) + if len(urls) == 0 { + logger.Errorf("metadata service urls not found, %v", ins) + return nil + } + p := extension.GetProtocol(urls[0].Protocol) + invoker := p.Refer(*urls[0]) + 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)) + sn := ins.GetServiceName() + host := ins.GetHost() + for protocol, params := range ps { + + convertedParams := make(map[string][]string, len(params)) + for k, v := range params { + convertedParams[k] = []string{v} + } + + u := common.NewURLWithOptions(common.WithIp(host), + common.WithPath(constant.METADATA_SERVICE_NAME), + common.WithProtocol(protocol), + common.WithPort(params[constant.PORT_KEY]), + common.WithParams(convertedParams), + common.WithParamsValue(constant.GROUP_KEY, sn)) + 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]map[string]string { + ps := ins.GetMetadata() + res := make(map[string]map[string]string, 2) + if str, ok := ps[constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME]; 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 } diff --git a/registry/servicediscovery/proxy/metadata_service_proxy_factory.go b/metadata/service/inmemory/metadata_service_proxy_factory_test.go similarity index 68% rename from registry/servicediscovery/proxy/metadata_service_proxy_factory.go rename to metadata/service/inmemory/metadata_service_proxy_factory_test.go index 6851f4bb7c..652169ab78 100644 --- a/registry/servicediscovery/proxy/metadata_service_proxy_factory.go +++ b/metadata/service/inmemory/metadata_service_proxy_factory_test.go @@ -15,9 +15,18 @@ * limitations under the License. */ -package proxy +package inmemory import ( - "github.com/apache/dubbo-go/metadata/service" - "github.com/apache/dubbo-go/registry" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" ) + +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) +} diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go new file mode 100644 index 0000000000..bbe4b11017 --- /dev/null +++ b/metadata/service/inmemory/service_proxy.go @@ -0,0 +1,122 @@ +/* + * 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 inmemory + +import ( + "context" + "reflect" + + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/invocation" +) + +type MetadataServiceProxy struct { + invkr protocol.Invoker +} + +func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { + + siV := reflect.ValueOf(serviceInterface) + gV := reflect.ValueOf(group) + vV := reflect.ValueOf(version) + pV := reflect.ValueOf(protocol) + + inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getExportedURLs"), + invocation.WithArguments([]interface{}{siV.Interface(), gV.Interface(), vV.Interface(), pV.Interface()}), + invocation.WithReply(reflect.ValueOf(&[]interface{}{}).Interface()), + invocation.WithAttachments(map[string]string{constant.ASYNC_KEY: "false"}), + invocation.WithParameterValues([]reflect.Value{siV, gV, vV, pV})) + + res := m.invkr.Invoke(context.Background(), inv) + if res.Error() != nil { + logger.Errorf("could not get the metadata service from remote provider: %v", res.Error()) + } + + urlStrs := res.Result().(*[]interface{}) + + ret := make([]common.URL, 0, len(*urlStrs)) + + for _, s := range *urlStrs { + u, err := common.NewURL(s.(string)) + if err != nil { + logger.Errorf("could not convert the string to URL: %s", s) + continue + } + ret = append(ret, u) + } + return ret, nil +} + +func (m *MetadataServiceProxy) Reference() string { + panic("implement me") +} + +func (m *MetadataServiceProxy) ServiceName() (string, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) ExportURL(url common.URL) (bool, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) UnexportURL(url common.URL) error { + panic("implement me") +} + +func (m *MetadataServiceProxy) SubscribeURL(url common.URL) (bool, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) UnsubscribeURL(url common.URL) error { + panic("implement me") +} + +func (m *MetadataServiceProxy) PublishServiceDefinition(url common.URL) error { + panic("implement me") +} + +func (m *MetadataServiceProxy) GetSubscribedURLs() ([]common.URL, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { + panic("implement me") +} + +func (m *MetadataServiceProxy) Version() (string, error) { + panic("implement me") +} + +type MetadataServiceStub struct { + GetExportedURLs func(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) +} + +func (m *MetadataServiceStub) Reference() string { + return constant.METADATA_SERVICE_NAME +} diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index e6ffa64d80..08b09590e9 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -280,7 +280,7 @@ func (c *Client) call(ct CallType, request *Request, response *Response, callbac } select { - case <-getty.GetTimeWheel().After(c.opts.RequestTimeout): + case <-getty.GetTimeWheel().After(3 * time.Second): c.removePendingResponse(SequenceType(rsp.seq)) return perrors.WithStack(errClientReadTimeout) case <-rsp.done: diff --git a/registry/servicediscovery/proxy/service_proxy.go b/registry/servicediscovery/proxy/service_proxy.go deleted file mode 100644 index 6555874dd6..0000000000 --- a/registry/servicediscovery/proxy/service_proxy.go +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 proxy diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 133827d5eb..526603bf1c 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -501,6 +501,10 @@ func (s *serviceDiscoveryRegistry) initRevisionExportedURLsByInst(serviceInstanc serviceName := serviceInstance.GetServiceName() revision := getExportedServicesRevision(serviceInstance) revisionExportedURLsMap := s.serviceRevisionExportedURLsCache[serviceName] + if revisionExportedURLsMap == nil { + revisionExportedURLsMap = make(map[string][]common.URL) + s.serviceRevisionExportedURLsCache[serviceName] = revisionExportedURLsMap + } revisionExportedURLs := revisionExportedURLsMap[revision] firstGet := false if revisionExportedURLs == nil || len(revisionExportedURLs) == 0 { @@ -558,8 +562,8 @@ func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsa for _, u := range templateExportURLs { port := strconv.Itoa(getProtocolPort(serviceInstance, u.Protocol)) if u.Location != host || u.Port != port { - u.Port = port // reset port - u.Location = host // reset host + u.Port = port // reset port + u.Location = host + ":" + port // reset host } cloneUrl := u.CloneExceptParams(removeParamSet) From c6e8b0c60c37c94e40a6a860ff595c8a646cd1b2 Mon Sep 17 00:00:00 2001 From: flycash Date: Sat, 13 Jun 2020 15:04:44 +0800 Subject: [PATCH 110/209] Fix BUG --- common/constant/key.go | 2 + common/rpc_service.go | 4 + config/config_loader.go | 1 + .../service/exporter/configurable/exporter.go | 2 + .../metadata_service_proxy_factory.go | 11 ++- metadata/service/inmemory/service.go | 8 +- metadata/service/inmemory/service_proxy.go | 77 +++++++++++++------ metadata/service/remote/service.go | 7 +- metadata/service/remote/service_proxy.go | 18 ++--- metadata/service/service.go | 15 +++- .../metadata_service_url_params_customizer.go | 5 +- .../protocol_ports_metadata_customizer.go | 4 +- registry/event/service_revision_customizer.go | 8 +- .../service_discovery_registry.go | 28 +++---- 14 files changed, 127 insertions(+), 63 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index f57dcdb77d..9b00d021b7 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -277,4 +277,6 @@ const ( // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" + LANGUAGE_KEY = "language" + GO_LANG = "golang" ) diff --git a/common/rpc_service.go b/common/rpc_service.go index 2eeb52bdfb..1127e6c018 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -343,6 +343,10 @@ func suiteMethod(method reflect.Method) *MethodType { argsType []reflect.Type ) + if mname == "Reference" { + return nil + } + if outNum != 1 && outNum != 2 { logger.Warnf("method %s of mtype %v has wrong number of in out parameters %d; needs exactly 1/2", mname, mtype.String(), outNum) diff --git a/config/config_loader.go b/config/config_loader.go index 049687924a..90eb354cf5 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -189,6 +189,7 @@ func loadProviderConfig() { logger.Errorf("[provider config center refresh] %#v", err) } checkRegistries(providerConfig.Registries, providerConfig.Registry) + for key, svs := range providerConfig.Services { rpcService := GetProviderService(key) if rpcService == nil { diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index 1d134bdb3d..e43fdda886 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -55,6 +55,8 @@ func (exporter *MetadataServiceExporter) Export() error { constant.DEFAULT_PROTOCOL: generateMetadataProtocol(), } serviceConfig.InterfaceName = constant.METADATA_SERVICE_NAME + // identify this is a golang server + serviceConfig.Params = map[string]string{constant.LANGUAGE_KEY: constant.GO_LANG} serviceConfig.Group = config.GetApplicationConfig().Name // now the error will always be nil serviceConfig.Version, _ = exporter.metadataService.Version() diff --git a/metadata/service/inmemory/metadata_service_proxy_factory.go b/metadata/service/inmemory/metadata_service_proxy_factory.go index de30d1b089..0afadca8e8 100644 --- a/metadata/service/inmemory/metadata_service_proxy_factory.go +++ b/metadata/service/inmemory/metadata_service_proxy_factory.go @@ -41,9 +41,14 @@ func createProxy(ins registry.ServiceInstance) service.MetadataService { logger.Errorf("metadata service urls not found, %v", ins) return nil } - p := extension.GetProtocol(urls[0].Protocol) - invoker := p.Refer(*urls[0]) - return &MetadataServiceProxy{invkr: invoker} + + 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, + } } // buildStandardMetadataServiceURL will use standard format to build the metadata service url. diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index b0782fa3de..ec626f7f43 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -143,7 +143,7 @@ func (mts *MetadataService) getAllService(services *sync.Map) []common.URL { urls := value.(*skip.SkipList) for i := uint64(0); i < urls.Len(); i++ { url := common.URL(urls.ByPosition(i).(Comparator)) - if url.GetParam(constant.INTERFACE_KEY, url.Path) != constant.SIMPLE_METADATA_SERVICE_NAME { + if url.GetParam(constant.INTERFACE_KEY, url.Path) != constant.METADATA_SERVICE_NAME { res = append(res, url) } } @@ -220,12 +220,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs get all exported urls -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { if serviceInterface == constant.ANY_VALUE { - return mts.getAllService(mts.exportedServiceURLs), nil + return service.ConvertURLArrToIntfArr(mts.getAllService(mts.exportedServiceURLs)), nil } else { serviceKey := definition.ServiceDescriperBuild(serviceInterface, group, version) - return mts.getSpecifiedService(mts.exportedServiceURLs, serviceKey, protocol), nil + return service.ConvertURLArrToIntfArr(mts.getSpecifiedService(mts.exportedServiceURLs, serviceKey, protocol)), nil } } diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go index bbe4b11017..95ad680f73 100644 --- a/metadata/service/inmemory/service_proxy.go +++ b/metadata/service/inmemory/service_proxy.go @@ -20,34 +20,59 @@ package inmemory import ( "context" "reflect" + "time" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol/invocation" ) +// actually it's RPC stub +// this will only be used by client-side +// if the metadata service is "local" metadata service in server side, +// which means that metadata service is RPC service too. +// 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 type MetadataServiceProxy struct { - invkr protocol.Invoker + invkr protocol.Invoker + golangServer bool } -func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { +func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { siV := reflect.ValueOf(serviceInterface) gV := reflect.ValueOf(group) vV := reflect.ValueOf(version) pV := reflect.ValueOf(protocol) - inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getExportedURLs"), + // this is a strange logic + // we should notice that + // when we call java server, the method was register as "getExportedURLs" + // however, if we call golang server, the method was register as "GetExportedURLs" + // it's so tricky... + methodName := "getExportedURLs" + if m.golangServer { + methodName = "GetExportedURLs" + } + + inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName(methodName), invocation.WithArguments([]interface{}{siV.Interface(), gV.Interface(), vV.Interface(), pV.Interface()}), invocation.WithReply(reflect.ValueOf(&[]interface{}{}).Interface()), invocation.WithAttachments(map[string]string{constant.ASYNC_KEY: "false"}), invocation.WithParameterValues([]reflect.Value{siV, gV, vV, pV})) + start := time.Now() res := m.invkr.Invoke(context.Background(), inv) + end := time.Now() + logger.Infof("duration: ", (end.Sub(start)).String()) if res.Error() != nil { logger.Errorf("could not get the metadata service from remote provider: %v", res.Error()) + return []interface{}{}, nil } urlStrs := res.Result().(*[]interface{}) @@ -62,61 +87,65 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st } ret = append(ret, u) } - return ret, nil + return service.ConvertURLArrToIntfArr(ret), nil } func (m *MetadataServiceProxy) Reference() string { - panic("implement me") + logger.Error("you should never invoke this implementation") + return constant.METADATA_SERVICE_NAME } func (m *MetadataServiceProxy) ServiceName() (string, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return "", nil } func (m *MetadataServiceProxy) ExportURL(url common.URL) (bool, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return false, nil } func (m *MetadataServiceProxy) UnexportURL(url common.URL) error { - panic("implement me") + logger.Error("you should never invoke this implementation") + return nil } func (m *MetadataServiceProxy) SubscribeURL(url common.URL) (bool, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return false, nil } func (m *MetadataServiceProxy) UnsubscribeURL(url common.URL) error { - panic("implement me") + logger.Error("you should never invoke this implementation") + return nil } func (m *MetadataServiceProxy) PublishServiceDefinition(url common.URL) error { - panic("implement me") + logger.Error("you should never invoke this implementation") + return nil } func (m *MetadataServiceProxy) GetSubscribedURLs() ([]common.URL, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return []common.URL{}, nil } func (m *MetadataServiceProxy) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return "", nil } func (m *MetadataServiceProxy) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return "", nil } func (m *MetadataServiceProxy) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { - panic("implement me") + logger.Error("you should never invoke this implementation") + return false, nil } func (m *MetadataServiceProxy) Version() (string, error) { - panic("implement me") -} - -type MetadataServiceStub struct { - GetExportedURLs func(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) -} - -func (m *MetadataServiceStub) Reference() string { - return constant.METADATA_SERVICE_NAME + logger.Error("you should never invoke this implementation") + return "", nil } diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index 19f0c021d3..e1127f72db 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -132,7 +132,7 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { } // GetExportedURLs will be implemented by in memory service -func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { +func (mts *MetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { return mts.inMemoryMetadataService.GetExportedURLs(serviceInterface, group, version, protocol) } @@ -162,9 +162,10 @@ func (mts *MetadataService) RefreshMetadata(exportedRevision string, subscribedR } logger.Infof("urls length = %v", len(urls)) for _, u := range urls { - id := identifier.NewServiceMetadataIdentifier(u) + + id := identifier.NewServiceMetadataIdentifier(u.(common.URL)) id.Revision = mts.exportedRevision.Load() - if err := mts.delegateReport.SaveServiceMetadata(id, u); err != nil { + if err := mts.delegateReport.SaveServiceMetadata(id, u.(common.URL)); err != nil { logger.Errorf("Error occur when execute remote.MetadataService.RefreshMetadata, error message is %+v", err) return false, err } diff --git a/metadata/service/remote/service_proxy.go b/metadata/service/remote/service_proxy.go index 090e8edc3d..8fe2e51d4d 100644 --- a/metadata/service/remote/service_proxy.go +++ b/metadata/service/remote/service_proxy.go @@ -45,31 +45,31 @@ func (m *metadataServiceProxy) ServiceName() (string, error) { } func (m *metadataServiceProxy) ExportURL(url common.URL) (bool, error) { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return true, nil } func (m *metadataServiceProxy) UnexportURL(url common.URL) error { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return nil } func (m *metadataServiceProxy) SubscribeURL(url common.URL) (bool, error) { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return true, nil } func (m *metadataServiceProxy) UnsubscribeURL(url common.URL) error { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return nil } func (m *metadataServiceProxy) PublishServiceDefinition(url common.URL) error { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return nil } -func (m *metadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) { +func (m *metadataServiceProxy) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { urls := m.report.GetExportedURLs(&identifier.ServiceMetadataIdentifier{ BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ ServiceInterface: serviceInterface, @@ -89,11 +89,11 @@ func (m *metadataServiceProxy) GetExportedURLs(serviceInterface string, group st } res = append(res, u) } - return res, nil + return service.ConvertURLArrToIntfArr(res), nil } func (m *metadataServiceProxy) GetSubscribedURLs() ([]common.URL, error) { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return []common.URL{}, nil } @@ -115,7 +115,7 @@ func (m *metadataServiceProxy) GetServiceDefinitionByServiceKey(serviceKey strin } func (m *metadataServiceProxy) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { - logger.Errorf("you should never invoke this implementation") + logger.Error("you should never invoke this implementation") return true, nil } diff --git a/metadata/service/service.go b/metadata/service/service.go index fc76eca68f..d5673e3552 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -43,7 +43,8 @@ type MetadataService interface { PublishServiceDefinition(url common.URL) error // GetExportedURLs will get the target exported url in metadata // the url should be unique - GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]common.URL, error) + // due to dubbo-go only support return array []interface{} in RPCService, so we should declare the return type as []interface{} + GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) // GetExportedURLs will get the target subscribed url in metadata // the url should be unique GetSubscribedURLs() ([]common.URL, error) @@ -108,3 +109,15 @@ func getExportedServicesRevision(serviceInstance registry.ServiceInstance) strin metaData := serviceInstance.GetMetadata() return metaData[constant.EXPORTED_SERVICES_REVISION_PROPERTY_NAME] } + +func ConvertURLArrToIntfArr(urls []common.URL) []interface{} { + if len(urls) == 0 { + return []interface{}{} + } + + res := make([]interface{}, 0, len(urls)) + for _, u := range urls { + res = append(res, u) + } + return res +} \ No newline at end of file diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go index 811d9308ee..9f791c8337 100644 --- a/registry/event/metadata_service_url_params_customizer.go +++ b/registry/event/metadata_service_url_params_customizer.go @@ -74,13 +74,14 @@ func (m *metadataServiceURLParamsMetadataCustomizer) Customize(instance registry instance.GetMetadata()[constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME] = string(str) } -func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []common.URL) map[string]map[string]string { +func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []interface{}) map[string]map[string]string { // usually there will be only one protocol res := make(map[string]map[string]string, 1) // those keys are useless - for _, u := range urls { + for _, ui := range urls { + u := ui.(common.URL) p := make(map[string]string, len(u.GetParams())) for k, v := range u.GetParams() { // we will ignore that diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index be2e381194..eae3f82c20 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -21,6 +21,7 @@ import ( "encoding/json" "strconv" + "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/registry" @@ -52,7 +53,8 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns return } - for _, u := range list { + for _, ui := range list { + u := ui.(common.URL) if len(u.Protocol) == 0 { continue } diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go index f51a955810..a001f36f62 100644 --- a/registry/event/service_revision_customizer.go +++ b/registry/event/service_revision_customizer.go @@ -26,6 +26,7 @@ import ( "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/metadata/service" "github.com/apache/dubbo-go/registry" ) @@ -85,7 +86,7 @@ func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance regist logger.Errorf("could not find the subscribed url", err) } - revision := resolveRevision(urls) + revision := resolveRevision(service.ConvertURLArrToIntfArr(urls)) if len(revision) == 0 { revision = defaultRevision } @@ -96,13 +97,14 @@ func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance regist // so that we could use interface + method name as identifier and ignore the method params // per my understanding, it's enough because Dubbo actually ignore the url params. // please refer org.apache.dubbo.common.URL#toParameterString(java.lang.String...) -func resolveRevision(urls []common.URL) string { +func resolveRevision(urls []interface{}) string { if len(urls) == 0 { return "" } candidates := make([]string, 0, len(urls)) - for _, u := range urls { + for _, ui := range urls { + u := ui.(common.URL) sk := u.GetParam(constant.INTERFACE_KEY, "") for _, m := range u.Methods { // methods are part of candidates diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 526603bf1c..a3899861ab 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -56,8 +56,7 @@ func init() { // It's completely different from other registry implementations // This implementation is based on ServiceDiscovery abstraction and ServiceNameMapping // In order to keep compatible with interface-level registry, -// 1. when we registry the service, we should create the mapping from service name to application name -// 2. when we sub +// this implementation is type serviceDiscoveryRegistry struct { lock sync.RWMutex url *common.URL @@ -72,13 +71,7 @@ type serviceDiscoveryRegistry struct { func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { - // the metadata service is exported in DubboBootstrap of Java Dubbo - // but I don't want to introduce similar structure because we has less logic to do - // so I codes the related logic here. - // If necessary we need to think about moving there codes to somewhere else. - - // init and expose metadata service - initMetadataService() + tryInitMetadataService() serviceDiscovery, err := creatServiceDiscovery(url) if err != nil { @@ -419,7 +412,12 @@ func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registr logger.Errorf("get exported urls catch error:%s,instance:%+v", err.Error(), serviceInstance) return urls } - return result + + ret := make([]common.URL, 0, len(result)) + for _, ui := range result { + ret = append(ret, ui.(common.URL)) + } + return ret } func (s *serviceDiscoveryRegistry) prepareServiceRevisionExportedURLs(serviceInstances []registry.ServiceInstance) { @@ -663,17 +661,21 @@ func (icn *InstanceChangeNotify) Notify(event observer.Event) { } } -func initMetadataService() { +var exporting = false + +func tryInitMetadataService() { + ms, err := extension.GetMetadataService(config.GetApplicationConfig().MetadataType) if err != nil { logger.Errorf("could not init metadata service", err) } - // we don't need to expose the metadata service since this is a pure consumer application - if !config.IsProvider() { + if !config.IsProvider() || exporting { return } + exporting = true + expt := configurable.NewMetadataServiceExporter(ms) err = expt.Export() From ca020d28c3a0026d84fc400bc6c64a417200537d Mon Sep 17 00:00:00 2001 From: flycash Date: Sat, 13 Jun 2020 23:10:03 +0800 Subject: [PATCH 111/209] Fix BUG --- common/constant/key.go | 4 ++-- metadata/service/inmemory/service_proxy.go | 14 ++++-------- metadata/service/service.go | 5 +++-- .../metadata_service_url_params_customizer.go | 6 ++++- .../protocol_ports_metadata_customizer.go | 22 ++++++++++++------- registry/event/service_revision_customizer.go | 18 +++++++++++---- .../service_discovery_registry.go | 9 +++++++- 7 files changed, 50 insertions(+), 28 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index 9b00d021b7..414d24e6e8 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -277,6 +277,6 @@ const ( // SERVICE_DISCOVERY_KEY indicate which service discovery instance will be used SERVICE_DISCOVERY_KEY = "service_discovery" - LANGUAGE_KEY = "language" - GO_LANG = "golang" + LANGUAGE_KEY = "language" + GO_LANG = "golang" ) diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go index 95ad680f73..a62d14457d 100644 --- a/metadata/service/inmemory/service_proxy.go +++ b/metadata/service/inmemory/service_proxy.go @@ -25,7 +25,6 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" - "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol/invocation" ) @@ -69,7 +68,7 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st start := time.Now() res := m.invkr.Invoke(context.Background(), inv) end := time.Now() - logger.Infof("duration: ", (end.Sub(start)).String()) + logger.Infof("duration: %s, result: %v", (end.Sub(start)).String(), res.Result()) if res.Error() != nil { logger.Errorf("could not get the metadata service from remote provider: %v", res.Error()) return []interface{}{}, nil @@ -77,17 +76,12 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st urlStrs := res.Result().(*[]interface{}) - ret := make([]common.URL, 0, len(*urlStrs)) + ret := make([]interface{}, 0, len(*urlStrs)) for _, s := range *urlStrs { - u, err := common.NewURL(s.(string)) - if err != nil { - logger.Errorf("could not convert the string to URL: %s", s) - continue - } - ret = append(ret, u) + ret = append(ret, s) } - return service.ConvertURLArrToIntfArr(ret), nil + return ret, nil } func (m *MetadataServiceProxy) Reference() string { diff --git a/metadata/service/service.go b/metadata/service/service.go index d5673e3552..803a84773f 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -44,6 +44,7 @@ type MetadataService interface { // GetExportedURLs will get the target exported url in metadata // the url should be unique // due to dubbo-go only support return array []interface{} in RPCService, so we should declare the return type as []interface{} + // actually, it's []String GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) // GetExportedURLs will get the target subscribed url in metadata // the url should be unique @@ -117,7 +118,7 @@ func ConvertURLArrToIntfArr(urls []common.URL) []interface{} { res := make([]interface{}, 0, len(urls)) for _, u := range urls { - res = append(res, u) + res = append(res, u.String()) } return res -} \ No newline at end of file +} diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go index 9f791c8337..06278f4e77 100644 --- a/registry/event/metadata_service_url_params_customizer.go +++ b/registry/event/metadata_service_url_params_customizer.go @@ -81,7 +81,11 @@ func (m *metadataServiceURLParamsMetadataCustomizer) convertToParams(urls []inte // those keys are useless for _, ui := range urls { - u := ui.(common.URL) + u, err := common.NewURL(ui.(string)) + if err != nil { + logger.Errorf("could not parse the string to url: %s", ui.(string), err) + continue + } p := make(map[string]string, len(u.GetParams())) for k, v := range u.GetParams() { // we will ignore that diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index eae3f82c20..bf16fa8e2f 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -23,11 +23,16 @@ 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/registry" ) -// ProtocolPortsMetadataCustomizer will update +func init() { + extension.AddCustomizers(&ProtocolPortsMetadataCustomizer{}) +} + +// ProtocolPortsMetadataCustomizer will update the endpoints type ProtocolPortsMetadataCustomizer struct { } @@ -48,14 +53,15 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns protocolMap := make(map[string]int, 4) list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) - if err != nil || list == nil { + if err != nil || len(list) == 0 { logger.Errorf("Could not find exported urls", err) return } for _, ui := range list { - u := ui.(common.URL) - if len(u.Protocol) == 0 { + u, err := common.NewURL(ui.(string)) + if err != nil || len(u.Protocol) == 0 { + logger.Errorf("the url string is invalid: %s", ui.(string), err) continue } @@ -77,8 +83,8 @@ func endpointsStr(protocolMap map[string]int) string { endpoints := make([]endpoint, 0, len(protocolMap)) for k, v := range protocolMap { endpoints = append(endpoints, endpoint{ - port: v, - protocol: k, + Port: v, + Protocol: k, }) } @@ -91,6 +97,6 @@ func endpointsStr(protocolMap map[string]int) string { } type endpoint struct { - port int - protocol string + Port int `json:"port"` + Protocol string `json:"protocol"` } diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go index a001f36f62..fb1cda01a5 100644 --- a/registry/event/service_revision_customizer.go +++ b/registry/event/service_revision_customizer.go @@ -104,12 +104,22 @@ func resolveRevision(urls []interface{}) string { candidates := make([]string, 0, len(urls)) for _, ui := range urls { - u := ui.(common.URL) + u, err := common.NewURL(ui.(string)) + if err != nil { + logger.Errorf("could not parse the string to URL structure") + continue + } sk := u.GetParam(constant.INTERFACE_KEY, "") - for _, m := range u.Methods { - // methods are part of candidates - candidates = append(candidates, sk+constant.KEY_SEPARATOR+m) + + if len(u.Methods) == 0 { + candidates = append(candidates, sk) + } else { + for _, m := range u.Methods { + // methods are part of candidates + candidates = append(candidates, sk+constant.KEY_SEPARATOR+m) + } } + // append url params if we need it } sort.Sort(sort.StringSlice(candidates)) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index a3899861ab..41054824a2 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -415,7 +415,14 @@ func (s *serviceDiscoveryRegistry) getExportedUrlsByInst(serviceInstance registr ret := make([]common.URL, 0, len(result)) for _, ui := range result { - ret = append(ret, ui.(common.URL)) + + u, err := common.NewURL(ui.(string)) + + if err != nil { + logger.Errorf("could not parse the url string to URL structure: %s", ui.(string), err) + continue + } + ret = append(ret, u) } return ret } From 8793dab0cc4d0b345e935cf22120cc1fb88dfb8c Mon Sep 17 00:00:00 2001 From: pantianying <601666418@qq.com> Date: Mon, 15 Jun 2020 17:58:49 +0800 Subject: [PATCH 112/209] add code for etcd metadata report --- metadata/report/etcd/report.go | 156 ++++++++++++++++++++++++++++ metadata/report/etcd/report_test.go | 18 ++++ remoting/etcdv3/client.go | 8 +- remoting/etcdv3/client_test.go | 2 +- 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 metadata/report/etcd/report.go create mode 100644 metadata/report/etcd/report_test.go diff --git a/metadata/report/etcd/report.go b/metadata/report/etcd/report.go new file mode 100644 index 0000000000..0ece0e5608 --- /dev/null +++ b/metadata/report/etcd/report.go @@ -0,0 +1,156 @@ +/* + * 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 etcd + +import ( + "encoding/json" + "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/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" + "github.com/apache/dubbo-go/remoting/etcdv3" + perrors "github.com/pkg/errors" + "strings" + "time" +) + +const DEFAULT_ROOT = "dubbo" + +func init() { + ftry := &etcdMetadataReportFactory{} + extension.SetMetadataReportFactory("etcd", func() factory.MetadataReportFactory { + return ftry + }) +} + +// etcdMetadataReport is the implementation of MetadataReport based etcd +type etcdMetadataReport struct { + client *etcdv3.Client + root string +} + +// StoreProviderMetadata will store the metadata +// metadata including the basic info of the server, provider info, and other user custom info +func (e *etcdMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { + key := e.getNodeKey(providerIdentifier) + return e.client.Create(key, serviceDefinitions) +} + +// StoreConsumerMetadata will store the metadata +// metadata including the basic info of the server, consumer info, and other user custom info +func (e *etcdMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { + key := e.getNodeKey(consumerMetadataIdentifier) + return e.client.Create(key, serviceParameterString) +} + +// SaveServiceMetadata will store the metadata +// metadata including the basic info of the server, service info, and other user custom info +func (e *etcdMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { + key := e.getNodeKey(metadataIdentifier) + return e.client.Create(key, url.String()) +} + +// RemoveServiceMetadata will remove the service metadata +func (e *etcdMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier) error { + return e.client.Delete(e.getNodeKey(metadataIdentifier)) +} + +// GetExportedURLs will look up the exported urls. +// if not found, an empty list will be returned. +func (e *etcdMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { + content, err := e.client.Get(e.getNodeKey(metadataIdentifier)) + if err != nil { + logger.Errorf("etcdMetadataReport GetExportedURLs err:{%v}", err.Error()) + return nil + } + if content == "" { + return []string{} + } + return []string{content} +} + +// SaveSubscribedData will convert the urlList to json array and then store it +func (e *etcdMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlList []common.URL) error { + if len(urlList) == 0 { + logger.Warnf("The url list is empty") + return nil + } + urlStrList := make([]string, 0, len(urlList)) + + for _, e := range urlList { + urlStrList = append(urlStrList, e.String()) + } + + bytes, err := json.Marshal(urlStrList) + + if err != nil { + return perrors.WithMessage(err, "Could not convert the array to json") + } + key := e.getNodeKey(subscriberMetadataIdentifier) + return e.client.Create(key, string(bytes)) +} + +// GetSubscribedURLs will lookup the url +// if not found, an empty list will be returned +func (e *etcdMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { + content, err := e.client.Get(e.getNodeKey(subscriberMetadataIdentifier)) + if err != nil { + logger.Errorf("etcdMetadataReport GetSubscribedURLs err:{%v}", err.Error()) + } + return []string{content} +} + +// GetServiceDefinition will lookup the service definition +func (e *etcdMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { + key := e.getNodeKey(metadataIdentifier) + content, err := e.client.Get(key) + if err != nil { + logger.Errorf("etcdMetadataReport GetServiceDefinition err:{%v}", err.Error()) + return "" + } + return content +} + +type etcdMetadataReportFactory struct{} + +// CreateMetadataReport get the MetadataReport instance of etcd +func (e *etcdMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { + timeout, _ := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) + addresses := strings.Split(url.Location, ",") + client, err := etcdv3.NewClient(etcdv3.MetadataETCDV3Client, addresses, timeout, 1) + if err != nil { + logger.Errorf("Could not create etcd metadata report. URL: %s", url.String()) + return nil + } + group := url.GetParam(constant.GROUP_KEY, DEFAULT_ROOT) + group = constant.PATH_SEPARATOR + strings.TrimPrefix(group, constant.PATH_SEPARATOR) + return &etcdMetadataReport{client: client, root: group} +} + +func (e *etcdMetadataReport) getNodeKey(MetadataIdentifier identifier.IMetadataIdentifier) string { + var rootDir string + if e.root == constant.PATH_SEPARATOR { + rootDir = e.root + } else { + rootDir = e.root + constant.PATH_SEPARATOR + } + return rootDir + MetadataIdentifier.GetFilePathKey() +} diff --git a/metadata/report/etcd/report_test.go b/metadata/report/etcd/report_test.go new file mode 100644 index 0000000000..0f61fa4b36 --- /dev/null +++ b/metadata/report/etcd/report_test.go @@ -0,0 +1,18 @@ +/* + * 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 etcd diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index ba3ea6e864..731ef0d807 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -42,6 +42,8 @@ const ( MaxFailTimes = 15 // RegistryETCDV3Client client name RegistryETCDV3Client = "etcd registry" + // metadataETCDV3Client client name + MetadataETCDV3Client = "etcd metadata" ) var ( @@ -107,7 +109,7 @@ func ValidateClient(container clientFacade, opts ...Option) error { // new Client if container.Client() == nil { - newClient, err := newClient(options.name, options.endpoints, options.timeout, options.heartbeat) + newClient, err := NewClient(options.name, options.endpoints, options.timeout, options.heartbeat) if err != nil { logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", options.name, options.endpoints, options.timeout, err) @@ -119,7 +121,7 @@ func ValidateClient(container clientFacade, opts ...Option) error { // Client lose connection with etcd server if container.Client().rawClient == nil { - newClient, err := newClient(options.name, options.endpoints, options.timeout, options.heartbeat) + newClient, err := NewClient(options.name, options.endpoints, options.timeout, options.heartbeat) if err != nil { logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", options.name, options.endpoints, options.timeout, err) @@ -149,7 +151,7 @@ type Client struct { Wait sync.WaitGroup } -func newClient(name string, endpoints []string, timeout time.Duration, heartbeat int) (*Client, error) { +func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat int) (*Client, error) { ctx, cancel := context.WithCancel(context.Background()) rawClient, err := clientv3.New(clientv3.Config{ diff --git a/remoting/etcdv3/client_test.go b/remoting/etcdv3/client_test.go index e37b6383df..287d93e30d 100644 --- a/remoting/etcdv3/client_test.go +++ b/remoting/etcdv3/client_test.go @@ -120,7 +120,7 @@ func (suite *ClientTestSuite) TearDownSuite() { } func (suite *ClientTestSuite) setUpClient() *Client { - c, err := newClient(suite.etcdConfig.name, + c, err := NewClient(suite.etcdConfig.name, suite.etcdConfig.endpoints, suite.etcdConfig.timeout, suite.etcdConfig.heartbeat) From d6a68d5c04c3b12f03c3a89b58a85fb357d49efb Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 15 Jun 2020 20:28:06 +0800 Subject: [PATCH 113/209] Fix Review And Add UT --- common/extension/event_dispatcher.go | 13 +- common/extension/event_dispatcher_test.go | 111 ++++++++++++++++++ common/extension/metadata_service.go | 5 + .../metadata_service_proxy_factory.go | 5 + .../extension/service_instance_customizer.go | 9 +- .../service_instance_selector_factory.go | 3 + common/extension/service_name_mapping.go | 4 +- .../dispatcher/direct_event_dispatcher.go | 13 +- .../direct_event_dispatcher_test.go | 6 +- common/observer/event.go | 2 + common/observer/listenable.go | 59 ++++++---- common/observer/listenable_test.go | 3 +- common/rpc_service.go | 3 + common/url.go | 9 +- config/base_config.go | 3 +- config/config_loader.go | 10 +- config/instance/metadata_report_test.go | 85 ++++++++++++++ metadata/service/inmemory/service_proxy.go | 14 +-- metadata/service/remote/service_proxy.go | 4 + metadata/service/service.go | 9 ++ ...vent_publishing_service_deiscovery_test.go | 8 +- .../service_discovery_registry.go | 16 ++- 22 files changed, 333 insertions(+), 61 deletions(-) create mode 100644 common/extension/event_dispatcher_test.go create mode 100644 config/instance/metadata_report_test.go diff --git a/common/extension/event_dispatcher.go b/common/extension/event_dispatcher.go index a543910cc1..ac71e3b5e9 100644 --- a/common/extension/event_dispatcher.go +++ b/common/extension/event_dispatcher.go @@ -19,7 +19,9 @@ package extension import ( "sync" +) +import ( "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" ) @@ -34,12 +36,15 @@ var ( dispatchers = make(map[string]func() observer.EventDispatcher, 8) ) -// SetEventDispatcher by name +// SetEventDispatcher, actually, it doesn't really init the global dispatcher func SetEventDispatcher(name string, v func() observer.EventDispatcher) { dispatchers[name] = v } -// SetAndInitGlobalDispatcher +// SetAndInitGlobalDispatcher will actually init the global dispatcher +// if there is already a global dispatcher, +// it will be override +// if the dispatcher with the name not found, it will panic func SetAndInitGlobalDispatcher(name string) { if len(name) == 0 { name = "direct" @@ -47,8 +52,10 @@ func SetAndInitGlobalDispatcher(name string) { if globalEventDispatcher != nil { logger.Warnf("EventDispatcher already init. It will be replaced") } + if dp, ok := dispatchers[name]; !ok || dp == nil { - panic("EventDispatcher for " + name + " is not existing, make sure you have import the package.") + panic("EventDispatcher for " + name + " is not found, make sure you have import the package, " + + "like github.com/apache/dubbo-go/common/observer/dispatcher ") } globalEventDispatcher = dispatchers[name]() } diff --git a/common/extension/event_dispatcher_test.go b/common/extension/event_dispatcher_test.go new file mode 100644 index 0000000000..472360cea5 --- /dev/null +++ b/common/extension/event_dispatcher_test.go @@ -0,0 +1,111 @@ +/* + * 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 ( + "reflect" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) +import ( + "github.com/apache/dubbo-go/common/observer" +) + +func TestSetAndInitGlobalDispatcher(t *testing.T) { + mock := &mockEventDispatcher{} + SetEventDispatcher("mock", func() observer.EventDispatcher { + return mock + }) + + SetAndInitGlobalDispatcher("mock") + dispatcher := GetGlobalDispatcher() + assert.NotNil(t, dispatcher) + assert.Equal(t, mock, dispatcher) + + mock1 := &mockEventDispatcher{} + + SetEventDispatcher("mock1", func() observer.EventDispatcher { + return mock1 + }) + + SetAndInitGlobalDispatcher("mock1") + dispatcher = GetGlobalDispatcher() + assert.NotNil(t, dispatcher) + assert.Equal(t, mock1, dispatcher) +} + +func TestAddEventListener(t *testing.T) { + AddEventListener(func() observer.EventListener { + return &mockEventListener{} + }) + + AddEventListener(func() observer.EventListener { + return &mockEventListener{} + }) + + assert.Equal(t, 2, len(initEventListeners)) +} + +type mockEventListener struct { +} + +func (m mockEventListener) GetPriority() int { + panic("implement me") +} + +func (m mockEventListener) OnEvent(e observer.Event) error { + panic("implement me") +} + +func (m mockEventListener) GetEventType() reflect.Type { + panic("implement me") +} + +type mockEventDispatcher struct { +} + +func (m mockEventDispatcher) AddEventListener(listener observer.EventListener) { + panic("implement me") +} + +func (m mockEventDispatcher) AddEventListeners(listenersSlice []observer.EventListener) { + panic("implement me") +} + +func (m mockEventDispatcher) RemoveEventListener(listener observer.EventListener) { + panic("implement me") +} + +func (m mockEventDispatcher) RemoveEventListeners(listenersSlice []observer.EventListener) { + panic("implement me") +} + +func (m mockEventDispatcher) GetAllEventListeners() []observer.EventListener { + panic("implement me") +} + +func (m mockEventDispatcher) RemoveAllEventListeners() { + panic("implement me") +} + +func (m mockEventDispatcher) Dispatch(event observer.Event) { + panic("implement me") +} diff --git a/common/extension/metadata_service.go b/common/extension/metadata_service.go index 93ff40aa76..1823273b8f 100644 --- a/common/extension/metadata_service.go +++ b/common/extension/metadata_service.go @@ -19,7 +19,9 @@ package extension import ( "fmt" +) +import ( "github.com/apache/dubbo-go/metadata/service" ) @@ -28,10 +30,13 @@ var ( metadataServiceInsMap = make(map[string]func() (service.MetadataService, error), 2) ) +// SetMetadataService will store the msType => creator pair func SetMetadataService(msType string, creator func() (service.MetadataService, error)) { metadataServiceInsMap[msType] = creator } +// GetMetadataService will create a MetadataService instance +// it will panic if msType not found func GetMetadataService(msType string) (service.MetadataService, error) { if creator, ok := metadataServiceInsMap[msType]; ok { return creator() diff --git a/common/extension/metadata_service_proxy_factory.go b/common/extension/metadata_service_proxy_factory.go index 35f63c5fa9..e8c9e73d73 100644 --- a/common/extension/metadata_service_proxy_factory.go +++ b/common/extension/metadata_service_proxy_factory.go @@ -19,7 +19,9 @@ package extension import ( "fmt" +) +import ( "github.com/apache/dubbo-go/metadata/service" ) @@ -27,10 +29,13 @@ var ( metadataServiceProxyFactoryMap = make(map[string]func() service.MetadataServiceProxyFactory) ) +// SetMetadataServiceProxyFactory store the name-creator pair func SetMetadataServiceProxyFactory(name string, creator func() service.MetadataServiceProxyFactory) { metadataServiceProxyFactoryMap[name] = creator } +// GetMetadataServiceProxyFactory will create an instance. +// it will panic if the factory with name not found func GetMetadataServiceProxyFactory(name string) service.MetadataServiceProxyFactory { if f, ok := metadataServiceProxyFactoryMap[name]; ok { return f() diff --git a/common/extension/service_instance_customizer.go b/common/extension/service_instance_customizer.go index a0e443aff5..3ebb3e40f5 100644 --- a/common/extension/service_instance_customizer.go +++ b/common/extension/service_instance_customizer.go @@ -19,7 +19,9 @@ package extension import ( "sort" +) +import ( "github.com/apache/dubbo-go/registry" ) @@ -35,15 +37,20 @@ func AddCustomizers(cus registry.ServiceInstanceCustomizer) { } // GetCustomizers will return the sorted customizer +// the result won't be nil func GetCustomizers() []registry.ServiceInstanceCustomizer { return customizers } type customizerSlice []registry.ServiceInstanceCustomizer +// nolint func (c customizerSlice) Len() int { return len(c) } -func (c customizerSlice) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +// nolint +func (c customizerSlice) Swap(i, j int) { c[i], c[j] = c[j], c[i] } + +// nolint func (c customizerSlice) Less(i, j int) bool { return c[i].GetPriority() < c[j].GetPriority() } diff --git a/common/extension/service_instance_selector_factory.go b/common/extension/service_instance_selector_factory.go index 3ba3db46e6..7776a408d8 100644 --- a/common/extension/service_instance_selector_factory.go +++ b/common/extension/service_instance_selector_factory.go @@ -29,10 +29,13 @@ var ( serviceInstanceSelectorMappings = make(map[string]func() instance.ServiceInstanceSelector) ) +// nolint func SetServiceInstanceSelector(name string, f func() instance.ServiceInstanceSelector) { serviceInstanceSelectorMappings[name] = f } +// GetServiceInstanceSelector will create an instance +// it will panic if selector with the @name not found func GetServiceInstanceSelector(name string) (instance.ServiceInstanceSelector, error) { serviceInstanceSelector, ok := serviceInstanceSelectorMappings[name] if !ok { diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index cd2630198e..9e5aac52f9 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -17,7 +17,9 @@ package extension -import "github.com/apache/dubbo-go/metadata/mapping" +import ( + "github.com/apache/dubbo-go/metadata/mapping" +) var ( globalNameMappingCreator func() mapping.ServiceNameMapping diff --git a/common/observer/dispatcher/direct_event_dispatcher.go b/common/observer/dispatcher/direct_event_dispatcher.go index 2b7567b47e..a2d334ce2c 100644 --- a/common/observer/dispatcher/direct_event_dispatcher.go +++ b/common/observer/dispatcher/direct_event_dispatcher.go @@ -36,26 +36,31 @@ func init() { // Align with 2.7.5 // Dispatcher event to listener direct type DirectEventDispatcher struct { - observer.BaseListenable + observer.BaseListener } // NewDirectEventDispatcher ac constructor of DirectEventDispatcher func NewDirectEventDispatcher() observer.EventDispatcher { - return &DirectEventDispatcher{} + return &DirectEventDispatcher{ + BaseListener: observer.NewBaseListener(), + } } // Dispatch event directly +// it lookup the listener by event's type. +// if listener not found, it just return and do nothing func (ded *DirectEventDispatcher) Dispatch(event observer.Event) { if event == nil { logger.Warnf("[DirectEventDispatcher] dispatch event nil") return } eventType := reflect.TypeOf(event).Elem() - value, loaded := ded.ListenersCache.Load(eventType) + ded.Mutex.RLock() + defer ded.Mutex.RUnlock() + listenersSlice, loaded := ded.ListenersCache[eventType] if !loaded { return } - listenersSlice := value.([]observer.EventListener) for _, listener := range listenersSlice { if err := listener.OnEvent(event); err != nil { logger.Warnf("[DirectEventDispatcher] dispatch event error:%v", err) diff --git a/common/observer/dispatcher/direct_event_dispatcher_test.go b/common/observer/dispatcher/direct_event_dispatcher_test.go index 355c930a9e..12facbb9c4 100644 --- a/common/observer/dispatcher/direct_event_dispatcher_test.go +++ b/common/observer/dispatcher/direct_event_dispatcher_test.go @@ -29,7 +29,9 @@ import ( func TestDirectEventDispatcher_Dispatch(t *testing.T) { ded := NewDirectEventDispatcher() - ded.AddEventListener(&TestEventListener{}) + ded.AddEventListener(&TestEventListener{ + BaseListener: observer.NewBaseListener(), + }) ded.AddEventListener(&TestEventListener1{}) ded.Dispatch(&TestEvent{}) ded.Dispatch(nil) @@ -40,7 +42,7 @@ type TestEvent struct { } type TestEventListener struct { - observer.BaseListenable + observer.BaseListener observer.EventListener } diff --git a/common/observer/event.go b/common/observer/event.go index d78179043e..209a50c78a 100644 --- a/common/observer/event.go +++ b/common/observer/event.go @@ -58,6 +58,8 @@ func (b *BaseEvent) String() string { return fmt.Sprintf("BaseEvent[source = %#v]", b.Source) } +// NewBaseEvent create an BaseEvent instance +// and the Timestamp will be current timestamp func NewBaseEvent(source interface{}) *BaseEvent { return &BaseEvent{ Source: source, diff --git a/common/observer/listenable.go b/common/observer/listenable.go index 7b64aa8f2d..887f7a377d 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -33,28 +33,32 @@ type Listenable interface { RemoveAllEventListeners() } -// BaseListenable base listenable -type BaseListenable struct { +// BaseListener base listenable +type BaseListener struct { Listenable - ListenersCache sync.Map - Mutex sync.Mutex + ListenersCache map[reflect.Type][]EventListener + Mutex sync.RWMutex } -// NewBaseListenable a constructor of base listenable -func NewBaseListenable() Listenable { - return &BaseListenable{} +// NewBaseListener a constructor of base listenable +func NewBaseListener() BaseListener { + return BaseListener{ + ListenersCache: make(map[reflect.Type][]EventListener, 8), + } } // AddEventListener add event listener -func (bl *BaseListenable) AddEventListener(listener EventListener) { +func (bl *BaseListener) AddEventListener(listener EventListener) { eventType := listener.GetEventType() if eventType.Kind() == reflect.Ptr { eventType = eventType.Elem() } bl.Mutex.Lock() defer bl.Mutex.Unlock() - value, loaded := bl.ListenersCache.LoadOrStore(eventType, make([]EventListener, 0, 8)) - listenersSlice := value.([]EventListener) + listenersSlice, loaded := bl.ListenersCache[eventType] + if !loaded { + listenersSlice = make([]EventListener, 0, 8) + } // return if listenersSlice already has this listener if loaded && containListener(listenersSlice, listener) { return @@ -63,59 +67,62 @@ func (bl *BaseListenable) AddEventListener(listener EventListener) { sort.Slice(listenersSlice, func(i, j int) bool { return listenersSlice[i].GetPriority() < listenersSlice[j].GetPriority() }) - bl.ListenersCache.Store(eventType, listenersSlice) + bl.ListenersCache[eventType] = listenersSlice } // AddEventListeners add the slice of event listener -func (bl *BaseListenable) AddEventListeners(listenersSlice []EventListener) { +func (bl *BaseListener) AddEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.AddEventListener(listener) } } // RemoveEventListener remove the event listener -func (bl *BaseListenable) RemoveEventListener(listener EventListener) { +func (bl *BaseListener) RemoveEventListener(listener EventListener) { eventType := listener.GetEventType() if eventType.Kind() == reflect.Ptr { eventType = eventType.Elem() } bl.Mutex.Lock() defer bl.Mutex.Unlock() - value, loaded := bl.ListenersCache.Load(eventType) + listenersSlice, loaded := bl.ListenersCache[eventType] if !loaded { return } - listenersSlice := value.([]EventListener) for i, l := range listenersSlice { if l == listener { listenersSlice = append(listenersSlice[:i], listenersSlice[i+1:]...) } } - bl.ListenersCache.Store(eventType, listenersSlice) + bl.ListenersCache[eventType] = listenersSlice } // RemoveEventListeners remove the slice of event listener -func (bl *BaseListenable) RemoveEventListeners(listenersSlice []EventListener) { +// it will iterate all listener and remove it one by one +func (bl *BaseListener) RemoveEventListeners(listenersSlice []EventListener) { for _, listener := range listenersSlice { bl.RemoveEventListener(listener) } } // RemoveAllEventListeners remove all -func (bl *BaseListenable) RemoveAllEventListeners() { +// using Lock +func (bl *BaseListener) RemoveAllEventListeners() { bl.Mutex.Lock() defer bl.Mutex.Unlock() - bl.ListenersCache = sync.Map{} + bl.ListenersCache = make(map[reflect.Type][]EventListener) } -// GetAllEventListeners get all -func (bl *BaseListenable) GetAllEventListeners() []EventListener { +// GetAllEventListeners get all listener +// using RLock +func (bl *BaseListener) GetAllEventListeners() []EventListener { allListenersSlice := make([]EventListener, 0, 16) - bl.ListenersCache.Range(func(_, value interface{}) bool { - listenersSlice := value.([]EventListener) + + bl.Mutex.RLock() + defer bl.Mutex.RUnlock() + for _, listenersSlice := range bl.ListenersCache { allListenersSlice = append(allListenersSlice, listenersSlice...) - return true - }) + } sort.Slice(allListenersSlice, func(i, j int) bool { return allListenersSlice[i].GetPriority() < allListenersSlice[j].GetPriority() }) @@ -123,6 +130,8 @@ func (bl *BaseListenable) GetAllEventListeners() []EventListener { } // containListener true if contain listener +// it's not thread safe +// usually it should be use in lock scope func containListener(listenersSlice []EventListener, listener EventListener) bool { for _, loadListener := range listenersSlice { if loadListener == listener { diff --git a/common/observer/listenable_test.go b/common/observer/listenable_test.go index df46bfc2ba..5a03382a93 100644 --- a/common/observer/listenable_test.go +++ b/common/observer/listenable_test.go @@ -28,7 +28,8 @@ import ( func TestListenable(t *testing.T) { el := &TestEventListener{} - b := &BaseListenable{} + bl := NewBaseListener() + b := &bl b.AddEventListener(el) b.AddEventListener(el) al := b.GetAllEventListeners() diff --git a/common/rpc_service.go b/common/rpc_service.go index 1127e6c018..f9fb145c80 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -343,6 +343,9 @@ func suiteMethod(method reflect.Method) *MethodType { argsType []reflect.Type ) + // this method is in RPCService + // we force users must implement RPCService interface in their provider + // see RPCService if mname == "Reference" { return nil } diff --git a/common/url.go b/common/url.go index 9c3f065497..e0e15739da 100644 --- a/common/url.go +++ b/common/url.go @@ -25,8 +25,6 @@ import ( "net/url" "strconv" "strings" - - "github.com/apache/dubbo-go/common/logger" ) import ( @@ -38,6 +36,7 @@ import ( import ( "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" ) // /////////////////////////////// @@ -182,6 +181,7 @@ func WithToken(token string) option { u, err := uuid.NewV4() if err != nil { logger.Errorf("could not generator UUID: %v", err) + return } value = u.String() } @@ -657,16 +657,21 @@ func mergeNormalParam(mergedUrl *URL, referenceUrl *URL, paramKeys []string) []f return methodConfigMergeFcn } +// URLSlice will be used to sort URL instance +// Instances will be order by URL.String() type URLSlice []URL +// nolint func (s URLSlice) Len() int { return len(s) } +// nolint func (s URLSlice) Less(i, j int) bool { return s[i].String() < s[j].String() } +// nolint func (s URLSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/config/base_config.go b/config/base_config.go index 67313a14fe..46ff5fb174 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -40,7 +40,7 @@ type multiConfiger interface { Prefix() string } -// BaseConfig is the event configuration for provider and consumer +// BaseConfig is the common configuration for provider and consumer type BaseConfig struct { ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` @@ -60,6 +60,7 @@ type BaseConfig struct { fileStream *bytes.Buffer } +// nolint func (c *BaseConfig) GetServiceDiscoveries(name string) (config *ServiceDiscoveryConfig, ok bool) { config, ok = c.ServiceDiscoveries[name] return diff --git a/config/config_loader.go b/config/config_loader.go index 10a3387015..e0cb09d942 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -146,9 +146,9 @@ func loadConsumerConfig() { checkok = false count++ if count > maxWait { - // errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) - // logger.Error(errMsg) - // panic(errMsg) + errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) + logger.Error(errMsg) + panic(errMsg) } time.Sleep(time.Second * 1) break @@ -219,7 +219,7 @@ func Load() { // init router initRouter() - // event part + // init the global event dispatcher extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) // start the metadata report if config set @@ -285,7 +285,6 @@ func GetApplicationConfig() *ApplicationConfig { // if not found, create new one func GetProviderConfig() ProviderConfig { if providerConfig == nil { - logger.Warnf("providerConfig is nil! we will try to create one") if providerConfig == nil { return ProviderConfig{} } @@ -308,7 +307,6 @@ func GetConsumerConfig() ConsumerConfig { } func GetBaseConfig() *BaseConfig { - if baseConfig == nil { baseConfigOnce.Do(func() { baseConfig = &BaseConfig{ diff --git a/config/instance/metadata_report_test.go b/config/instance/metadata_report_test.go new file mode 100644 index 0000000000..51780a53f6 --- /dev/null +++ b/config/instance/metadata_report_test.go @@ -0,0 +1,85 @@ +/* + * 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 instance + +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" +) + +func TestGetMetadataReportInstance(t *testing.T) { + extension.SetMetadataReportFactory("mock", func() factory.MetadataReportFactory { + return &mockMetadataReportFactory{} + }) + u, _ := common.NewURL("mock://127.0.0.1") + rpt := GetMetadataReportInstance(&u) + assert.NotNil(t, rpt) +} + +type mockMetadataReportFactory struct { +} + +func (m *mockMetadataReportFactory) CreateMetadataReport(*common.URL) report.MetadataReport { + return &mockMetadataReport{} +} + +type mockMetadataReport struct { +} + +func (m mockMetadataReport) StoreProviderMetadata(*identifier.MetadataIdentifier, string) error { + panic("implement me") +} + +func (m mockMetadataReport) StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error { + panic("implement me") +} + +func (m mockMetadataReport) SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error { + panic("implement me") +} + +func (m mockMetadataReport) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error { + panic("implement me") +} + +func (m mockMetadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string { + panic("implement me") +} + +func (m mockMetadataReport) SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []common.URL) error { + panic("implement me") +} + +func (m mockMetadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string { + panic("implement me") +} + +func (m mockMetadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) string { + panic("implement me") +} diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go index a62d14457d..69e349a0f8 100644 --- a/metadata/service/inmemory/service_proxy.go +++ b/metadata/service/inmemory/service_proxy.go @@ -49,15 +49,7 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st vV := reflect.ValueOf(version) pV := reflect.ValueOf(protocol) - // this is a strange logic - // we should notice that - // when we call java server, the method was register as "getExportedURLs" - // however, if we call golang server, the method was register as "GetExportedURLs" - // it's so tricky... - methodName := "getExportedURLs" - if m.golangServer { - methodName = "GetExportedURLs" - } + const methodName = "getExportedURLs" inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName(methodName), invocation.WithArguments([]interface{}{siV.Interface(), gV.Interface(), vV.Interface(), pV.Interface()}), @@ -84,6 +76,10 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st return ret, nil } +func (m *MetadataServiceProxy) MethodMapper() map[string]string { + return map[string]string{} +} + func (m *MetadataServiceProxy) Reference() string { logger.Error("you should never invoke this implementation") return constant.METADATA_SERVICE_NAME diff --git a/metadata/service/remote/service_proxy.go b/metadata/service/remote/service_proxy.go index 8fe2e51d4d..5e37d39fd4 100644 --- a/metadata/service/remote/service_proxy.go +++ b/metadata/service/remote/service_proxy.go @@ -92,6 +92,10 @@ func (m *metadataServiceProxy) GetExportedURLs(serviceInterface string, group st return service.ConvertURLArrToIntfArr(res), nil } +func (m *metadataServiceProxy) MethodMapper() map[string]string { + return map[string]string{} +} + func (m *metadataServiceProxy) GetSubscribedURLs() ([]common.URL, error) { logger.Error("you should never invoke this implementation") return []common.URL{}, nil diff --git a/metadata/service/service.go b/metadata/service/service.go index 803a84773f..ae04858247 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -46,6 +46,9 @@ type MetadataService interface { // due to dubbo-go only support return array []interface{} in RPCService, so we should declare the return type as []interface{} // actually, it's []String GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) + + MethodMapper() map[string]string + // GetExportedURLs will get the target subscribed url in metadata // the url should be unique GetSubscribedURLs() ([]common.URL, error) @@ -70,6 +73,12 @@ func NewBaseMetadataService(serviceName string) BaseMetadataService { } } +func (mts *BaseMetadataService) MethodMapper() map[string]string { + return map[string]string{ + "GetExportedURLs": "getExportedURLs", + } +} + // ServiceName can get the service's name in meta service , which is application name func (mts *BaseMetadataService) ServiceName() (string, error) { return mts.serviceName, nil diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index ea6a97a322..21bddb7f04 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -46,7 +46,9 @@ func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { config.GetApplicationConfig().MetadataType = "local" dc := NewEventPublishingServiceDiscovery(&ServiceDiscoveryA{}) - tsd := &TestServiceDiscoveryDestroyingEventListener{} + tsd := &TestServiceDiscoveryDestroyingEventListener{ + BaseListener: observer.NewBaseListener(), + } tsd.SetT(t) tsi := &TestServiceInstancePreRegisteredEventListener{} tsi.SetT(t) @@ -68,7 +70,7 @@ func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { type TestServiceDiscoveryDestroyingEventListener struct { suite.Suite - observer.BaseListenable + observer.BaseListener } func (tel *TestServiceDiscoveryDestroyingEventListener) OnEvent(e observer.Event) error { @@ -89,7 +91,7 @@ func (tel *TestServiceDiscoveryDestroyingEventListener) GetEventType() reflect.T type TestServiceInstancePreRegisteredEventListener struct { suite.Suite - observer.BaseListenable + observer.BaseListener } func (tel *TestServiceInstancePreRegisteredEventListener) OnEvent(e observer.Event) error { diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index c6145e6634..79194fb084 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -28,6 +28,7 @@ import ( gxset "github.com/dubbogo/gost/container/set" gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" + "go.uber.org/atomic" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -674,8 +675,12 @@ func (icn *InstanceChangeNotify) Notify(event observer.Event) { } } -var exporting = false +var ( + exporting = &atomic.Bool{} +) +// tryInitMetadataService will try to initialize metadata service +// TODO (move to somewhere) func tryInitMetadataService() { ms, err := extension.GetMetadataService(config.GetApplicationConfig().MetadataType) @@ -683,11 +688,16 @@ func tryInitMetadataService() { logger.Errorf("could not init metadata service", err) } - if !config.IsProvider() || exporting { + if !config.IsProvider() || exporting.Load() { return } - exporting = true + // In theory, we can use sync.Once + // But sync.Once is not reentrant. + // Now the invocation chain is createRegistry -> tryInitMetadataService -> metadataServiceExporter.export + // -> createRegistry -> initMetadataService... + // So using sync.Once will result in dead lock + exporting.Store(true) expt := configurable.NewMetadataServiceExporter(ms) From 69500606908735823fa09d641e656ea8fb2ab14d Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 16 Jun 2020 11:06:00 +0800 Subject: [PATCH 114/209] fix user images error --- README.md | 2 +- README_CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0de082eeea..26e2ae8cd1 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ If you are using [apache/dubbo-go](github.com/apache/dubbo-go) and think that it - + diff --git a/README_CN.md b/README_CN.md index 05a7a20ba0..9770108eb4 100644 --- a/README_CN.md +++ b/README_CN.md @@ -185,7 +185,7 @@ go test ./... -coverprofile=coverage.txt -covermode=atomic - + From 94636fc27eeb00032e0af71637f699cf3ee653ff Mon Sep 17 00:00:00 2001 From: pantianying <601666418@qq.com> Date: Tue, 16 Jun 2020 14:11:43 +0800 Subject: [PATCH 115/209] add test code --- metadata/report/etcd/report.go | 5 +- metadata/report/etcd/report_test.go | 107 ++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/metadata/report/etcd/report.go b/metadata/report/etcd/report.go index 0ece0e5608..6e36ee7ce6 100644 --- a/metadata/report/etcd/report.go +++ b/metadata/report/etcd/report.go @@ -35,9 +35,8 @@ import ( const DEFAULT_ROOT = "dubbo" func init() { - ftry := &etcdMetadataReportFactory{} extension.SetMetadataReportFactory("etcd", func() factory.MetadataReportFactory { - return ftry + return &etcdMetadataReportFactory{} }) } @@ -137,7 +136,7 @@ func (e *etcdMetadataReportFactory) CreateMetadataReport(url *common.URL) report addresses := strings.Split(url.Location, ",") client, err := etcdv3.NewClient(etcdv3.MetadataETCDV3Client, addresses, timeout, 1) if err != nil { - logger.Errorf("Could not create etcd metadata report. URL: %s", url.String()) + logger.Errorf("Could not create etcd metadata report. URL: %s,error:{%v}", url.String(), err) return nil } group := url.GetParam(constant.GROUP_KEY, DEFAULT_ROOT) diff --git a/metadata/report/etcd/report_test.go b/metadata/report/etcd/report_test.go index 0f61fa4b36..437b6207ee 100644 --- a/metadata/report/etcd/report_test.go +++ b/metadata/report/etcd/report_test.go @@ -16,3 +16,110 @@ */ package etcd + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/coreos/etcd/embed" + "github.com/stretchr/testify/assert" + "net/url" + "strconv" + "testing" +) + +const defaultEtcdV3WorkDir = "/tmp/default-dubbo-go-registry.etcd" + +func initEtcd(t *testing.T) *embed.Etcd { + DefaultListenPeerURLs := "http://localhost:2380" + DefaultListenClientURLs := "http://localhost:2379" + lpurl, _ := url.Parse(DefaultListenPeerURLs) + lcurl, _ := url.Parse(DefaultListenClientURLs) + cfg := embed.NewConfig() + cfg.LPUrls = []url.URL{*lpurl} + cfg.LCUrls = []url.URL{*lcurl} + cfg.Dir = defaultEtcdV3WorkDir + e, err := embed.StartEtcd(cfg) + if err != nil { + t.Fatal(err) + } + return e +} + +func TestEtcdMetadataReportFactory_CreateMetadataReport(t *testing.T) { + e := initEtcd(t) + url, err := common.NewURL("registry://127.0.0.1:2379", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + if err != nil { + t.Fatal(err) + } + metadataReportFactory := &etcdMetadataReportFactory{} + metadataReport := metadataReportFactory.CreateMetadataReport(&url) + assert.NotNil(t, metadataReport) + e.Close() +} + +func TestEtcdMetadataReport_CRUD(t *testing.T) { + e := initEtcd(t) + url, err := common.NewURL("registry://127.0.0.1:2379", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + if err != nil { + t.Fatal(err) + } + metadataReportFactory := &etcdMetadataReportFactory{} + metadataReport := metadataReportFactory.CreateMetadataReport(&url) + assert.NotNil(t, metadataReport) + + err = metadataReport.StoreConsumerMetadata(newMetadataIdentifier("consumer"), "consumer metadata") + assert.Nil(t, err) + + err = metadataReport.StoreProviderMetadata(newMetadataIdentifier("provider"), "provider metadata") + assert.Nil(t, err) + + serviceMi := newServiceMetadataIdentifier() + serviceUrl, _ := common.NewURL("registry://localhost:8848", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) + metadataReport.SaveServiceMetadata(serviceMi, serviceUrl) + assert.Nil(t, err) + + subMi := newSubscribeMetadataIdentifier() + urlList := make([]common.URL, 0, 1) + urlList = append(urlList, serviceUrl) + err = metadataReport.SaveSubscribedData(subMi, urlList) + assert.Nil(t, err) + + err = metadataReport.RemoveServiceMetadata(serviceMi) + assert.Nil(t, err) + + e.Close() +} + +func newSubscribeMetadataIdentifier() *identifier.SubscriberMetadataIdentifier { + return &identifier.SubscriberMetadataIdentifier{ + Revision: "subscribe", + MetadataIdentifier: *newMetadataIdentifier("provider"), + } + +} + +func newServiceMetadataIdentifier() *identifier.ServiceMetadataIdentifier { + return &identifier.ServiceMetadataIdentifier{ + Protocol: "nacos", + Revision: "a", + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: "com.test.MyTest", + Version: "1.0.0", + Group: "test_group", + Side: "service", + }, + } +} + +func newMetadataIdentifier(side string) *identifier.MetadataIdentifier { + return &identifier.MetadataIdentifier{ + Application: "test", + BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{ + ServiceInterface: "com.test.MyTest", + Version: "1.0.0", + Group: "test_group", + Side: side, + }, + } +} From 05a614643ab923e00b53abad379e69ecc43cad68 Mon Sep 17 00:00:00 2001 From: pantianying <601666418@qq.com> Date: Tue, 16 Jun 2020 14:13:47 +0800 Subject: [PATCH 116/209] fix go fmt --- metadata/report/etcd/report.go | 12 +++++++++--- metadata/report/etcd/report_test.go | 16 +++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/metadata/report/etcd/report.go b/metadata/report/etcd/report.go index 6e36ee7ce6..0d49ff1783 100644 --- a/metadata/report/etcd/report.go +++ b/metadata/report/etcd/report.go @@ -19,6 +19,15 @@ package etcd import ( "encoding/json" + "strings" + "time" +) + +import ( + perrors "github.com/pkg/errors" +) + +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" @@ -27,9 +36,6 @@ import ( "github.com/apache/dubbo-go/metadata/report" "github.com/apache/dubbo-go/metadata/report/factory" "github.com/apache/dubbo-go/remoting/etcdv3" - perrors "github.com/pkg/errors" - "strings" - "time" ) const DEFAULT_ROOT = "dubbo" diff --git a/metadata/report/etcd/report_test.go b/metadata/report/etcd/report_test.go index 437b6207ee..8219cb83c7 100644 --- a/metadata/report/etcd/report_test.go +++ b/metadata/report/etcd/report_test.go @@ -18,16 +18,22 @@ package etcd import ( - "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/metadata/identifier" - "github.com/coreos/etcd/embed" - "github.com/stretchr/testify/assert" "net/url" "strconv" "testing" ) +import ( + "github.com/coreos/etcd/embed" + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/metadata/identifier" +) + const defaultEtcdV3WorkDir = "/tmp/default-dubbo-go-registry.etcd" func initEtcd(t *testing.T) *embed.Etcd { From df758dcd3fd8952324dc4bc9576973ee7d245e13 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Tue, 16 Jun 2020 14:40:29 +0800 Subject: [PATCH 117/209] require --> assert --- remoting/zookeeper/client_test.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/remoting/zookeeper/client_test.go b/remoting/zookeeper/client_test.go index d2f231c6b0..34741700ca 100644 --- a/remoting/zookeeper/client_test.go +++ b/remoting/zookeeper/client_test.go @@ -24,7 +24,7 @@ import ( import ( "github.com/dubbogo/go-zookeeper/zk" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" ) import ( @@ -80,7 +80,7 @@ func verifyEventStateOrder(t *testing.T, c <-chan zk.Event, expectedStates []zk. func Test_newMockZookeeperClient(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - require.NoError(t, err) + assert.NoError(t, err) defer ts.Stop() states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") @@ -91,10 +91,10 @@ func Test_newMockZookeeperClient(t *testing.T) { func TestCreate(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - require.NoError(t, err) + assert.NoError(t, err) defer ts.Stop() err = z.Create("test1/test2/test3/test4") - require.NoError(t, err) + assert.NoError(t, err) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") @@ -102,41 +102,41 @@ func TestCreate(t *testing.T) { func TestCreateDelete(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - require.NoError(t, err) + assert.NoError(t, err) defer ts.Stop() states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") err = z.Create("/test1/test2/test3/test4") - require.NoError(t, err) + assert.NoError(t, err) err = z.Delete("/test1/test2/test3/test4") - require.NoError(t, err) + assert.NoError(t, err) // verifyEventOrder(t, event, []zk.EventType{zk.EventNodeCreated}, "event channel") } func TestRegisterTemp(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - require.NoError(t, err) + assert.NoError(t, err) defer ts.Stop() err = z.Create("/test1/test2/test3") - require.NoError(t, err) + assert.NoError(t, err) tmpath, err := z.RegisterTemp("/test1/test2/test3", "test4") - require.NoError(t, err) - require.Equal(t, "/test1/test2/test3/test4", tmpath) + assert.NoError(t, err) + assert.Equal(t, "/test1/test2/test3/test4", tmpath) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") } func TestRegisterTempSeq(t *testing.T) { ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second) - require.NoError(t, err) + assert.NoError(t, err) defer ts.Stop() err = z.Create("/test1/test2/test3") - require.NoError(t, err) + assert.NoError(t, err) tmpath, err := z.RegisterTempSeq("/test1/test2/test3", []byte("test")) - require.NoError(t, err) - require.Equal(t, "/test1/test2/test3/0000000000", tmpath) + assert.NoError(t, err) + assert.Equal(t, "/test1/test2/test3/0000000000", tmpath) states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession} verifyEventStateOrder(t, event, states, "event channel") } From 760fc22a2388f99d027073cfaa892954fa20de3b Mon Sep 17 00:00:00 2001 From: flycash Date: Tue, 16 Jun 2020 23:43:34 +0800 Subject: [PATCH 118/209] Fix Review And UT --- common/constant/key.go | 2 - config/remote_config.go | 8 ++ config/remote_config_test.go | 3 +- config/service_config.go | 12 +- config_center/nacos/impl.go | 7 +- filter/rejected_execution_handler.go | 2 +- metadata/definition/definition.go | 2 + .../identifier/base_metadata_identifier.go | 8 +- metadata/identifier/metadata_identifier.go | 4 +- .../identifier/service_metadata_identifier.go | 7 +- .../subscribe_metadata_identifier.go | 4 +- .../mapping/dynamic/service_name_mapping.go | 18 +-- .../mapping/memory/service_name_mapping.go | 55 ------- metadata/report/nacos/report.go | 4 +- .../service/exporter/configurable/exporter.go | 2 +- .../metadata_service_proxy_factory.go | 13 +- .../metadata_service_proxy_factory_test.go | 68 +++++++++ metadata/service/inmemory/service.go | 5 +- metadata/service/inmemory/service_proxy.go | 4 +- .../service/inmemory/service_proxy_test.go | 82 +++++++++++ metadata/service/remote/service.go | 5 +- metadata/service/remote/service_proxy.go | 5 +- metadata/service/remote/service_proxy_test.go | 135 ++++++++++++++++++ metadata/service/service.go | 2 + protocol/dubbo/client.go | 2 +- registry/base_registry.go | 2 +- registry/consul/registry.go | 11 +- 27 files changed, 368 insertions(+), 104 deletions(-) delete mode 100644 metadata/mapping/memory/service_name_mapping.go create mode 100644 metadata/service/inmemory/service_proxy_test.go create mode 100644 metadata/service/remote/service_proxy_test.go diff --git a/common/constant/key.go b/common/constant/key.go index 07057fa17c..9c59575eb8 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -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" ) diff --git a/config/remote_config.go b/config/remote_config.go index 4d17cc1c41..5e0330c571 100644 --- a/config/remote_config.go +++ b/config/remote_config.go @@ -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 diff --git a/config/remote_config_test.go b/config/remote_config_test.go index 99facb7dda..82535fd60b 100644 --- a/config/remote_config_test.go +++ b/config/remote_config_test.go @@ -19,7 +19,8 @@ package config import ( "testing" - +) +import ( "github.com/stretchr/testify/assert" ) diff --git a/config/service_config.go b/config/service_config.go index 43c53bc9c2..a500a44419 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -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 } diff --git a/config_center/nacos/impl.go b/config_center/nacos/impl.go index 18873f7c4a..bbf707b938 100644 --- a/config_center/nacos/impl.go +++ b/config_center/nacos/impl.go @@ -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 diff --git a/filter/rejected_execution_handler.go b/filter/rejected_execution_handler.go index fc97101095..3d1e1c1e64 100644 --- a/filter/rejected_execution_handler.go +++ b/filter/rejected_execution_handler.go @@ -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. */ diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go index c3b3bd2769..dbbc0c8f16 100644 --- a/metadata/definition/definition.go +++ b/metadata/definition/definition.go @@ -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 { diff --git a/metadata/identifier/base_metadata_identifier.go b/metadata/identifier/base_metadata_identifier.go index 64290c668f..2371f7ca02 100644 --- a/metadata/identifier/base_metadata_identifier.go +++ b/metadata/identifier/base_metadata_identifier.go @@ -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 diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go index 18b330ae08..7e50c4c6b9 100644 --- a/metadata/identifier/metadata_identifier.go +++ b/metadata/identifier/metadata_identifier.go @@ -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) } diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index 7a1bc283dc..b9e65967e0 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -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) } diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index fa35ab79d6..b1e37db971 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -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) } diff --git a/metadata/mapping/dynamic/service_name_mapping.go b/metadata/mapping/dynamic/service_name_mapping.go index 9a8d8299a9..84039ace9a 100644 --- a/metadata/mapping/dynamic/service_name_mapping.go +++ b/metadata/mapping/dynamic/service_name_mapping.go @@ -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 diff --git a/metadata/mapping/memory/service_name_mapping.go b/metadata/mapping/memory/service_name_mapping.go deleted file mode 100644 index ef2e5fa06c..0000000000 --- a/metadata/mapping/memory/service_name_mapping.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 memory - -import ( - "sync" - - gxset "github.com/dubbogo/gost/container/set" - - "github.com/apache/dubbo-go/metadata/mapping" -) - -import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/config" -) - -func init() { - extension.SetGlobalServiceNameMapping(GetNameMappingInstance) -} - -type InMemoryServiceNameMapping struct{} - -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 -} - -var serviceNameMappingInstance *InMemoryServiceNameMapping -var serviceNameMappingOnce sync.Once - -func GetNameMappingInstance() mapping.ServiceNameMapping { - serviceNameMappingOnce.Do(func() { - serviceNameMappingInstance = &InMemoryServiceNameMapping{} - }) - return serviceNameMappingInstance -} diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index a119e0651f..2bf40db519 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -39,9 +39,9 @@ import ( ) func init() { - ftry := &nacosMetadataReportFactory{} + ins := &nacosMetadataReportFactory{} extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory { - return ftry + return ins }) } diff --git a/metadata/service/exporter/configurable/exporter.go b/metadata/service/exporter/configurable/exporter.go index e43fdda886..f8b4b0c017 100644 --- a/metadata/service/exporter/configurable/exporter.go +++ b/metadata/service/exporter/configurable/exporter.go @@ -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() diff --git a/metadata/service/inmemory/metadata_service_proxy_factory.go b/metadata/service/inmemory/metadata_service_proxy_factory.go index 0afadca8e8..1f8eeaa55f 100644 --- a/metadata/service/inmemory/metadata_service_proxy_factory.go +++ b/metadata/service/inmemory/metadata_service_proxy_factory.go @@ -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)) diff --git a/metadata/service/inmemory/metadata_service_proxy_factory_test.go b/metadata/service/inmemory/metadata_service_proxy_factory_test.go index 652169ab78..96020e1eb7 100644 --- a/metadata/service/inmemory/metadata_service_proxy_factory_test.go +++ b/metadata/service/inmemory/metadata_service_proxy_factory_test.go @@ -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 := ®istry.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"}, + } +} diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index ec626f7f43..6fe44cfc71 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -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" ) diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go index 69e349a0f8..840bd9a9d5 100644 --- a/metadata/service/inmemory/service_proxy.go +++ b/metadata/service/inmemory/service_proxy.go @@ -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 diff --git a/metadata/service/inmemory/service_proxy_test.go b/metadata/service/inmemory/service_proxy_test.go new file mode 100644 index 0000000000..0d75517e41 --- /dev/null +++ b/metadata/service/inmemory/service_proxy_test.go @@ -0,0 +1,82 @@ +/* + * 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 inmemory + +import ( + "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/metadata/service" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/registry" +) + +func TestMetadataServiceProxy_GetExportedURLs(t *testing.T) { + + 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) + +} + +// 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) + +} + +func createPxy() service.MetadataService { + extension.SetProtocol("mock", func() protocol.Protocol { + return &mockProtocol{} + }) + + ins := ®istry.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) +} diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index fa00a8dc2a..af9d1f0079 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -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" diff --git a/metadata/service/remote/service_proxy.go b/metadata/service/remote/service_proxy.go index 5e37d39fd4..b7fe6f4685 100644 --- a/metadata/service/remote/service_proxy.go +++ b/metadata/service/remote/service_proxy.go @@ -19,7 +19,8 @@ package remote import ( "strings" - +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" @@ -141,7 +142,7 @@ func newMetadataServiceProxy(ins registry.ServiceInstance) service.MetadataServi } func parse(key string) []string { - arr := make([]string, 0, 3) + arr := make([]string, 3, 3) tmp := strings.SplitN(key, "/", 2) if len(tmp) > 1 { arr[0] = tmp[0] diff --git a/metadata/service/remote/service_proxy_test.go b/metadata/service/remote/service_proxy_test.go new file mode 100644 index 0000000000..31a9ba1fd1 --- /dev/null +++ b/metadata/service/remote/service_proxy_test.go @@ -0,0 +1,135 @@ +/* + * 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 remote + +import ( + "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/config/instance" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" +) + +func TestMetadataServiceProxy_GetExportedURLs(t *testing.T) { + pxy := createProxy() + res, err := pxy.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + assert.Nil(t, err) + assert.Len(t, res, 2) +} + +func TestMetadataServiceProxy_GetServiceDefinition(t *testing.T) { + pxy := createProxy() + res, err := pxy.GetServiceDefinition(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) + assert.Nil(t, err) + assert.Equal(t, "definition", res) +} + +// TestMetadataServiceProxy test those unimportant method +// in fact, we don't use them +func TestMetadataServiceProxy(t *testing.T) { + pxy := createProxy() + pxy.ServiceName() + pxy.PublishServiceDefinition(common.URL{}) + 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.Reference() + pxy.RefreshMetadata(constant.ANY_VALUE, constant.ANY_VALUE) +} + +func createProxy() service.MetadataService { + + prepareTest() + + ins := ®istry.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 newMetadataServiceProxy(ins) +} + +func prepareTest() { + extension.SetMetadataReportFactory("mock", func() factory.MetadataReportFactory { + return &mockMetadataReportFactory{} + }) + u, _ := common.NewURL("mock://localhost") + instance.GetMetadataReportInstance(&u) +} + +type mockMetadataReportFactory struct { +} + +func (m *mockMetadataReportFactory) CreateMetadataReport(*common.URL) report.MetadataReport { + return &mockMetadataReport{} +} + +type mockMetadataReport struct { +} + +func (m mockMetadataReport) StoreProviderMetadata(*identifier.MetadataIdentifier, string) error { + panic("implement me") +} + +func (m mockMetadataReport) StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error { + panic("implement me") +} + +func (m mockMetadataReport) SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error { + panic("implement me") +} + +func (m mockMetadataReport) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error { + panic("implement me") +} + +func (m mockMetadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string { + return []string{"mock://localhost1", "mock://localhost2"} +} + +func (m mockMetadataReport) SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []common.URL) error { + panic("implement me") +} + +func (m mockMetadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string { + panic("implement me") +} + +func (m mockMetadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) string { + return "definition" +} diff --git a/metadata/service/service.go b/metadata/service/service.go index ae04858247..f6509d0a72 100644 --- a/metadata/service/service.go +++ b/metadata/service/service.go @@ -19,7 +19,9 @@ package service import ( "sync" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index 981f295b39..6d1b771bf4 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -280,7 +280,7 @@ func (c *Client) call(ct CallType, request *Request, response *Response, callbac } select { - case <-getty.GetTimeWheel().After(3 * time.Second): + case <-getty.GetTimeWheel().After(c.opts.RequestTimeout): c.removePendingResponse(SequenceType(rsp.seq)) return perrors.WithStack(errClientReadTimeout) case <-rsp.done: diff --git a/registry/base_registry.go b/registry/base_registry.go index 504e087091..ad1a3b6174 100644 --- a/registry/base_registry.go +++ b/registry/base_registry.go @@ -92,7 +92,7 @@ type FacadeBasedRegistry interface { InitListeners() } -// BaseRegistry is a event logic abstract for registry. It implement Registry interface. +// BaseRegistry is a common logic abstract for registry. It implement Registry interface. type BaseRegistry struct { context context.Context facadeBasedRegistry FacadeBasedRegistry diff --git a/registry/consul/registry.go b/registry/consul/registry.go index c9e0718346..bd394be443 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -74,6 +74,8 @@ func newConsulRegistry(url *common.URL) (registry.Registry, error) { return r, nil } +// Register register @url +// it delegate the job to register() method func (r *consulRegistry) Register(url common.URL) error { var err error @@ -87,6 +89,7 @@ func (r *consulRegistry) Register(url common.URL) error { return nil } +// register actually register the @url func (r *consulRegistry) register(url common.URL) error { service, err := buildService(url) if err != nil { @@ -95,6 +98,8 @@ func (r *consulRegistry) register(url common.URL) error { return r.client.Agent().ServiceRegister(service) } +// UnRegister unregister the @url +// it delegate the job to unregister() method func (r *consulRegistry) UnRegister(url common.URL) error { var err error @@ -108,10 +113,12 @@ func (r *consulRegistry) UnRegister(url common.URL) error { return nil } +// unregister actually unregister the @url func (r *consulRegistry) unregister(url common.URL) error { return r.client.Agent().ServiceDeregister(buildId(url)) } +// Subscribe subscribe the @url with the @notifyListener func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) error { role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, "")) if role == common.CONSUMER { @@ -120,11 +127,13 @@ func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.Noti return nil } -// UnSubscribe : +// UnSubscribe is not supported yet func (r *consulRegistry) UnSubscribe(url *common.URL, notifyListener registry.NotifyListener) error { return perrors.New("UnSubscribe not support in consulRegistry") } +// subscribe actually subscribe the @url +// it loops forever until success func (r *consulRegistry) subscribe(url *common.URL, notifyListener registry.NotifyListener) { for { if !r.IsAvailable() { From b83f86aaa951e296f8eb038c06378eb15af9e3d3 Mon Sep 17 00:00:00 2001 From: flycash Date: Wed, 17 Jun 2020 22:53:00 +0800 Subject: [PATCH 119/209] Fix Review And Add UT --- go.mod | 4 +- go.sum | 6 +- metadata/service/remote/service.go | 2 +- metadata/service/remote/service_proxy_test.go | 4 +- metadata/service/remote/service_test.go | 10 +- .../customizable_service_instance_listener.go | 10 +- ...omizable_service_instance_listener_test.go | 76 ++++++ ...vent_publishing_service_deiscovery_test.go | 20 +- .../event_publishing_service_discovery.go | 23 +- registry/event/log_event_listener.go | 2 + registry/event/log_event_listener_test.go | 2 + .../metadata_service_url_params_customizer.go | 4 + ...data_service_url_params_customizer_test.go | 124 +++++++++ .../protocol_ports_metadata_customizer.go | 8 +- .../event/service_config_exported_event.go | 4 + registry/event/service_discovery_event.go | 4 + registry/event/service_instance_event.go | 3 + .../event/service_name_mapping_listener.go | 12 +- registry/event/service_revision_customizer.go | 4 + registry/event_listener.go | 8 +- registry/inmemory/service_discovery.go | 161 ------------ registry/inmemory/service_discovery_test.go | 98 -------- registry/nacos/registry.go | 7 +- registry/nacos/service_discovery.go | 7 +- registry/nacos/service_discovery_test.go | 3 +- .../service_discovery_registry.go | 4 + .../service_discovery_registry_test.go | 237 ++++++++++++++++-- .../subscribed_urls_synthesizer.go | 4 +- .../subscribed_urls_synthesizer_factory.go | 2 + remoting/nacos/builder.go | 13 +- 30 files changed, 533 insertions(+), 333 deletions(-) create mode 100644 registry/event/customizable_service_instance_listener_test.go create mode 100644 registry/event/metadata_service_url_params_customizer_test.go delete mode 100644 registry/inmemory/service_discovery.go delete mode 100644 registry/inmemory/service_discovery_test.go diff --git a/go.mod b/go.mod index 5a7efac66d..f4318e5a5d 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/magiconair/properties v1.8.1 github.com/mitchellh/mapstructure v1.1.2 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd - github.com/nacos-group/nacos-sdk-go v0.3.1 + github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.1.0 @@ -56,5 +56,3 @@ require ( ) go 1.13 - -replace github.com/nacos-group/nacos-sdk-go => /Users/mindeng/go-workspace/src/nacos-sdk-go diff --git a/go.sum b/go.sum index 65f2b7c7b1..93bca6b976 100644 --- a/go.sum +++ b/go.sum @@ -388,8 +388,8 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.3.1 h1:MI7bNDAN5m9UFcRRUTSPfJi4dCQo+TYG85qVB1rCHeg= -github.com/nacos-group/nacos-sdk-go v0.3.1/go.mod h1:ESKb6yF0gxSc8GuS+0jaMBe+n8rJ5/k4ya6LyFG2xi8= +github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f h1:gid5/0AkHvINWK69Fgbidb3BVIXqlf1YEm7wO0NVPsw= +github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f/go.mod h1:fti1GlX/EB6RDKvzK/P7Vuibqj0JMPJHQwrcTU1tLXk= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0= @@ -457,8 +457,6 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go index af9d1f0079..ae83a69bef 100644 --- a/metadata/service/remote/service.go +++ b/metadata/service/remote/service.go @@ -93,7 +93,7 @@ func (mts *MetadataService) ExportURL(url common.URL) (bool, error) { return mts.inMemoryMetadataService.ExportURL(url) } -// UnexportURL +// UnexportURL remove @url's metadata func (mts *MetadataService) UnexportURL(url common.URL) error { smi := identifier.NewServiceMetadataIdentifier(url) smi.Revision = mts.exportedRevision.Load() diff --git a/metadata/service/remote/service_proxy_test.go b/metadata/service/remote/service_proxy_test.go index 31a9ba1fd1..ca9137fe59 100644 --- a/metadata/service/remote/service_proxy_test.go +++ b/metadata/service/remote/service_proxy_test.go @@ -111,7 +111,7 @@ func (m mockMetadataReport) StoreConsumerMetadata(*identifier.MetadataIdentifier } func (m mockMetadataReport) SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error { - panic("implement me") + return nil } func (m mockMetadataReport) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error { @@ -123,7 +123,7 @@ func (m mockMetadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifie } func (m mockMetadataReport) SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []common.URL) error { - panic("implement me") + return nil } func (m mockMetadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string { diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 2bf1c4c6c0..1c07d9d9c7 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -38,8 +38,10 @@ import ( "github.com/apache/dubbo-go/metadata/service/inmemory" ) -var serviceMetadata = make(map[*identifier.ServiceMetadataIdentifier]common.URL, 4) -var subscribedMetadata = make(map[*identifier.SubscriberMetadataIdentifier][]common.URL, 4) +var ( + serviceMetadata = make(map[*identifier.ServiceMetadataIdentifier]common.URL, 4) + subscribedMetadata = make(map[*identifier.SubscriberMetadataIdentifier][]common.URL, 4) +) func getMetadataReportFactory() factory.MetadataReportFactory { return &metadataReportFactory{} @@ -100,9 +102,7 @@ func TestMetadataService(t *testing.T) { mts, err := newMetadataService() assert.NoError(t, err) mts.(*MetadataService).setInMemoryMetadataService(mockInmemoryProc(t)) - mts.RefreshMetadata("0.0.1", "0.0.1") - assert.Equal(t, 1, len(serviceMetadata)) - assert.Equal(t, 1, len(subscribedMetadata)) + _, _ = mts.RefreshMetadata("0.0.1", "0.0.1") } func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { diff --git a/registry/event/customizable_service_instance_listener.go b/registry/event/customizable_service_instance_listener.go index 89d1621974..07e84c1454 100644 --- a/registry/event/customizable_service_instance_listener.go +++ b/registry/event/customizable_service_instance_listener.go @@ -20,7 +20,9 @@ package event import ( "reflect" "sync" +) +import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" ) @@ -56,9 +58,13 @@ func (c *customizableServiceInstanceListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancePreRegisteredEvent{}) } -var customizableServiceInstanceListenerInstance *customizableServiceInstanceListener -var customizableServiceInstanceListenerOnce sync.Once +var ( + customizableServiceInstanceListenerInstance *customizableServiceInstanceListener + customizableServiceInstanceListenerOnce sync.Once +) +// GetCustomizableServiceInstanceListener returns an instance +// if the instance was not initialized, we create one func GetCustomizableServiceInstanceListener() observer.EventListener { customizableServiceInstanceListenerOnce.Do(func() { customizableServiceInstanceListenerInstance = &customizableServiceInstanceListener{} diff --git a/registry/event/customizable_service_instance_listener_test.go b/registry/event/customizable_service_instance_listener_test.go new file mode 100644 index 0000000000..1c81ece498 --- /dev/null +++ b/registry/event/customizable_service_instance_listener_test.go @@ -0,0 +1,76 @@ +/* + * 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 event + +import ( + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/registry" +) + +func TestGetCustomizableServiceInstanceListener(t *testing.T) { + + prepareMetadataServiceForTest() + + cus := GetCustomizableServiceInstanceListener() + + assert.Equal(t, 9999, cus.GetPriority()) + + extension.AddCustomizers(&mockCustomizer{}) + + err := cus.OnEvent(&mockEvent{}) + assert.Nil(t, err) + err = cus.OnEvent(NewServiceInstancePreRegisteredEvent("hello", createInstance())) + assert.Nil(t, err) + + tp := cus.GetEventType() + assert.NotNil(t, tp) +} + +type mockEvent struct { +} + +func (m *mockEvent) String() string { + panic("implement me") +} + +func (m *mockEvent) GetSource() interface{} { + panic("implement me") +} + +func (m *mockEvent) GetTimestamp() time.Time { + panic("implement me") +} + +type mockCustomizer struct { +} + +func (m *mockCustomizer) GetPriority() int { + return 0 +} + +func (m *mockCustomizer) Customize(instance registry.ServiceInstance) { +} diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index 21bddb7f04..8020702080 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -21,8 +21,7 @@ import ( "reflect" "testing" - "github.com/apache/dubbo-go/config" - _ "github.com/apache/dubbo-go/metadata/service/inmemory" + "github.com/apache/dubbo-go/metadata/mapping" ) import ( @@ -36,6 +35,8 @@ import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" dispatcher2 "github.com/apache/dubbo-go/common/observer/dispatcher" + "github.com/apache/dubbo-go/config" + _ "github.com/apache/dubbo-go/metadata/service/inmemory" "github.com/apache/dubbo-go/registry" ) @@ -45,6 +46,10 @@ func TestEventPublishingServiceDiscovery_DispatchEvent(t *testing.T) { config.GetApplicationConfig().MetadataType = "local" + extension.SetGlobalServiceNameMapping(func() mapping.ServiceNameMapping { + return &mockServiceNameMapping{} + }) + dc := NewEventPublishingServiceDiscovery(&ServiceDiscoveryA{}) tsd := &TestServiceDiscoveryDestroyingEventListener{ BaseListener: observer.NewBaseListener(), @@ -173,3 +178,14 @@ func (msd *ServiceDiscoveryA) DispatchEventForInstances(serviceName string, inst func (msd *ServiceDiscoveryA) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { return nil } + +type mockServiceNameMapping struct { +} + +func (m *mockServiceNameMapping) Map(serviceInterface string, group string, version string, protocol string) error { + return nil +} + +func (m *mockServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { + return gxset.NewSet("dubbo"), nil +} diff --git a/registry/event/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go index 496eb9b4a5..3ee2f4a449 100644 --- a/registry/event/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -20,14 +20,13 @@ package event import ( gxset "github.com/dubbogo/gost/container/set" gxpage "github.com/dubbogo/gost/page" - - "github.com/apache/dubbo-go/config" - "github.com/apache/dubbo-go/metadata/service" ) import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/registry" ) @@ -44,7 +43,7 @@ func NewEventPublishingServiceDiscovery(serviceDiscovery registry.ServiceDiscove } } -// String +// String returns serviceDiscovery.String() func (epsd *EventPublishingServiceDiscovery) String() string { return epsd.serviceDiscovery.String() } @@ -68,7 +67,7 @@ func (epsd *EventPublishingServiceDiscovery) Register(instance registry.ServiceI } -// Update delegate function +// Update returns the result of serviceDiscovery.Update func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceInstance) error { f := func() error { return epsd.serviceDiscovery.Update(instance) @@ -76,7 +75,7 @@ func (epsd *EventPublishingServiceDiscovery) Update(instance registry.ServiceIns return epsd.executeWithEvents(nil, f, nil) } -// Unregister delegate function +// Unregister unregister the instance and drop ServiceInstancePreUnregisteredEvent and ServiceInstanceUnregisteredEvent func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.ServiceInstance) error { f := func() error { return epsd.serviceDiscovery.Unregister(instance) @@ -85,26 +84,32 @@ func (epsd *EventPublishingServiceDiscovery) Unregister(instance registry.Servic f, NewServiceInstanceUnregisteredEvent(epsd.serviceDiscovery, instance)) } +// GetDefaultPageSize returns the result of serviceDiscovery.GetDefaultPageSize func (epsd *EventPublishingServiceDiscovery) GetDefaultPageSize() int { return epsd.serviceDiscovery.GetDefaultPageSize() } +// GetServices returns the result of serviceDiscovery.GetServices func (epsd *EventPublishingServiceDiscovery) GetServices() *gxset.HashSet { return epsd.serviceDiscovery.GetServices() } +// GetInstances returns the result of serviceDiscovery.GetInstances func (epsd *EventPublishingServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { return epsd.serviceDiscovery.GetInstances(serviceName) } +// GetInstancesByPage returns the result of serviceDiscovery.GetInstancesByPage func (epsd *EventPublishingServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { return epsd.serviceDiscovery.GetInstancesByPage(serviceName, offset, pageSize) } +// GetHealthyInstancesByPage returns the result of serviceDiscovery.GetHealthyInstancesByPage func (epsd *EventPublishingServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { return epsd.serviceDiscovery.GetHealthyInstancesByPage(serviceName, offset, pageSize, healthy) } +// GetRequestInstances returns result from serviceDiscovery.GetRequestInstances func (epsd *EventPublishingServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { return epsd.serviceDiscovery.GetRequestInstances(serviceNames, offset, requestedSize) } @@ -115,14 +120,17 @@ func (epsd *EventPublishingServiceDiscovery) AddListener(listener *registry.Serv return epsd.serviceDiscovery.AddListener(listener) } +// DispatchEventByServiceName pass serviceName to serviceDiscovery func (epsd *EventPublishingServiceDiscovery) DispatchEventByServiceName(serviceName string) error { - return epsd.DispatchEventByServiceName(serviceName) + return epsd.serviceDiscovery.DispatchEventByServiceName(serviceName) } +// DispatchEventForInstances pass params to serviceDiscovery func (epsd *EventPublishingServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { return epsd.serviceDiscovery.DispatchEventForInstances(serviceName, instances) } +// DispatchEvent pass the event to serviceDiscovery func (epsd *EventPublishingServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { return epsd.serviceDiscovery.DispatchEvent(event) } @@ -143,6 +151,7 @@ func (epsd *EventPublishingServiceDiscovery) executeWithEvents(beforeEvent obser return nil } +// getMetadataService returns metadata service instance func getMetadataService() (service.MetadataService, error) { return extension.GetMetadataService(config.GetApplicationConfig().MetadataType) } diff --git a/registry/event/log_event_listener.go b/registry/event/log_event_listener.go index a06d5e4499..0781a6d6db 100644 --- a/registry/event/log_event_listener.go +++ b/registry/event/log_event_listener.go @@ -20,7 +20,9 @@ package event import ( "reflect" "sync" +) +import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/common/observer" diff --git a/registry/event/log_event_listener_test.go b/registry/event/log_event_listener_test.go index f142168b65..3136564687 100644 --- a/registry/event/log_event_listener_test.go +++ b/registry/event/log_event_listener_test.go @@ -19,7 +19,9 @@ package event import ( "testing" +) +import ( "github.com/stretchr/testify/assert" ) diff --git a/registry/event/metadata_service_url_params_customizer.go b/registry/event/metadata_service_url_params_customizer.go index 06278f4e77..6d8f99b327 100644 --- a/registry/event/metadata_service_url_params_customizer.go +++ b/registry/event/metadata_service_url_params_customizer.go @@ -19,9 +19,13 @@ package event import ( "encoding/json" +) +import ( gxset "github.com/dubbogo/gost/container/set" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" diff --git a/registry/event/metadata_service_url_params_customizer_test.go b/registry/event/metadata_service_url_params_customizer_test.go new file mode 100644 index 0000000000..98ae2df883 --- /dev/null +++ b/registry/event/metadata_service_url_params_customizer_test.go @@ -0,0 +1,124 @@ +/* + * 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 event + +import ( + "testing" +) + +import ( + gxset "github.com/dubbogo/gost/container/set" + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "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/registry" +) + +func prepareMetadataServiceForTest() { + config.GetApplicationConfig().MetadataType = "mock" + extension.SetMetadataService("mock", func() (service.MetadataService, error) { + return &mockMetadataService{ + urls: []interface{}{"mock://localhost:8080?a=b"}, + }, nil + }) +} + +func TestMetadataServiceURLParamsMetadataCustomizer(t *testing.T) { + + prepareMetadataServiceForTest() + + msup := &metadataServiceURLParamsMetadataCustomizer{exceptKeys: gxset.NewSet()} + assert.Equal(t, 0, msup.GetPriority()) + + msup.Customize(createInstance()) +} + +func createInstance() registry.ServiceInstance { + ins := ®istry.DefaultServiceInstance{} + return ins +} + +type mockMetadataService struct { + urls []interface{} +} + +func (m *mockMetadataService) Reference() string { + panic("implement me") +} + +func (m *mockMetadataService) ServiceName() (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) ExportURL(url common.URL) (bool, error) { + panic("implement me") +} + +func (m *mockMetadataService) UnexportURL(url common.URL) error { + panic("implement me") +} + +func (m *mockMetadataService) SubscribeURL(url common.URL) (bool, error) { + panic("implement me") +} + +func (m *mockMetadataService) UnsubscribeURL(url common.URL) error { + panic("implement me") +} + +func (m *mockMetadataService) PublishServiceDefinition(url common.URL) error { + panic("implement me") +} + +func (m *mockMetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { + return m.urls, nil +} + +func (m *mockMetadataService) MethodMapper() map[string]string { + panic("implement me") +} + +func (m *mockMetadataService) GetSubscribedURLs() ([]common.URL, error) { + res := make([]common.URL, 0, len(m.urls)) + for _, ui := range m.urls { + u, _ := common.NewURL(ui.(string)) + res = append(res, u) + } + return res, nil +} + +func (m *mockMetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { + panic("implement me") +} + +func (m *mockMetadataService) Version() (string, error) { + return "1.0.0", nil +} diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index dd7f7678fc..cf5d1a8ec1 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -20,7 +20,9 @@ package event import ( "encoding/json" "strconv" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" @@ -41,7 +43,7 @@ func (p *ProtocolPortsMetadataCustomizer) GetPriority() int { return 0 } -// Customize will +// Customize put the the string like [{"protocol": "dubbo", "port": 123}] into instance's metadata func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceInstance) { metadataService, err := getMetadataService() if err != nil { @@ -49,7 +51,7 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns return } - // 4 is enough... + // 4 is enough... we don't have many protocol protocolMap := make(map[string]int, 4) list, err := metadataService.GetExportedURLs(constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE, constant.ANY_VALUE) @@ -75,6 +77,7 @@ func (p *ProtocolPortsMetadataCustomizer) Customize(instance registry.ServiceIns instance.GetMetadata()[constant.SERVICE_INSTANCE_ENDPOINTS] = endpointsStr(protocolMap) } +// endpointsStr convert the map to json like [{"protocol": "dubbo", "port": 123}] func endpointsStr(protocolMap map[string]int) string { if len(protocolMap) == 0 { return "" @@ -96,6 +99,7 @@ func endpointsStr(protocolMap map[string]int) string { return string(str) } +// nolint type endpoint struct { Port int `json:"port"` Protocol string `json:"protocol"` diff --git a/registry/event/service_config_exported_event.go b/registry/event/service_config_exported_event.go index 7946609acd..5ec027da31 100644 --- a/registry/event/service_config_exported_event.go +++ b/registry/event/service_config_exported_event.go @@ -19,16 +19,20 @@ package event import ( "time" +) +import ( "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/config" ) +// ServiceConfigExportedEvent represents an service was exported type ServiceConfigExportedEvent struct { observer.BaseEvent ServiceConfig *config.ServiceConfig } +// NewServiceConfigExportedEvent create an instance func NewServiceConfigExportedEvent(serviceConfig *config.ServiceConfig) *ServiceConfigExportedEvent { return &ServiceConfigExportedEvent{ BaseEvent: observer.BaseEvent{ diff --git a/registry/event/service_discovery_event.go b/registry/event/service_discovery_event.go index 74f6c5f19d..13afa1a6aa 100644 --- a/registry/event/service_discovery_event.go +++ b/registry/event/service_discovery_event.go @@ -22,11 +22,13 @@ import ( "github.com/apache/dubbo-go/registry" ) +// ServiceDiscoveryEvent means that something happens to service discovery instance type ServiceDiscoveryEvent struct { observer.BaseEvent original registry.ServiceDiscovery } +// NewServiceDiscoveryEvent returns an instance func NewServiceDiscoveryEvent(discovery registry.ServiceDiscovery, original registry.ServiceDiscovery) *ServiceDiscoveryEvent { return &ServiceDiscoveryEvent{ BaseEvent: *observer.NewBaseEvent(discovery), @@ -34,10 +36,12 @@ func NewServiceDiscoveryEvent(discovery registry.ServiceDiscovery, original regi } } +// GetServiceDiscovery returns the event source func (sde *ServiceDiscoveryEvent) GetServiceDiscovery() registry.ServiceDiscovery { return sde.GetSource().(registry.ServiceDiscovery) } +// GetOriginal actually I think we can remove this method. func (sde *ServiceDiscoveryEvent) GetOriginal() registry.ServiceDiscovery { return sde.original } diff --git a/registry/event/service_instance_event.go b/registry/event/service_instance_event.go index 650b2e8e29..d4f23c299a 100644 --- a/registry/event/service_instance_event.go +++ b/registry/event/service_instance_event.go @@ -22,6 +22,8 @@ import ( "github.com/apache/dubbo-go/registry" ) +// ServiceInstanceEvent means something happen to this ServiceInstance +// like register this service instance type ServiceInstanceEvent struct { observer.BaseEvent serviceInstance registry.ServiceInstance @@ -35,6 +37,7 @@ func NewServiceInstanceEvent(source interface{}, instance registry.ServiceInstan } } +// getServiceInstance return the service instance func (sie *ServiceInstanceEvent) getServiceInstance() registry.ServiceInstance { return sie.serviceInstance } diff --git a/registry/event/service_name_mapping_listener.go b/registry/event/service_name_mapping_listener.go index 68cf588c66..a4ac8b28db 100644 --- a/registry/event/service_name_mapping_listener.go +++ b/registry/event/service_name_mapping_listener.go @@ -20,9 +20,13 @@ package event import ( "reflect" "sync" +) +import ( perrors "github.com/pkg/errors" +) +import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" @@ -30,9 +34,12 @@ import ( ) func init() { - extension.AddEventListener(GetCustomizableServiceInstanceListener) + extension.AddEventListener(GetServiceNameMappingListener) } +// serviceNameMappingListener listen to service name mapping event +// usually it means that we exported some service +// it's a singleton type serviceNameMappingListener struct { nameMapping mapping.ServiceNameMapping } @@ -42,6 +49,7 @@ func (s *serviceNameMappingListener) GetPriority() int { return 3 } +// OnEvent only handle ServiceConfigExportedEvent func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { if ex, ok := e.(*ServiceConfigExportedEvent); ok { sc := ex.ServiceConfig @@ -60,6 +68,7 @@ func (s *serviceNameMappingListener) OnEvent(e observer.Event) error { return nil } +// GetEventType return ServiceConfigExportedEvent func (s *serviceNameMappingListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceConfigExportedEvent{}) } @@ -69,6 +78,7 @@ var ( serviceNameMappingListenerOnce sync.Once ) +// GetServiceNameMappingListener returns an instance func GetServiceNameMappingListener() observer.EventListener { serviceNameMappingListenerOnce.Do(func() { serviceNameMappingListenerInstance = &serviceNameMappingListener{ diff --git a/registry/event/service_revision_customizer.go b/registry/event/service_revision_customizer.go index fb1cda01a5..fd21e8f4c7 100644 --- a/registry/event/service_revision_customizer.go +++ b/registry/event/service_revision_customizer.go @@ -21,7 +21,9 @@ import ( "fmt" "hash/crc32" "sort" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" @@ -45,6 +47,7 @@ func (e *exportedServicesRevisionMetadataCustomizer) GetPriority() int { return 1 } +// Customize calculate the revision for exported urls and then put it into instance metadata func (e *exportedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { ms, err := getMetadataService() if err != nil { @@ -73,6 +76,7 @@ func (e *subscribedServicesRevisionMetadataCustomizer) GetPriority() int { return 2 } +// Customize calculate the revision for subscribed urls and then put it into instance metadata func (e *subscribedServicesRevisionMetadataCustomizer) Customize(instance registry.ServiceInstance) { ms, err := getMetadataService() if err != nil { diff --git a/registry/event_listener.go b/registry/event_listener.go index 1cd5ad43a6..9e9ec2d5d4 100644 --- a/registry/event_listener.go +++ b/registry/event_listener.go @@ -31,13 +31,13 @@ type ServiceInstancesChangedListener struct { ChangedNotify observer.ChangedNotify } -// On ServiceInstancesChangedEvent the service instances change event +// OnEvent on ServiceInstancesChangedEvent the service instances change event func (lstn *ServiceInstancesChangedListener) OnEvent(e observer.Event) error { lstn.ChangedNotify.Notify(e) return nil } -// return true if the name is the same +// Accept return true if the name is the same func (lstn *ServiceInstancesChangedListener) Accept(e observer.Event) bool { if ce, ok := e.(*ServiceInstancesChangedEvent); ok { return ce.ServiceName == lstn.ServiceName @@ -45,12 +45,12 @@ func (lstn *ServiceInstancesChangedListener) Accept(e observer.Event) bool { return false } -// get listener priority +// GetPriority returns -1, it will be the first invoked listener func (lstn *ServiceInstancesChangedListener) GetPriority() int { return -1 } -// get event type +// GetEventType returns ServiceInstancesChangedEvent func (lstn *ServiceInstancesChangedListener) GetEventType() reflect.Type { return reflect.TypeOf(&ServiceInstancesChangedEvent{}) } diff --git a/registry/inmemory/service_discovery.go b/registry/inmemory/service_discovery.go deleted file mode 100644 index f7c3ef3bb5..0000000000 --- a/registry/inmemory/service_discovery.go +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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 inmemory - -import ( - "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/page" -) - -import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/registry" -) - -const ( - name = "in-memory" -) - -func init() { - - instance := &InMemoryServiceDiscovery{ - instances: make(map[string]registry.ServiceInstance, 4), - listeners: make([]*registry.ServiceInstancesChangedListener, 0, 2), - } - - extension.SetServiceDiscovery(name, func(name string) (discovery registry.ServiceDiscovery, err error) { - return instance, nil - }) -} - -// InMemoryServiceDiscovery is an implementation based on memory. -// Usually you will not use this implementation except for tests. -type InMemoryServiceDiscovery struct { - instances map[string]registry.ServiceInstance - listeners []*registry.ServiceInstancesChangedListener -} - -func (i *InMemoryServiceDiscovery) String() string { - return name -} - -// Destroy doesn't destroy the instance, it just clear the instances -func (i *InMemoryServiceDiscovery) Destroy() error { - // reset to empty - i.instances = make(map[string]registry.ServiceInstance, 4) - i.listeners = make([]*registry.ServiceInstancesChangedListener, 0, 2) - return nil -} - -// Register will store the instance using its id as key -func (i *InMemoryServiceDiscovery) Register(instance registry.ServiceInstance) error { - i.instances[instance.GetId()] = instance - return nil -} - -// Update will act like register -func (i *InMemoryServiceDiscovery) Update(instance registry.ServiceInstance) error { - return i.Register(instance) -} - -// Unregister will remove the instance -func (i *InMemoryServiceDiscovery) Unregister(instance registry.ServiceInstance) error { - delete(i.instances, instance.GetId()) - return nil -} - -// GetDefaultPageSize will return the default page size -func (i *InMemoryServiceDiscovery) GetDefaultPageSize() int { - return registry.DefaultPageSize -} - -// GetServices will return all service names -func (i *InMemoryServiceDiscovery) GetServices() *gxset.HashSet { - result := gxset.NewSet() - for _, value := range i.instances { - result.Add(value.GetServiceName()) - } - return result -} - -// GetInstances will find out all instances with serviceName -func (i *InMemoryServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { - result := make([]registry.ServiceInstance, 0, len(i.instances)) - for _, value := range i.instances { - if value.GetServiceName() == serviceName { - result = append(result, value) - } - } - return result -} - -// GetInstancesByPage will return the part of instances -func (i *InMemoryServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { - instances := i.GetInstances(serviceName) - // we can not use []registry.ServiceInstance since New(...) received []interface{} as parameter - result := make([]interface{}, 0, pageSize) - for i := offset; i < len(instances) && i < offset+pageSize; i++ { - result = append(result, instances[i]) - } - return gxpage.New(offset, pageSize, result, len(instances)) -} - -// GetHealthyInstancesByPage will return the instances -func (i *InMemoryServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { - instances := i.GetInstances(serviceName) - // we can not use []registry.ServiceInstance since New(...) received []interface{} as parameter - result := make([]interface{}, 0, pageSize) - count := 0 - for i := offset; i < len(instances) && count < pageSize; i++ { - if instances[i].IsHealthy() == healthy { - result = append(result, instances[i]) - count++ - } - } - return gxpage.New(offset, pageSize, result, len(instances)) -} - -// GetRequestInstances will iterate the serviceName and aggregate them -func (i *InMemoryServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { - res := make(map[string]gxpage.Pager, len(serviceNames)) - for _, name := range serviceNames { - res[name] = i.GetInstancesByPage(name, offset, requestedSize) - } - return res -} - -// AddListener will save the listener inside the memory -func (i *InMemoryServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { - i.listeners = append(i.listeners, listener) - return nil -} - -// DispatchEventByServiceName will do nothing -func (i *InMemoryServiceDiscovery) DispatchEventByServiceName(serviceName string) error { - return nil -} - -// DispatchEventForInstances will do nothing -func (i *InMemoryServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { - return nil -} - -// DispatchEvent will do nothing -func (i *InMemoryServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { - return nil -} diff --git a/registry/inmemory/service_discovery_test.go b/registry/inmemory/service_discovery_test.go deleted file mode 100644 index fac4699913..0000000000 --- a/registry/inmemory/service_discovery_test.go +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 inmemory - -import ( - "testing" -) - -import ( - "github.com/stretchr/testify/assert" -) - -import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/registry" -) - -func TestInMemoryServiceDiscovery(t *testing.T) { - discovery, _ := extension.GetServiceDiscovery(name, "in") - serviceName := "my-service" - err := discovery.Register(®istry.DefaultServiceInstance{ - ServiceName: serviceName, - Id: "1", - Healthy: true, - }) - assert.Nil(t, err) - - err = discovery.Register(®istry.DefaultServiceInstance{ - Id: "2", - ServiceName: "mock-service", - Healthy: false, - }) - - assert.Nil(t, err) - - services := discovery.GetServices() - assert.Equal(t, 2, services.Size()) - assert.Equal(t, registry.DefaultPageSize, discovery.GetDefaultPageSize()) - - reqInstances := discovery.GetRequestInstances([]string{serviceName, "mock-service"}, 0, 10) - assert.Equal(t, 2, len(reqInstances)) - - page := discovery.GetInstancesByPage(serviceName, 0, 10) - assert.Equal(t, 1, page.GetDataSize()) - - discovery.GetHealthyInstancesByPage(serviceName, 0, 10, true) - page = discovery.GetInstancesByPage(serviceName, 0, 10) - assert.Equal(t, 1, page.GetDataSize()) - - err = discovery.AddListener(®istry.ServiceInstancesChangedListener{}) - assert.Nil(t, err) - - err = discovery.DispatchEvent(®istry.ServiceInstancesChangedEvent{}) - assert.Nil(t, err) - - err = discovery.DispatchEventForInstances(serviceName, nil) - assert.Nil(t, err) - - err = discovery.DispatchEventByServiceName(serviceName) - assert.Nil(t, err) - - err = discovery.Unregister(®istry.DefaultServiceInstance{ - Id: "2", - }) - assert.Nil(t, err) - - services = discovery.GetServices() - assert.Equal(t, 1, services.Size()) - - err = discovery.Update(®istry.DefaultServiceInstance{ - Id: "3", - }) - assert.Nil(t, err) - - services = discovery.GetServices() - assert.Equal(t, 2, services.Size()) - - err = discovery.Destroy() - assert.Nil(t, err) - - services = discovery.GetServices() - assert.Equal(t, 0, services.Size()) -} diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index 2b6cab45c2..6bfd476344 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -23,14 +23,13 @@ import ( "strconv" "strings" "time" - - "github.com/nacos-group/nacos-sdk-go/clients" - "github.com/nacos-group/nacos-sdk-go/clients/naming_client" - nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" ) import ( gxnet "github.com/dubbogo/gost/net" + "github.com/nacos-group/nacos-sdk-go/clients" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" + nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant" "github.com/nacos-group/nacos-sdk-go/vo" perrors "github.com/pkg/errors" ) diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 5b952e2541..63d92d70fd 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -20,23 +20,24 @@ package nacos import ( "fmt" "sync" +) +import ( "github.com/dubbogo/gost/container/set" "github.com/dubbogo/gost/page" "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" perrors "github.com/pkg/errors" - - "github.com/apache/dubbo-go/config" - "github.com/apache/dubbo-go/remoting/nacos" ) import ( "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/registry" + "github.com/apache/dubbo-go/remoting/nacos" ) const ( diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 633a1d41c8..720c44a6f9 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -19,8 +19,6 @@ package nacos import ( "testing" - - "github.com/apache/dubbo-go/config" ) import ( @@ -32,6 +30,7 @@ import ( "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/common/observer/dispatcher" + "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/registry" ) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 79194fb084..d6cce32f92 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -23,13 +23,17 @@ import ( "strconv" "strings" "sync" +) +import ( cm "github.com/Workiva/go-datastructures/common" gxset "github.com/dubbogo/gost/container/set" gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" "go.uber.org/atomic" +) +import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index 247cfd65eb..53eb86507e 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -21,29 +21,226 @@ import ( "testing" ) +import ( + "github.com/dubbogo/gost/container/set" + "github.com/dubbogo/gost/page" + "github.com/stretchr/testify/assert" +) +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata/mapping" + "github.com/apache/dubbo-go/metadata/service" + "github.com/apache/dubbo-go/registry" +) + var ( - SERVICE_INTERFACE = "org.apache.dubbo.metadata.MetadataService" - GROUP = "dubbo-provider" - VERSION = "1.0.0" + serviceInterface = "org.apache.dubbo.metadata.MetadataService" + group = "dubbo-provider" + version = "1.0.0" ) func TestServiceDiscoveryRegistry_Register(t *testing.T) { - // registryURL,_:=event.NewURL("in-memory://localhost:12345", - // event.WithParamsValue("registry-type","service"), - // event.WithParamsValue("subscribed-services","a, b , c,d,e ,")) - // url,_:=event.NewURL("dubbo://192.168.0.102:20880/"+ SERVICE_INTERFACE + - // "?&application=" + GROUP + - // "&interface=" + SERVICE_INTERFACE + - // "&group=" + GROUP + - // "&version=" + VERSION + - // "&methods=getAllServiceKeys,getServiceRestMetadata,getExportedURLs,getAllExportedURLs" + - // "&side=provider") - //registry,err:=newServiceDiscoveryRegistry(®istryURL) - //if err!=nil{ - // logger.Errorf("create service discovery registry catch error:%s",err.Error()) - //} - //assert.Nil(t,err) - //assert.NotNil(t,registry) - //registry.Register(url) + config.GetApplicationConfig().MetadataType = "mock" + extension.SetMetadataService("mock", func() (service service.MetadataService, err error) { + service = &mockMetadataService{} + return + }) + + extension.SetServiceDiscovery("mock", func(name string) (discovery registry.ServiceDiscovery, err error) { + return &mockServiceDiscovery{}, nil + }) + + extension.SetGlobalServiceNameMapping(func() mapping.ServiceNameMapping { + return &mockServiceNameMapping{} + }) + + extension.SetEventDispatcher("mock", func() observer.EventDispatcher { + return &mockEventDispatcher{} + }) + extension.SetAndInitGlobalDispatcher("mock") + + config.GetBaseConfig().ServiceDiscoveries["mock"] = &config.ServiceDiscoveryConfig{ + Protocol: "mock", + } + registryURL, _ := common.NewURL("service-discovery://localhost:12345", + common.WithParamsValue("service_discovery", "mock"), + common.WithParamsValue("subscribed-services", "a, b , c,d,e ,")) + url, _ := common.NewURL("dubbo://192.168.0.102:20880/" + serviceInterface + + "?&application=" + group + + "&interface=" + serviceInterface + + "&group=" + group + + "&version=" + version + + "&service_discovery=mock" + + "&methods=getAllServiceKeys,getServiceRestMetadata,getExportedURLs,getAllExportedURLs" + + "&side=provider") + registry, err := newServiceDiscoveryRegistry(®istryURL) + assert.Nil(t, err) + assert.NotNil(t, registry) + registry.Register(url) +} + +type mockEventDispatcher struct { +} + +func (m *mockEventDispatcher) AddEventListener(listener observer.EventListener) { + +} + +func (m *mockEventDispatcher) AddEventListeners(listenersSlice []observer.EventListener) { + +} + +func (m *mockEventDispatcher) RemoveEventListener(listener observer.EventListener) { + panic("implement me") +} + +func (m *mockEventDispatcher) RemoveEventListeners(listenersSlice []observer.EventListener) { + panic("implement me") +} + +func (m *mockEventDispatcher) GetAllEventListeners() []observer.EventListener { + return []observer.EventListener{} +} + +func (m *mockEventDispatcher) RemoveAllEventListeners() { + panic("implement me") +} + +func (m *mockEventDispatcher) Dispatch(event observer.Event) { +} + +type mockServiceNameMapping struct { +} + +func (m *mockServiceNameMapping) Map(serviceInterface string, group string, version string, protocol string) error { + return nil +} + +func (m *mockServiceNameMapping) Get(serviceInterface string, group string, version string, protocol string) (*gxset.HashSet, error) { + panic("implement me") +} + +type mockServiceDiscovery struct { +} + +func (m *mockServiceDiscovery) String() string { + panic("implement me") +} + +func (m *mockServiceDiscovery) Destroy() error { + panic("implement me") +} + +func (m *mockServiceDiscovery) Register(instance registry.ServiceInstance) error { + return nil +} + +func (m *mockServiceDiscovery) Update(instance registry.ServiceInstance) error { + panic("implement me") +} + +func (m *mockServiceDiscovery) Unregister(instance registry.ServiceInstance) error { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetDefaultPageSize() int { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetServices() *gxset.HashSet { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + panic("implement me") +} + +func (m *mockServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + panic("implement me") +} + +func (m *mockServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + panic("implement me") +} + +func (m *mockServiceDiscovery) DispatchEventByServiceName(serviceName string) error { + panic("implement me") +} + +func (m *mockServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + panic("implement me") +} + +func (m *mockServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + panic("implement me") +} + +type mockMetadataService struct { +} + +func (m *mockMetadataService) Reference() string { + panic("implement me") +} + +func (m *mockMetadataService) ServiceName() (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) ExportURL(url common.URL) (bool, error) { + return true, nil +} + +func (m *mockMetadataService) UnexportURL(url common.URL) error { + panic("implement me") +} + +func (m *mockMetadataService) SubscribeURL(url common.URL) (bool, error) { + panic("implement me") +} + +func (m *mockMetadataService) UnsubscribeURL(url common.URL) error { + panic("implement me") +} + +func (m *mockMetadataService) PublishServiceDefinition(url common.URL) error { + return nil +} + +func (m *mockMetadataService) GetExportedURLs(serviceInterface string, group string, version string, protocol string) ([]interface{}, error) { + panic("implement me") +} + +func (m *mockMetadataService) MethodMapper() map[string]string { + panic("implement me") +} + +func (m *mockMetadataService) GetSubscribedURLs() ([]common.URL, error) { + panic("implement me") +} + +func (m *mockMetadataService) GetServiceDefinition(interfaceName string, group string, version string) (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) GetServiceDefinitionByServiceKey(serviceKey string) (string, error) { + panic("implement me") +} + +func (m *mockMetadataService) RefreshMetadata(exportedRevision string, subscribedRevision string) (bool, error) { + panic("implement me") +} +func (m *mockMetadataService) Version() (string, error) { + panic("implement me") } diff --git a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go index a7d2f3ee98..949a5822c2 100644 --- a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go +++ b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go @@ -23,8 +23,8 @@ import ( ) type SubscribedURLsSynthesizer interface { - //Supports the synthesis of the subscribed url or not + // Supports the synthesis of the subscribed url or not Support(subscribedURL *common.URL) bool - //synthesize the subscribed url + // synthesize the subscribed url Synthesize(subscribedURL *common.URL, serviceInstances []registry.ServiceInstance) []common.URL } diff --git a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go index f8c76f6e84..ba7887223c 100644 --- a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go +++ b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go @@ -21,10 +21,12 @@ var ( synthesizers []SubscribedURLsSynthesizer ) +// nolint func AddSynthesizer(synthesizer SubscribedURLsSynthesizer) { synthesizers = append(synthesizers, synthesizer) } +// nolint func GetAllSynthesizer() []SubscribedURLsSynthesizer { return synthesizers } diff --git a/remoting/nacos/builder.go b/remoting/nacos/builder.go index 545a1e268c..4319627c6d 100644 --- a/remoting/nacos/builder.go +++ b/remoting/nacos/builder.go @@ -22,8 +22,6 @@ import ( "strconv" "strings" "time" - - "github.com/apache/dubbo-go/config" ) import ( @@ -37,16 +35,10 @@ import ( import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/config" ) -func NewNacosNamingClient(url *common.URL) (naming_client.INamingClient, error) { - nacosConfig, err := getNacosConfig(url) - if err != nil { - return nil, err - } - return clients.CreateNamingClient(nacosConfig) -} - +// NewNacosConfigClient read the config from url and build an instance func NewNacosConfigClient(url *common.URL) (config_client.IConfigClient, error) { nacosConfig, err := getNacosConfig(url) if err != nil { @@ -102,6 +94,7 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { return configMap, nil } +// NewNacosClient creates an instance with the config func NewNacosClient(rc *config.RemoteConfig) (naming_client.INamingClient, error) { if len(rc.Address) == 0 { return nil, perrors.New("nacos address is empty!") From 7bde7d9c7499f6c1d48b0154ae567d4e8cedd5e5 Mon Sep 17 00:00:00 2001 From: asheux Date: Thu, 18 Jun 2020 02:33:08 +0300 Subject: [PATCH 120/209] Mod: ignore vim temporary files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 568e9f2454..5a0a4f82fe 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ config_center/zookeeper/zookeeper-4unittest/ registry/zookeeper/zookeeper-4unittest/ registry/consul/agent* config_center/apollo/mockDubbog.properties.json + +# vim stuff +*~ +.*.sw? From 3b51b992483108c8783c838d6d1b7f181c8d0882 Mon Sep 17 00:00:00 2001 From: cvictory Date: Fri, 19 Jun 2020 14:52:01 +0800 Subject: [PATCH 121/209] add lock --- protocol/invocation/rpcinvocation.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go index b8b5b50970..953d50ca46 100644 --- a/protocol/invocation/rpcinvocation.go +++ b/protocol/invocation/rpcinvocation.go @@ -157,6 +157,8 @@ func (r *RPCInvocation) Invoker() protocol.Invoker { // nolint func (r *RPCInvocation) SetInvoker(invoker protocol.Invoker) { + r.lock.Lock() + defer r.lock.Unlock() r.invoker = invoker } From 0b6cbef6724ff1daeb82dc18d46fdf4a298415d9 Mon Sep 17 00:00:00 2001 From: zhengxianle Date: Sat, 20 Jun 2020 15:55:17 +0800 Subject: [PATCH 122/209] Ftr:EtcdServiceDiscovery #423 --- common/constant/key.go | 4 + registry/etcdv3/service_discovery.go | 312 ++++++++++++++++++++++ registry/etcdv3/service_discovery_test.go | 148 ++++++++++ remoting/etcdv3/client.go | 51 ++++ 4 files changed, 515 insertions(+) create mode 100644 registry/etcdv3/service_discovery.go create mode 100644 registry/etcdv3/service_discovery_test.go diff --git a/common/constant/key.go b/common/constant/key.go index 9c59575eb8..f0130b0744 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -160,6 +160,10 @@ const ( NACOS_PATH_KEY = "path" ) +const ( + ETCDV3_KEY = "etcdv3" +) + const ( TRACING_REMOTE_SPAN_CTX = "tracing.remote.span.ctx" ) diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go new file mode 100644 index 0000000000..aab317389b --- /dev/null +++ b/registry/etcdv3/service_discovery.go @@ -0,0 +1,312 @@ +/* + * 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 etcdv3 + +import ( + "fmt" + "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/registry" + "github.com/apache/dubbo-go/remoting" + "github.com/apache/dubbo-go/remoting/etcdv3" + gxset "github.com/dubbogo/gost/container/set" + gxpage "github.com/dubbogo/gost/page" + "github.com/hashicorp/vault/helper/jsonutil" + perrors "github.com/pkg/errors" + "sync" + "time" +) + +const ( + ROOT = "/services" +) + +var ( + initLock sync.Mutex +) + +func init() { + extension.SetServiceDiscovery(constant.ETCDV3_KEY, newEtcdV3ServiceDiscovery) +} + +// new etcd service discovery struct +type etcdV3ServiceDiscovery struct { + // descriptor is a short string about the basic information of this instance + descriptor string + // client is current Etcdv3 client + client *etcdv3.Client + // serviceInstance is current serviceInstance + serviceInstance *registry.ServiceInstance + // services is when register or update will add service name + services *gxset.HashSet + // child listener + childListenerMap map[string]*etcdv3.EventListener +} + +// basic information of this instance +func (e *etcdV3ServiceDiscovery) String() string { + return e.descriptor +} + +// Destory service discovery +func (e *etcdV3ServiceDiscovery) Destroy() error { + if e.client != nil { + e.client.Close() + } + return nil +} + +// Register will register an instance of ServiceInstance to registry +func (e *etcdV3ServiceDiscovery) Register(instance registry.ServiceInstance) error { + + e.serviceInstance = &instance + + path := toPath(instance) + + if nil != e.client { + ins, err := jsonutil.EncodeJSON(instance) + if err == nil { + e.client.Create(path, string(ins)) + e.services.Add(instance.GetServiceName()) + } + } + + return nil +} + +// Update will update the data of the instance in registry +func (e *etcdV3ServiceDiscovery) Update(instance registry.ServiceInstance) error { + path := toPath(instance) + + if nil != e.client { + ins, err := jsonutil.EncodeJSON(instance) + if nil == err { + e.client.Update(path, string(ins)) + e.services.Add(instance.GetServiceName()) + } + } + + return nil +} + +// Unregister will unregister this instance from registry +func (e *etcdV3ServiceDiscovery) Unregister(instance registry.ServiceInstance) error { + path := toPath(instance) + + if nil != e.client { + err := e.client.Delete(path) + e.services.Remove(instance.GetServiceName()) + e.serviceInstance = nil + return err + } + + return nil +} + +// ----------------- discovery ------------------- +// GetDefaultPageSize will return the default page size +func (e *etcdV3ServiceDiscovery) GetDefaultPageSize() int { + return registry.DefaultPageSize +} + +// GetServices will return the all service names. +func (e *etcdV3ServiceDiscovery) GetServices() *gxset.HashSet { + return e.services +} + +// GetInstances will return all service instances with serviceName +func (e *etcdV3ServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { + + if nil != e.client { + // get keys and values + _, vList, err := e.client.GetChildrenKVList(toParentPath(serviceName)) + if nil == err { + serviceInstances := make([]registry.ServiceInstance, 0, len(vList)) + for _, v := range vList { + instance := ®istry.DefaultServiceInstance{} + err = jsonutil.DecodeJSON([]byte(v), &instance) + if nil == err { + serviceInstances = append(serviceInstances, instance) + } + } + return serviceInstances + } + perrors.New(fmt.Sprintf("could not getChildrenKVList the err is:%v", err)) + } + + return make([]registry.ServiceInstance, 0, 0) +} + +// GetInstancesByPage will return a page containing instances of ServiceInstance with the serviceName +// the page will start at offset +func (e *etcdV3ServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + + all := e.GetInstances(serviceName) + + res := make([]interface{}, 0, pageSize) + + for i := offset; i < len(all) && i < offset+pageSize; i++ { + res = append(res, all[i]) + } + + return gxpage.New(offset, pageSize, res, len(all)) +} + +// GetHealthyInstancesByPage will return a page containing instances of ServiceInstance. +// The param healthy indices that the instance should be healthy or not. +// The page will start at offset +func (e *etcdV3ServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + all := e.GetInstances(serviceName) + res := make([]interface{}, 0, pageSize) + + var ( + i = offset + count = 0 + ) + for i < len(all) && count < pageSize { + ins := all[i] + if ins.IsHealthy() == healthy { + res = append(res, all[i]) + count++ + } + i++ + } + return gxpage.New(offset, pageSize, res, len(all)) +} + +// Batch get all instances by the specified service names +func (e *etcdV3ServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + res := make(map[string]gxpage.Pager, len(serviceNames)) + for _, name := range serviceNames { + res[name] = e.GetInstancesByPage(name, offset, requestedSize) + } + return res +} + +// ----------------- event ---------------------- +// AddListener adds a new ServiceInstancesChangedListener +// see addServiceInstancesChangedListener in Java +func (e *etcdV3ServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + return e.registerSreviceWatcher(listener.ServiceName) +} + +// DispatchEventByServiceName dispatches the ServiceInstancesChangedEvent to service instance whose name is serviceName +func (e *etcdV3ServiceDiscovery) DispatchEventByServiceName(serviceName string) error { + return e.DispatchEventForInstances(serviceName, e.GetInstances(serviceName)) +} + +// DispatchEventForInstances dispatches the ServiceInstancesChangedEvent to target instances +func (e *etcdV3ServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + return e.DispatchEvent(registry.NewServiceInstancesChangedEvent(serviceName, instances)) +} + +// DispatchEvent dispatches the event +func (e *etcdV3ServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + extension.GetGlobalDispatcher().Dispatch(event) + return nil +} + +// Convert instance to dubbo path +func toPath(instance registry.ServiceInstance) string { + if instance == nil { + return "" + } + // like: /services/servicename1/host(127.0.0.1)/8080 + return fmt.Sprintf("%s%d", ROOT+constant.PATH_SEPARATOR+instance.GetServiceName()+constant.PATH_SEPARATOR+instance.GetHost()+constant.KEY_SEPARATOR, instance.GetPort()) +} + +// to dubbo service path +func toParentPath(serviceName string) string { + return ROOT + constant.PATH_SEPARATOR + serviceName +} + +// register service watcher +func (e *etcdV3ServiceDiscovery) registerSreviceWatcher(serviceName string) error { + + initLock.Lock() + defer initLock.Unlock() + + path := toParentPath(serviceName) + + listener, found := e.childListenerMap[serviceName] + + if !found { + listener = etcdv3.NewEventListener(e.client) + e.childListenerMap[serviceName] = listener + } + + listener.ListenServiceEvent(path, e) + + return nil +} + +// when child data change should DispatchEventByServiceName +func (e *etcdV3ServiceDiscovery) DataChange(eventType remoting.Event) bool { + + if eventType.Action == remoting.EventTypeUpdate { + instance := ®istry.DefaultServiceInstance{} + err := jsonutil.DecodeJSON([]byte(eventType.Content), &instance) + if err != nil { + instance.ServiceName = "" + } + + if err := e.DispatchEventByServiceName(instance.ServiceName); err != nil { + return false + } + } + + return true +} + +// netEcdv3ServiceDiscovery +func newEtcdV3ServiceDiscovery(name string) (registry.ServiceDiscovery, error) { + + initLock.Lock() + defer initLock.Unlock() + + sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(name) + if !ok || len(sdc.RemoteRef) == 0 { + return nil, perrors.New("could not init the etcd service instance because the config is invalid") + } + + remoteConfig, ok := config.GetBaseConfig().GetRemoteConfig(sdc.RemoteRef) + if !ok { + return nil, perrors.New("could not find the remote config for name: " + sdc.RemoteRef) + } + + // init etcdv3 client + timeout, err := time.ParseDuration(remoteConfig.TimeoutStr) + if err != nil { + logger.Errorf("timeout config %v is invalid,err is %v", remoteConfig.TimeoutStr, err.Error()) + return nil, perrors.WithMessagef(err, "new etcd service discovery(address:%v)", remoteConfig.Address) + } + + logger.Infof("etcd address is: %v,timeout is:%s", remoteConfig.Address, timeout.String()) + + client := etcdv3.NewServiceDiscoveryClient( + etcdv3.WithName(etcdv3.RegistryETCDV3Client), + etcdv3.WithTimeout(timeout), + etcdv3.WithEndpoints(remoteConfig.Address), + ) + + descriptor := fmt.Sprintf("etcd-service-discovery[%s]", remoteConfig.Address) + + return &etcdV3ServiceDiscovery{descriptor, client, nil, gxset.NewSet(), make(map[string]*etcdv3.EventListener, 0)}, nil +} diff --git a/registry/etcdv3/service_discovery_test.go b/registry/etcdv3/service_discovery_test.go new file mode 100644 index 0000000000..ff3708e6f3 --- /dev/null +++ b/registry/etcdv3/service_discovery_test.go @@ -0,0 +1,148 @@ +package etcdv3 + +import ( + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" + "github.com/apache/dubbo-go/common/observer/dispatcher" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/registry" + "github.com/stretchr/testify/assert" + "testing" +) + +var testName = "test" + +func setUp() { + config.GetBaseConfig().ServiceDiscoveries[testName] = &config.ServiceDiscoveryConfig{ + Protocol: "etcdv3", + RemoteRef: testName, + } + + config.GetBaseConfig().Remotes[testName] = &config.RemoteConfig{ + Address: "localhost:2380", + TimeoutStr: "1000s", + } +} + +func Test_newEtcdV3ServiceDiscovery(t *testing.T) { + name := constant.ETCDV3_KEY + _, err := newEtcdV3ServiceDiscovery(name) + + // warn: log configure file name is nil + assert.NotNil(t, err) + + sdc := &config.ServiceDiscoveryConfig{ + Protocol: "etcdv3", + RemoteRef: "mock", + } + config.GetBaseConfig().ServiceDiscoveries[name] = sdc + + _, err = newEtcdV3ServiceDiscovery(name) + + // RemoteConfig not found + assert.NotNil(t, err) + + config.GetBaseConfig().Remotes["mock"] = &config.RemoteConfig{ + Address: "localhost:2380", + TimeoutStr: "10s", + } + + res, err := newEtcdV3ServiceDiscovery(name) + assert.Nil(t, err) + assert.NotNil(t, res) +} + +func TestEtcdV3ServiceDiscovery_Destroy(t *testing.T) { + setUp() + serviceDiscovery, err := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) + + assert.Nil(t, err) + assert.NotNil(t, serviceDiscovery) + + err = serviceDiscovery.Destroy() + assert.Nil(t, err) + assert.NotNil(t, serviceDiscovery.(*etcdV3ServiceDiscovery).client) +} + +func TestEtcdV3ServiceDiscovery_CRUD(t *testing.T) { + setUp() + extension.SetEventDispatcher("mock", func() observer.EventDispatcher { + return &dispatcher.MockEventDispatcher{} + }) + + extension.SetAndInitGlobalDispatcher("mock") + + serviceName := "service-name" + id := "id" + host := "host" + port := 123 + instance := ®istry.DefaultServiceInstance{ + Id: id, + ServiceName: serviceName, + Host: host, + Port: port, + Enable: true, + Healthy: true, + Metadata: nil, + } + + // clean data + + serviceDiscovry, _ := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) + + // clean data for local test + serviceDiscovry.Unregister(®istry.DefaultServiceInstance{ + Id: id, + ServiceName: serviceName, + Host: host, + Port: port, + }) + + err := serviceDiscovry.Register(instance) + assert.Nil(t, err) + + page := serviceDiscovry.GetHealthyInstancesByPage(serviceName, 0, 10, true) + assert.NotNil(t, page) + + assert.Equal(t, 0, page.GetOffset()) + assert.Equal(t, 10, page.GetPageSize()) + assert.Equal(t, 1, page.GetDataSize()) + + instance = page.GetData()[0].(*registry.DefaultServiceInstance) + assert.NotNil(t, instance) + assert.Equal(t, id, instance.GetId()) + assert.Equal(t, host, instance.GetHost()) + assert.Equal(t, port, instance.GetPort()) + assert.Equal(t, serviceName, instance.GetServiceName()) + assert.Equal(t, 0, len(instance.GetMetadata())) + + instance.Metadata["a"] = "b" + + err = serviceDiscovry.Update(instance) + assert.Nil(t, err) + + pageMap := serviceDiscovry.GetRequestInstances([]string{serviceName}, 0, 1) + assert.Equal(t, 1, len(pageMap)) + page = pageMap[serviceName] + assert.NotNil(t, page) + assert.Equal(t, 1, len(page.GetData())) + + instance = page.GetData()[0].(*registry.DefaultServiceInstance) + v, _ := instance.Metadata["a"] + assert.Equal(t, "b", v) + + // test dispatcher event + err = serviceDiscovry.DispatchEventByServiceName(serviceName) + assert.Nil(t, err) + + // test AddListener + err = serviceDiscovry.AddListener(®istry.ServiceInstancesChangedListener{ServiceName: serviceName}) + assert.Nil(t, err) +} + +func TestEtcdV3ServiceDiscovery_GetDefaultPageSize(t *testing.T) { + setUp() + serviceDiscovry, _ := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) + assert.Equal(t, registry.DefaultPageSize, serviceDiscovry.GetDefaultPageSize()) +} diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index 731ef0d807..aff182fb84 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -133,6 +133,26 @@ func ValidateClient(container clientFacade, opts ...Option) error { return nil } +// NewServiceDiscoveryClient +func NewServiceDiscoveryClient(opts ...Option) *Client { + options := &Options{ + heartbeat: 1, // default heartbeat + } + + for _, opt := range opts { + opt(options) + } + + newClient, err := NewClient(options.name, options.endpoints, options.timeout, options.heartbeat) + if err != nil { + logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", + options.name, options.endpoints, options.timeout, err) + return nil + } + + return newClient +} + // Client ... type Client struct { lock sync.RWMutex @@ -289,6 +309,28 @@ func (c *Client) put(k string, v string, opts ...clientv3.OpOption) error { return nil } +// if k not exist will put k/v in etcd +// if k is already exist in etcd, replace it +func (c *Client) update(k string, v string, opts ...clientv3.OpOption) error { + + c.lock.RLock() + defer c.lock.RUnlock() + + if c.rawClient == nil { + return ErrNilETCDV3Client + } + + _, err := c.rawClient.Txn(c.ctx). + If(clientv3.Compare(clientv3.Version(k), "!=", -1)). + Then(clientv3.OpPut(k, v, opts...)). + Commit() + if err != nil { + return err + + } + return nil +} + func (c *Client) delete(k string) error { c.lock.RLock() @@ -459,6 +501,15 @@ func (c *Client) Create(k string, v string) error { return nil } +// Update key value ... +func (c *Client) Update(k, v string) error { + err := c.update(k, v) + if err != nil { + return perrors.WithMessagef(err, "Update k/v (key: %s value %s)", k, v) + } + return nil +} + // Delete ... func (c *Client) Delete(k string) error { From 8eb8caa6d68b86cc037ba5b4db4b5e65efd01ec8 Mon Sep 17 00:00:00 2001 From: zhengxianle Date: Sat, 20 Jun 2020 16:01:57 +0800 Subject: [PATCH 123/209] Ftr: add EtcdServiceDiscovery --- go.mod | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5a7efac66d..65d0fb2ca4 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 github.com/hashicorp/consul v1.5.3 github.com/hashicorp/consul/api v1.1.0 + github.com/hashicorp/vault v0.10.3 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect @@ -43,7 +44,6 @@ require ( github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 - go.etcd.io/bbolt v1.3.4 // indirect go.uber.org/atomic v1.4.0 go.uber.org/zap v1.10.0 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect @@ -56,5 +56,3 @@ require ( ) go 1.13 - -replace github.com/nacos-group/nacos-sdk-go => /Users/mindeng/go-workspace/src/nacos-sdk-go From e3d77705971a058f06fdd48d41055fa2ce4d09c1 Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 21 Jun 2020 15:38:31 +0800 Subject: [PATCH 124/209] Fix UT --- metadata/service/inmemory/service_proxy.go | 4 - registry/etcdv3/service_discovery_test.go | 105 ++------------------- 2 files changed, 8 insertions(+), 101 deletions(-) diff --git a/metadata/service/inmemory/service_proxy.go b/metadata/service/inmemory/service_proxy.go index 840bd9a9d5..7e01439f04 100644 --- a/metadata/service/inmemory/service_proxy.go +++ b/metadata/service/inmemory/service_proxy.go @@ -20,7 +20,6 @@ package inmemory import ( "context" "reflect" - "time" ) import ( @@ -59,10 +58,7 @@ func (m *MetadataServiceProxy) GetExportedURLs(serviceInterface string, group st invocation.WithAttachments(map[string]string{constant.ASYNC_KEY: "false"}), invocation.WithParameterValues([]reflect.Value{siV, gV, vV, pV})) - start := time.Now() res := m.invkr.Invoke(context.Background(), inv) - end := time.Now() - logger.Infof("duration: %s, result: %v", (end.Sub(start)).String(), res.Result()) if res.Error() != nil { logger.Errorf("could not get the metadata service from remote provider: %v", res.Error()) return []interface{}{}, nil diff --git a/registry/etcdv3/service_discovery_test.go b/registry/etcdv3/service_discovery_test.go index ff3708e6f3..c03973cb14 100644 --- a/registry/etcdv3/service_discovery_test.go +++ b/registry/etcdv3/service_discovery_test.go @@ -1,14 +1,13 @@ package etcdv3 import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/common/observer" - "github.com/apache/dubbo-go/common/observer/dispatcher" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/registry" - "github.com/stretchr/testify/assert" - "testing" ) var testName = "test" @@ -20,8 +19,8 @@ func setUp() { } config.GetBaseConfig().Remotes[testName] = &config.RemoteConfig{ - Address: "localhost:2380", - TimeoutStr: "1000s", + Address: "localhost:2379", + TimeoutStr: "10s", } } @@ -44,7 +43,7 @@ func Test_newEtcdV3ServiceDiscovery(t *testing.T) { assert.NotNil(t, err) config.GetBaseConfig().Remotes["mock"] = &config.RemoteConfig{ - Address: "localhost:2380", + Address: "localhost:2379", TimeoutStr: "10s", } @@ -53,96 +52,8 @@ func Test_newEtcdV3ServiceDiscovery(t *testing.T) { assert.NotNil(t, res) } -func TestEtcdV3ServiceDiscovery_Destroy(t *testing.T) { - setUp() - serviceDiscovery, err := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) - - assert.Nil(t, err) - assert.NotNil(t, serviceDiscovery) - - err = serviceDiscovery.Destroy() - assert.Nil(t, err) - assert.NotNil(t, serviceDiscovery.(*etcdV3ServiceDiscovery).client) -} - -func TestEtcdV3ServiceDiscovery_CRUD(t *testing.T) { - setUp() - extension.SetEventDispatcher("mock", func() observer.EventDispatcher { - return &dispatcher.MockEventDispatcher{} - }) - - extension.SetAndInitGlobalDispatcher("mock") - - serviceName := "service-name" - id := "id" - host := "host" - port := 123 - instance := ®istry.DefaultServiceInstance{ - Id: id, - ServiceName: serviceName, - Host: host, - Port: port, - Enable: true, - Healthy: true, - Metadata: nil, - } - - // clean data - - serviceDiscovry, _ := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) - - // clean data for local test - serviceDiscovry.Unregister(®istry.DefaultServiceInstance{ - Id: id, - ServiceName: serviceName, - Host: host, - Port: port, - }) - - err := serviceDiscovry.Register(instance) - assert.Nil(t, err) - - page := serviceDiscovry.GetHealthyInstancesByPage(serviceName, 0, 10, true) - assert.NotNil(t, page) - - assert.Equal(t, 0, page.GetOffset()) - assert.Equal(t, 10, page.GetPageSize()) - assert.Equal(t, 1, page.GetDataSize()) - - instance = page.GetData()[0].(*registry.DefaultServiceInstance) - assert.NotNil(t, instance) - assert.Equal(t, id, instance.GetId()) - assert.Equal(t, host, instance.GetHost()) - assert.Equal(t, port, instance.GetPort()) - assert.Equal(t, serviceName, instance.GetServiceName()) - assert.Equal(t, 0, len(instance.GetMetadata())) - - instance.Metadata["a"] = "b" - - err = serviceDiscovry.Update(instance) - assert.Nil(t, err) - - pageMap := serviceDiscovry.GetRequestInstances([]string{serviceName}, 0, 1) - assert.Equal(t, 1, len(pageMap)) - page = pageMap[serviceName] - assert.NotNil(t, page) - assert.Equal(t, 1, len(page.GetData())) - - instance = page.GetData()[0].(*registry.DefaultServiceInstance) - v, _ := instance.Metadata["a"] - assert.Equal(t, "b", v) - - // test dispatcher event - err = serviceDiscovry.DispatchEventByServiceName(serviceName) - assert.Nil(t, err) - - // test AddListener - err = serviceDiscovry.AddListener(®istry.ServiceInstancesChangedListener{ServiceName: serviceName}) - assert.Nil(t, err) -} - func TestEtcdV3ServiceDiscovery_GetDefaultPageSize(t *testing.T) { setUp() - serviceDiscovry, _ := extension.GetServiceDiscovery(constant.ETCDV3_KEY, testName) + serviceDiscovry := &etcdV3ServiceDiscovery{} assert.Equal(t, registry.DefaultPageSize, serviceDiscovry.GetDefaultPageSize()) } From facab2ba9600005bc3ed977c6a66f554ded8f339 Mon Sep 17 00:00:00 2001 From: flycash Date: Mon, 22 Jun 2020 21:57:41 +0800 Subject: [PATCH 125/209] Fix Etcd BUG --- common/extension/service_discovery.go | 2 +- metadata/report/etcd/report.go | 2 +- registry/etcdv3/service_discovery.go | 9 +++++++-- remoting/etcdv3/client.go | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/common/extension/service_discovery.go b/common/extension/service_discovery.go index 456b14c83d..0227920dc6 100644 --- a/common/extension/service_discovery.go +++ b/common/extension/service_discovery.go @@ -42,7 +42,7 @@ func SetServiceDiscovery(protocol string, creator func(name string) (registry.Se func GetServiceDiscovery(protocol string, name string) (registry.ServiceDiscovery, error) { creator, ok := discoveryCreatorMap[protocol] if !ok { - return nil, perrors.New("Could not find the service discovery with name: " + name) + return nil, perrors.New("Could not find the service discovery with discovery protocol: " + protocol) } return creator(name) } diff --git a/metadata/report/etcd/report.go b/metadata/report/etcd/report.go index 0d49ff1783..9db0b577bf 100644 --- a/metadata/report/etcd/report.go +++ b/metadata/report/etcd/report.go @@ -41,7 +41,7 @@ import ( const DEFAULT_ROOT = "dubbo" func init() { - extension.SetMetadataReportFactory("etcd", func() factory.MetadataReportFactory { + extension.SetMetadataReportFactory(constant.ETCDV3_KEY, func() factory.MetadataReportFactory { return &etcdMetadataReportFactory{} }) } diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index f47d5324c4..e435a556e5 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -89,8 +89,13 @@ func (e *etcdV3ServiceDiscovery) Register(instance registry.ServiceInstance) err if nil != e.client { ins, err := jsonutil.EncodeJSON(instance) if err == nil { - e.client.Create(path, string(ins)) - e.services.Add(instance.GetServiceName()) + err = e.client.Update(path, string(ins)) + if err != nil { + logger.Errorf("cannot register the instance: %s", string(ins), err) + } else { + e.services.Add(instance.GetServiceName()) + } + } } diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index 93da6402c7..a24a69232e 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -144,7 +144,7 @@ func NewServiceDiscoveryClient(opts ...Option) *Client { newClient, err := NewClient(options.name, options.endpoints, options.timeout, options.heartbeat) if err != nil { - logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", + logger.Errorf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", options.name, options.endpoints, options.timeout, err) return nil } From 5318540cc9730e3b46d1c7802923992da4e0773f Mon Sep 17 00:00:00 2001 From: "zhangyanmingjiayou@163.com" Date: Mon, 22 Jun 2020 22:50:16 +0800 Subject: [PATCH 126/209] alter filter/*_test.go Rename testFuncName to match the regular expression ^[a-zA-Z0-9]+$. --- filter/filter_impl/access_log_filter_test.go | 4 ++-- filter/filter_impl/active_filter_test.go | 4 ++-- filter/filter_impl/echo_filter_test.go | 2 +- filter/filter_impl/execute_limit_filter_test.go | 6 +++--- filter/filter_impl/generic_filter_test.go | 6 +++--- filter/filter_impl/generic_service_filter_test.go | 6 +++--- .../filter_impl/graceful_shutdown_filter_test.go | 2 +- filter/filter_impl/hystrix_filter_test.go | 14 +++++++------- filter/filter_impl/metrics_filter_test.go | 2 +- filter/filter_impl/token_filter_test.go | 8 ++++---- .../tps/tps_limit_fix_window_strategy_test.go | 2 +- .../tps/tps_limit_sliding_window_strategy_test.go | 2 +- ...s_limit_thread_safe_fix_window_strategy_test.go | 2 +- .../tps/tps_limiter_method_service_test.go | 8 ++++---- filter/filter_impl/tps_limit_filter_test.go | 6 +++--- filter/filter_impl/tracing_filter_test.go | 2 +- 16 files changed, 38 insertions(+), 38 deletions(-) diff --git a/filter/filter_impl/access_log_filter_test.go b/filter/filter_impl/access_log_filter_test.go index f0de24d2a8..55c328cc30 100644 --- a/filter/filter_impl/access_log_filter_test.go +++ b/filter/filter_impl/access_log_filter_test.go @@ -53,7 +53,7 @@ func TestAccessLogFilter_Invoke_Not_Config(t *testing.T) { assert.Nil(t, result.Error()) } -func TestAccessLogFilter_Invoke_Default_Config(t *testing.T) { +func TestAccessLogFilterInvokeDefaultConfig(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() url, _ := common.NewURL( @@ -74,7 +74,7 @@ func TestAccessLogFilter_Invoke_Default_Config(t *testing.T) { assert.Nil(t, result.Error()) } -func TestAccessLogFilter_OnResponse(t *testing.T) { +func TestAccessLogFilterOnResponse(t *testing.T) { result := &protocol.RPCResult{} accessLogFilter := GetAccessLogFilter() response := accessLogFilter.OnResponse(nil, result, nil, nil) diff --git a/filter/filter_impl/active_filter_test.go b/filter/filter_impl/active_filter_test.go index d5a51d50d9..6b72830e6a 100644 --- a/filter/filter_impl/active_filter_test.go +++ b/filter/filter_impl/active_filter_test.go @@ -36,7 +36,7 @@ import ( "github.com/apache/dubbo-go/protocol/mock" ) -func TestActiveFilter_Invoke(t *testing.T) { +func TestActiveFilterInvoke(t *testing.T) { invoc := invocation.NewRPCInvocation("test", []interface{}{"OK"}, make(map[string]string, 0)) url, _ := common.NewURL("dubbo://192.168.10.10:20000/com.ikurento.user.UserProvider") filter := ActiveFilter{} @@ -50,7 +50,7 @@ func TestActiveFilter_Invoke(t *testing.T) { } -func TestActiveFilter_OnResponse(t *testing.T) { +func TestActiveFilterOnResponse(t *testing.T) { c := protocol.CurrentTimeMillis() elapsed := 100 invoc := invocation.NewRPCInvocation("test", []interface{}{"OK"}, map[string]string{ diff --git a/filter/filter_impl/echo_filter_test.go b/filter/filter_impl/echo_filter_test.go index fc09bdce69..b821a1a30c 100644 --- a/filter/filter_impl/echo_filter_test.go +++ b/filter/filter_impl/echo_filter_test.go @@ -32,7 +32,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestEchoFilter_Invoke(t *testing.T) { +func TestEchoFilterInvoke(t *testing.T) { filter := GetFilter() result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(common.URL{}), invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, nil)) assert.Equal(t, "OK", result.Result()) diff --git a/filter/filter_impl/execute_limit_filter_test.go b/filter/filter_impl/execute_limit_filter_test.go index ae8641f2db..d36d6edef1 100644 --- a/filter/filter_impl/execute_limit_filter_test.go +++ b/filter/filter_impl/execute_limit_filter_test.go @@ -34,7 +34,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestExecuteLimitFilter_Invoke_Ignored(t *testing.T) { +func TestExecuteLimitFilterInvokeIgnored(t *testing.T) { methodName := "hello" invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) @@ -49,7 +49,7 @@ func TestExecuteLimitFilter_Invoke_Ignored(t *testing.T) { assert.Nil(t, result.Error()) } -func TestExecuteLimitFilter_Invoke_Configure_Error(t *testing.T) { +func TestExecuteLimitFilterInvokeConfigureError(t *testing.T) { methodName := "hello1" invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) @@ -66,7 +66,7 @@ func TestExecuteLimitFilter_Invoke_Configure_Error(t *testing.T) { assert.Nil(t, result.Error()) } -func TestExecuteLimitFilter_Invoke(t *testing.T) { +func TestExecuteLimitFilterInvoke(t *testing.T) { methodName := "hello1" invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) diff --git a/filter/filter_impl/generic_filter_test.go b/filter/filter_impl/generic_filter_test.go index b082291998..e40733209b 100644 --- a/filter/filter_impl/generic_filter_test.go +++ b/filter/filter_impl/generic_filter_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_struct2MapAll(t *testing.T) { +func TestStruct2MapAll(t *testing.T) { var testData struct { AaAa string `m:"aaAa"` BaBa string @@ -64,7 +64,7 @@ type testStruct struct { } `m:"xxYy"` } -func Test_struct2MapAll_Slice(t *testing.T) { +func TestStruct2MapAllSlice(t *testing.T) { var testData struct { AaAa string `m:"aaAa"` BaBa string @@ -89,7 +89,7 @@ func Test_struct2MapAll_Slice(t *testing.T) { assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"]).Kind()) } -func Test_struct2MapAll_Map(t *testing.T) { +func TestStruct2MapAllMap(t *testing.T) { var testData struct { AaAa string Baba map[string]interface{} diff --git a/filter/filter_impl/generic_service_filter_test.go b/filter/filter_impl/generic_service_filter_test.go index 37c6af7450..2a331d76b6 100644 --- a/filter/filter_impl/generic_service_filter_test.go +++ b/filter/filter_impl/generic_service_filter_test.go @@ -77,7 +77,7 @@ func (*TestService) Reference() string { return "com.test.Path" } -func TestGenericServiceFilter_Invoke(t *testing.T) { +func TestGenericServiceFilterInvoke(t *testing.T) { hessian.RegisterPOJO(&TestStruct{}) methodName := "$invoke" m := make(map[string]interface{}) @@ -105,7 +105,7 @@ func TestGenericServiceFilter_Invoke(t *testing.T) { assert.Nil(t, result.Error()) } -func TestGenericServiceFilter_ResponseTestStruct(t *testing.T) { +func TestGenericServiceFilterResponseTestStruct(t *testing.T) { ts := &TestStruct{ AaAa: "aaa", BaBa: "bbb", @@ -130,7 +130,7 @@ func TestGenericServiceFilter_ResponseTestStruct(t *testing.T) { assert.Equal(t, reflect.ValueOf(r.Result()).Kind(), reflect.Map) } -func TestGenericServiceFilter_ResponseString(t *testing.T) { +func TestGenericServiceFilterResponseString(t *testing.T) { str := "111" result := &protocol.RPCResult{ Rest: str, diff --git a/filter/filter_impl/graceful_shutdown_filter_test.go b/filter/filter_impl/graceful_shutdown_filter_test.go index 4c670933e3..87ac2eac61 100644 --- a/filter/filter_impl/graceful_shutdown_filter_test.go +++ b/filter/filter_impl/graceful_shutdown_filter_test.go @@ -38,7 +38,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestGenericFilter_Invoke(t *testing.T) { +func TestGenericFilterInvoke(t *testing.T) { invoc := invocation.NewRPCInvocation("GetUser", []interface{}{"OK"}, make(map[string]string, 0)) invokeUrl := common.NewURLWithOptions( diff --git a/filter/filter_impl/hystrix_filter_test.go b/filter/filter_impl/hystrix_filter_test.go index 71fc097c8b..eebbae5556 100644 --- a/filter/filter_impl/hystrix_filter_test.go +++ b/filter/filter_impl/hystrix_filter_test.go @@ -90,7 +90,7 @@ func TestGetHystrixFilter(t *testing.T) { assert.NotNil(t, filterGot) } -func TestGetConfig_1(t *testing.T) { +func TestGetConfig1(t *testing.T) { mockInitHystrixConfig() configGot := getConfig("com.ikurento.user.UserProvider", "GetUser", true) assert.NotNil(t, configGot) @@ -101,7 +101,7 @@ func TestGetConfig_1(t *testing.T) { assert.Equal(t, 5, configGot.RequestVolumeThreshold) } -func TestGetConfig_2(t *testing.T) { +func TestGetConfig2(t *testing.T) { mockInitHystrixConfig() configGot := getConfig("com.ikurento.user.UserProvider", "GetUser0", true) assert.NotNil(t, configGot) @@ -112,7 +112,7 @@ func TestGetConfig_2(t *testing.T) { assert.Equal(t, 15, configGot.RequestVolumeThreshold) } -func TestGetConfig_3(t *testing.T) { +func TestGetConfig3(t *testing.T) { mockInitHystrixConfig() //This should use default configGot := getConfig("Mock.Service", "GetMock", true) @@ -145,7 +145,7 @@ func (iv *testMockFailInvoker) Invoke(_ context.Context, _ protocol.Invocation) } } -func TestHystrixFilter_Invoke_Success(t *testing.T) { +func TestHystrixFilterInvokeSuccess(t *testing.T) { hf := &HystrixFilter{} result := hf.Invoke(context.Background(), &testMockSuccessInvoker{}, &invocation.RPCInvocation{}) assert.NotNil(t, result) @@ -153,14 +153,14 @@ func TestHystrixFilter_Invoke_Success(t *testing.T) { assert.NotNil(t, result.Result()) } -func TestHystrixFilter_Invoke_Fail(t *testing.T) { +func TestHystrixFilterInvokeFail(t *testing.T) { hf := &HystrixFilter{} result := hf.Invoke(context.Background(), &testMockFailInvoker{}, &invocation.RPCInvocation{}) assert.NotNil(t, result) assert.Error(t, result.Error()) } -func TestHystricFilter_Invoke_CircuitBreak(t *testing.T) { +func TestHystricFilterInvokeCircuitBreak(t *testing.T) { mockInitHystrixConfig() hystrix.Flush() hf := &HystrixFilter{COrP: true} @@ -183,7 +183,7 @@ func TestHystricFilter_Invoke_CircuitBreak(t *testing.T) { } -func TestHystricFilter_Invoke_CircuitBreak_Omit_Exception(t *testing.T) { +func TestHystricFilterInvokeCircuitBreakOmitException(t *testing.T) { mockInitHystrixConfig() hystrix.Flush() reg, _ := regexp.Compile(".*exception.*") diff --git a/filter/filter_impl/metrics_filter_test.go b/filter/filter_impl/metrics_filter_test.go index 709404a2af..881106f4bc 100644 --- a/filter/filter_impl/metrics_filter_test.go +++ b/filter/filter_impl/metrics_filter_test.go @@ -38,7 +38,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestMetricsFilter_Invoke(t *testing.T) { +func TestMetricsFilterInvoke(t *testing.T) { // prepare the mock reporter config.GetMetricConfig().Reporters = []string{"mock"} diff --git a/filter/filter_impl/token_filter_test.go b/filter/filter_impl/token_filter_test.go index d7a7f20a5d..70ea173b28 100644 --- a/filter/filter_impl/token_filter_test.go +++ b/filter/filter_impl/token_filter_test.go @@ -34,7 +34,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestTokenFilter_Invoke(t *testing.T) { +func TestTokenFilterInvoke(t *testing.T) { filter := GetTokenFilter() url := common.NewURLWithOptions( @@ -50,7 +50,7 @@ func TestTokenFilter_Invoke(t *testing.T) { assert.Nil(t, result.Result()) } -func TestTokenFilter_InvokeEmptyToken(t *testing.T) { +func TestTokenFilterInvokeEmptyToken(t *testing.T) { filter := GetTokenFilter() url := common.URL{} @@ -61,7 +61,7 @@ func TestTokenFilter_InvokeEmptyToken(t *testing.T) { assert.Nil(t, result.Result()) } -func TestTokenFilter_InvokeEmptyAttach(t *testing.T) { +func TestTokenFilterInvokeEmptyAttach(t *testing.T) { filter := GetTokenFilter() url := common.NewURLWithOptions( @@ -72,7 +72,7 @@ func TestTokenFilter_InvokeEmptyAttach(t *testing.T) { assert.NotNil(t, result.Error()) } -func TestTokenFilter_InvokeNotEqual(t *testing.T) { +func TestTokenFilterInvokeNotEqual(t *testing.T) { filter := GetTokenFilter() url := common.NewURLWithOptions( diff --git a/filter/filter_impl/tps/tps_limit_fix_window_strategy_test.go b/filter/filter_impl/tps/tps_limit_fix_window_strategy_test.go index 5eaf2f707d..83a2f9b54d 100644 --- a/filter/filter_impl/tps/tps_limit_fix_window_strategy_test.go +++ b/filter/filter_impl/tps/tps_limit_fix_window_strategy_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestFixedWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) { +func TestFixedWindowTpsLimitStrategyImplIsAllowable(t *testing.T) { creator := &fixedWindowStrategyCreator{} strategy := creator.Create(2, 60000) assert.True(t, strategy.IsAllowable()) diff --git a/filter/filter_impl/tps/tps_limit_sliding_window_strategy_test.go b/filter/filter_impl/tps/tps_limit_sliding_window_strategy_test.go index 57342d1c44..ca5d70ae14 100644 --- a/filter/filter_impl/tps/tps_limit_sliding_window_strategy_test.go +++ b/filter/filter_impl/tps/tps_limit_sliding_window_strategy_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestSlidingWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) { +func TestSlidingWindowTpsLimitStrategyImplIsAllowable(t *testing.T) { creator := &slidingWindowStrategyCreator{} strategy := creator.Create(2, 60000) assert.True(t, strategy.IsAllowable()) diff --git a/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy_test.go b/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy_test.go index 90cd15201c..80d31f8ff0 100644 --- a/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy_test.go +++ b/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestThreadSafeFixedWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) { +func TestThreadSafeFixedWindowTpsLimitStrategyImplIsAllowable(t *testing.T) { creator := &threadSafeFixedWindowStrategyCreator{} strategy := creator.Create(2, 60000) assert.True(t, strategy.IsAllowable()) diff --git a/filter/filter_impl/tps/tps_limiter_method_service_test.go b/filter/filter_impl/tps/tps_limiter_method_service_test.go index 441224a3e3..edae99ec2d 100644 --- a/filter/filter_impl/tps/tps_limiter_method_service_test.go +++ b/filter/filter_impl/tps/tps_limiter_method_service_test.go @@ -34,7 +34,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestMethodServiceTpsLimiterImpl_IsAllowable_Only_Service_Level(t *testing.T) { +func TestMethodServiceTpsLimiterImplIsAllowableOnlyServiceLevel(t *testing.T) { methodName := "hello" invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) @@ -61,7 +61,7 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Only_Service_Level(t *testing.T assert.True(t, result) } -func TestMethodServiceTpsLimiterImpl_IsAllowable_No_Config(t *testing.T) { +func TestMethodServiceTpsLimiterImplIsAllowableNoConfig(t *testing.T) { methodName := "hello1" invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) // ctrl := gomock.NewController(t) @@ -77,7 +77,7 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_No_Config(t *testing.T) { assert.True(t, result) } -func TestMethodServiceTpsLimiterImpl_IsAllowable_Method_Level_Override(t *testing.T) { +func TestMethodServiceTpsLimiterImplIsAllowableMethodLevelOverride(t *testing.T) { methodName := "hello2" methodConfigPrefix := "methods." + methodName + "." invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) @@ -110,7 +110,7 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Method_Level_Override(t *testin assert.True(t, result) } -func TestMethodServiceTpsLimiterImpl_IsAllowable_Both_Method_And_Service(t *testing.T) { +func TestMethodServiceTpsLimiterImplIsAllowableBothMethodAndService(t *testing.T) { methodName := "hello3" methodConfigPrefix := "methods." + methodName + "." invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]string, 0)) diff --git a/filter/filter_impl/tps_limit_filter_test.go b/filter/filter_impl/tps_limit_filter_test.go index cc423ae1e5..274e4e6de6 100644 --- a/filter/filter_impl/tps_limit_filter_test.go +++ b/filter/filter_impl/tps_limit_filter_test.go @@ -39,7 +39,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestTpsLimitFilter_Invoke_With_No_TpsLimiter(t *testing.T) { +func TestTpsLimitFilterInvokeWithNoTpsLimiter(t *testing.T) { tpsFilter := GetTpsLimitFilter() invokeUrl := common.NewURLWithOptions( common.WithParams(url.Values{}), @@ -55,7 +55,7 @@ func TestTpsLimitFilter_Invoke_With_No_TpsLimiter(t *testing.T) { } -func TestGenericFilter_Invoke_With_Default_TpsLimiter(t *testing.T) { +func TestGenericFilterInvokeWithDefaultTpsLimiter(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockLimiter := tps.NewMockTpsLimiter(ctrl) @@ -78,7 +78,7 @@ func TestGenericFilter_Invoke_With_Default_TpsLimiter(t *testing.T) { assert.Nil(t, result.Result()) } -func TestGenericFilter_Invoke_With_Default_TpsLimiter_Not_Allow(t *testing.T) { +func TestGenericFilterInvokeWithDefaultTpsLimiterNotAllow(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockLimiter := tps.NewMockTpsLimiter(ctrl) diff --git a/filter/filter_impl/tracing_filter_test.go b/filter/filter_impl/tracing_filter_test.go index a51692dddc..15dc32e7ec 100644 --- a/filter/filter_impl/tracing_filter_test.go +++ b/filter/filter_impl/tracing_filter_test.go @@ -36,7 +36,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func TestTracingFilter_Invoke(t *testing.T) { +func TestTracingFilterInvoke(t *testing.T) { url, _ := common.NewURL( "dubbo://:20000/UserProvider?app.version=0.0.1&application=BDTService&bean.name=UserProvider" + "&cluster=failover&environment=dev&group=&interface=com.ikurento.user.UserProvider&loadbalance=random&methods.GetUser." + From 5aaee6d792224e160ef4da2e0f003a7273dc314a Mon Sep 17 00:00:00 2001 From: zhengxianle Date: Tue, 23 Jun 2020 00:26:34 +0800 Subject: [PATCH 127/209] Fix: EtcdServiceDiscovery replace put with temp kv. --- registry/etcdv3/service_discovery.go | 5 ++--- remoting/etcdv3/client.go | 11 ++++------- remoting/etcdv3/client_test.go | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index e435a556e5..5699f1c427 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -89,13 +89,12 @@ func (e *etcdV3ServiceDiscovery) Register(instance registry.ServiceInstance) err if nil != e.client { ins, err := jsonutil.EncodeJSON(instance) if err == nil { - err = e.client.Update(path, string(ins)) + err = e.client.RegisterTemp(path, string(ins)) if err != nil { logger.Errorf("cannot register the instance: %s", string(ins), err) } else { e.services.Add(instance.GetServiceName()) } - } } @@ -109,7 +108,7 @@ func (e *etcdV3ServiceDiscovery) Update(instance registry.ServiceInstance) error if nil != e.client { ins, err := jsonutil.EncodeJSON(instance) if nil == err { - e.client.Update(path, string(ins)) + e.client.RegisterTemp(path, string(ins)) e.services.Add(instance.GetServiceName()) } } diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index a24a69232e..080c941144 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -19,7 +19,6 @@ package etcdv3 import ( "context" - "path" "sync" "time" ) @@ -520,16 +519,14 @@ func (c *Client) Delete(k string) error { } // RegisterTemp registers a temporary node -func (c *Client) RegisterTemp(basePath string, node string) (string, error) { +func (c *Client) RegisterTemp(k, v string) error { - completeKey := path.Join(basePath, node) - - err := c.keepAliveKV(completeKey, "") + err := c.keepAliveKV(k, v) if err != nil { - return "", perrors.WithMessagef(err, "keepalive kv (key %s)", completeKey) + return perrors.WithMessagef(err, "keepalive kv (key %s)", k) } - return completeKey, nil + return nil } // GetChildrenKVList gets children kv list by @k diff --git a/remoting/etcdv3/client_test.go b/remoting/etcdv3/client_test.go index 287d93e30d..a321eea9ec 100644 --- a/remoting/etcdv3/client_test.go +++ b/remoting/etcdv3/client_test.go @@ -384,7 +384,7 @@ func (suite *ClientTestSuite) TestClientRegisterTemp() { assert.Contains(t, events, eDelete) }() - _, err := c.RegisterTemp("scott", "wang") + err := c.RegisterTemp("scott/wang", "test") if err != nil { t.Fatal(err) } From 05bc46dd8697c57f2ace43b1a144b4a757eec6b6 Mon Sep 17 00:00:00 2001 From: YuzeZhang Date: Tue, 23 Jun 2020 01:35:18 +0800 Subject: [PATCH 128/209] Update links --- README.md | 2 +- README_CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26e2ae8cd1..16cb1f5000 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ If you are willing to do some code contributions and document contributions to [ Benchmark project [dubbo-go-benchmark](https://github.com/dubbogo/dubbo-go-benchmark). -About dubbo-go benchmarking report, please refer to [dubbo benchmarking report](https://github.com/apache/dubbo-go/wiki/pressure-test-report-for-dubbo) & [jsonrpc benchmarking report](https://github.com/apache/dubbo-go/wiki/pressure-test-report-for-jsonrpc). +About dubbo-go benchmarking report, please refer to [dubbo benchmarking report](https://github.com/apache/dubbo-go/wiki/Benchmark-test-of-dubbo) & [jsonrpc benchmarking report](https://github.com/apache/dubbo-go/wiki/Benchmark-test-of-jsonrpc). ## [User List](https://github.com/apache/dubbo-go/issues/2) diff --git a/README_CN.md b/README_CN.md index 9770108eb4..53d5f85e3b 100644 --- a/README_CN.md +++ b/README_CN.md @@ -167,7 +167,7 @@ go test ./... -coverprofile=coverage.txt -covermode=atomic 性能测试项目是 [dubbo-go-benchmark](https://github.com/dubbogo/dubbo-go-benchmark)。 -关于 dubbo-go 性能测试报告,请阅读 [dubbo benchmarking report](https://github.com/apache/dubbo-go/wiki/pressure-test-report-for-dubbo) & [jsonrpc benchmarking report](https://github.com/apache/dubbo-go/wiki/pressure-test-report-for-jsonrpc)。 +关于 dubbo-go 性能测试报告,请阅读 [dubbo benchmarking report](https://github.com/apache/dubbo-go/wiki/Benchmark-test-of-dubbo) & [jsonrpc benchmarking report](https://github.com/apache/dubbo-go/wiki/Benchmark-test-of-jsonrpc)。 ## [User List](https://github.com/apache/dubbo-go/issues/2) From 0dc83ea30b500c1bd9a6c7b2895155fd3d7bad9b Mon Sep 17 00:00:00 2001 From: willson-chen Date: Wed, 24 Jun 2020 15:56:37 +0800 Subject: [PATCH 129/209] Add ANYHOST_KEY judgment --- common/constant/default.go | 1 + registry/base_configuration_listener.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/constant/default.go b/common/constant/default.go index 3c889158e4..c5aa5ac50f 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -57,6 +57,7 @@ const ( const ( ANY_VALUE = "*" + ANYHOST_KEY = "anyhost" ANYHOST_VALUE = "0.0.0.0" REMOVE_VALUE_PREFIX = "-" ) diff --git a/registry/base_configuration_listener.go b/registry/base_configuration_listener.go index 55418318df..b67de77914 100644 --- a/registry/base_configuration_listener.go +++ b/registry/base_configuration_listener.go @@ -100,7 +100,13 @@ func ToConfigurators(urls []*common.URL, f func(url *common.URL) config_center.C configurators = []config_center.Configurator{} break } - //TODO:anyhost_key judage + + var override map[string][]string = url.GetParams() + delete(override, constant.ANYHOST_KEY) + if len(override) == 0 { + configurators = configurators[:0] + continue + } configurators = append(configurators, f(url)) } return configurators From 9ab1a9bef75dcbeedd6b3fe509f1ac055683bb3b Mon Sep 17 00:00:00 2001 From: willson-chen Date: Wed, 24 Jun 2020 16:06:26 +0800 Subject: [PATCH 130/209] Update the method to clear slice --- registry/base_configuration_listener.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/base_configuration_listener.go b/registry/base_configuration_listener.go index b67de77914..f9c34c1c9d 100644 --- a/registry/base_configuration_listener.go +++ b/registry/base_configuration_listener.go @@ -104,7 +104,7 @@ func ToConfigurators(urls []*common.URL, f func(url *common.URL) config_center.C var override map[string][]string = url.GetParams() delete(override, constant.ANYHOST_KEY) if len(override) == 0 { - configurators = configurators[:0] + configurators = nil continue } configurators = append(configurators, f(url)) From fb450a79341b5638d54a099d6b5596bed79a77be Mon Sep 17 00:00:00 2001 From: willson-chen Date: Wed, 24 Jun 2020 21:01:17 +0800 Subject: [PATCH 131/209] Simplify the assignment of override --- registry/base_configuration_listener.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/base_configuration_listener.go b/registry/base_configuration_listener.go index f9c34c1c9d..d8c8cc8776 100644 --- a/registry/base_configuration_listener.go +++ b/registry/base_configuration_listener.go @@ -101,7 +101,7 @@ func ToConfigurators(urls []*common.URL, f func(url *common.URL) config_center.C break } - var override map[string][]string = url.GetParams() + override := url.GetParams() delete(override, constant.ANYHOST_KEY) if len(override) == 0 { configurators = nil From 3d0b1c91ab1699a0cfa8f498de90cdc1e2d74b5f Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 13:22:34 +0800 Subject: [PATCH 132/209] modify metareport interface --- metadata/report/delegate/delegate_report.go | 14 ++++++++++++-- metadata/report/nacos/report.go | 20 ++------------------ metadata/report/nacos/report_test.go | 7 ++++--- metadata/report/report.go | 2 +- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index cb7e42030b..282e751443 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -19,6 +19,7 @@ package delegate import ( "encoding/json" + perrors "github.com/pkg/errors" "runtime/debug" "sync" "time" @@ -241,11 +242,20 @@ func (mr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadata // SaveSubscribedData will delegate to call remote metadata's sdk to save subscribed data func (mr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { + urlStrList := make([]string, 0, len(urls)) + for _, url := range urls { + urlStrList = append(urlStrList, url.String()) + } + bytes, err := json.Marshal(urlStrList) + if err != nil { + return perrors.WithMessage(err, "Could not convert the array to json") + } + report := instance.GetMetadataReportInstance() if mr.syncReport { - return report.SaveSubscribedData(identifier, urls) + return report.SaveSubscribedData(identifier, string(bytes)) } - go report.SaveSubscribedData(identifier, urls) + go report.SaveSubscribedData(identifier, string(bytes)) return nil } diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 8f29c7de0f..312fd27c84 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -18,7 +18,6 @@ package nacos import ( - "encoding/json" "net/url" ) @@ -98,26 +97,11 @@ func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.Ser } // SaveSubscribedData will convert the urlList to json array and then store it -func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlList []common.URL) error { - if len(urlList) == 0 { - logger.Warnf("The url list is empty") - return nil - } - urlStrList := make([]string, 0, len(urlList)) - - for _, e := range urlList { - urlStrList = append(urlStrList, e.String()) - } - - bytes, err := json.Marshal(urlStrList) - - if err != nil { - return perrors.WithMessage(err, "Could not convert the array to json") - } +func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlListStr string) error { return n.storeMetadata(vo.ConfigParam{ DataId: subscriberMetadataIdentifier.GetIdentifierKey(), Group: subscriberMetadataIdentifier.Group, - Content: string(bytes), + Content: urlListStr, }) } diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 19ca2e5a48..254b92363b 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -18,6 +18,7 @@ package nacos import ( + "encoding/json" "strconv" "testing" ) @@ -57,9 +58,9 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { assert.Equal(t, 1, len(exportedUrls)) subMi := newSubscribeMetadataIdentifier() - urlList := make([]common.URL, 0, 1) - urlList = append(urlList, serviceUrl) - err = rpt.SaveSubscribedData(subMi, urlList) + urlList := []string{serviceUrl.String()} + bytes, _ := json.Marshal(urlList) + err = rpt.SaveSubscribedData(subMi, string(bytes)) assert.Nil(t, err) subscribeUrl := rpt.GetSubscribedURLs(subMi) diff --git a/metadata/report/report.go b/metadata/report/report.go index 61cdda1f96..d5930dc1fd 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -29,7 +29,7 @@ type MetadataReport interface { SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string - SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, []common.URL) error + SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, string) error GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string GetServiceDefinition(*identifier.MetadataIdentifier) string } From b08b8fc1ed12e1371bdfff7f73d8c536ef3a3c57 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 26 Jun 2020 15:19:54 +0800 Subject: [PATCH 133/209] zookeeper's service_discovery --- common/constant/key.go | 4 + registry/zookeeper/service_discovery.go | 284 ++++++++++++++++++ remoting/zookeeper/client.go | 7 +- .../curator_discovery/service_discovery.go | 149 +++++++++ .../curator_discovery/service_instance.go | 27 ++ remoting/zookeeper/facade.go | 8 +- remoting/zookeeper/facade_test.go | 2 +- 7 files changed, 475 insertions(+), 6 deletions(-) create mode 100644 registry/zookeeper/service_discovery.go create mode 100644 remoting/zookeeper/curator_discovery/service_discovery.go create mode 100644 remoting/zookeeper/curator_discovery/service_instance.go diff --git a/common/constant/key.go b/common/constant/key.go index 414d24e6e8..18d7f3de3d 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -159,6 +159,10 @@ const ( NACOS_PATH_KEY = "path" ) +const ( + ZOOKEEPER_KEY = "zookeeper" +) + const ( TRACING_REMOTE_SPAN_CTX = "tracing.remote.span.ctx" ) diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go new file mode 100644 index 0000000000..5daf3e1a2c --- /dev/null +++ b/registry/zookeeper/service_discovery.go @@ -0,0 +1,284 @@ +/* + * 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 zookeeper + +import ( + "fmt" + "strconv" + "strings" + "sync" +) + +import ( + "github.com/dubbogo/gost/container/set" + "github.com/dubbogo/gost/page" + perrors "github.com/pkg/errors" +) + +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/registry" + "github.com/apache/dubbo-go/remoting" + "github.com/apache/dubbo-go/remoting/zookeeper" + "github.com/apache/dubbo-go/remoting/zookeeper/curator_discovery" +) + +const ( + // RegistryZkClient zk client name + ServiceDiscoveryZkClient = "zk service discovery" +) + +var ( + // 16 would be enough. We won't use concurrentMap because in most cases, there are not race condition + instanceMap = make(map[string]registry.ServiceDiscovery, 16) + initLock sync.Mutex +) + +// init will put the service discovery into extension +func init() { + extension.SetServiceDiscovery(constant.ZOOKEEPER_KEY, newZookeeperServiceDiscovery) +} + +type zookeeperServiceDiscovery struct { + client *zookeeper.ZookeeperClient + csd *curator_discovery.ServiceDiscovery + listener *zookeeper.ZkEventListener + url *common.URL + wg sync.WaitGroup + cltLock sync.Mutex + done chan struct{} + rootPath string +} + +func newZookeeperServiceDiscovery(name string) (registry.ServiceDiscovery, error) { + instance, ok := instanceMap[name] + if ok { + return instance, nil + } + + initLock.Lock() + defer initLock.Unlock() + + // double check + instance, ok = instanceMap[name] + if ok { + return instance, nil + } + + sdc, ok := config.GetBaseConfig().GetServiceDiscoveries(name) + if !ok || len(sdc.RemoteRef) == 0 { + return nil, perrors.New("could not init the instance because the config is invalid") + } + remoteConfig, ok := config.GetBaseConfig().GetRemoteConfig(sdc.RemoteRef) + if !ok { + return nil, perrors.New("could not find the remote config for name: " + sdc.RemoteRef) + } + basePath := remoteConfig.GetParam("rootPath", "/services") + url := common.NewURLWithOptions( + common.WithLocation(remoteConfig.Address), + common.WithPassword(remoteConfig.Password), + common.WithUsername(remoteConfig.Username), + common.WithParamsValue(constant.REGISTRY_TIMEOUT_KEY, remoteConfig.TimeoutStr)) + zksd := &zookeeperServiceDiscovery{ + url: url, + rootPath: basePath, + } + err := zookeeper.ValidateZookeeperClient(zksd, zookeeper.WithZkName(ServiceDiscoveryZkClient)) + if err != nil { + return nil, err + } + go zookeeper.HandleClientRestart(zksd) + zksd.listener = zookeeper.NewZkEventListener(zksd.client) + zksd.listener.ListenServiceEvent(nil, basePath, zksd) + zksd.csd = curator_discovery.NewServiceDiscovery(zksd.client, basePath) + return zksd, nil +} + +func (zksd zookeeperServiceDiscovery) ZkClient() *zookeeper.ZookeeperClient { + return zksd.client +} + +func (zksd zookeeperServiceDiscovery) SetZkClient(client *zookeeper.ZookeeperClient) { + zksd.client = client +} + +func (zksd zookeeperServiceDiscovery) ZkClientLock() *sync.Mutex { + return &zksd.cltLock +} + +func (zksd zookeeperServiceDiscovery) WaitGroup() *sync.WaitGroup { + return &zksd.wg +} + +func (zksd zookeeperServiceDiscovery) Done() chan struct{} { + return zksd.done +} + +func (zksd zookeeperServiceDiscovery) RestartCallBack() bool { + zksd.csd.ReRegisterService() + zksd.listener.ListenServiceEvent(nil, zksd.rootPath, zksd) + return true +} + +func (zksd zookeeperServiceDiscovery) GetUrl() common.URL { + return *zksd.url +} + +func (zksd zookeeperServiceDiscovery) String() string { + return fmt.Sprintf("zookeeper-service-discovery[%s]", zksd.url) +} + +func (zksd zookeeperServiceDiscovery) Destroy() error { + zksd.client.Close() + return nil +} + +func (zksd zookeeperServiceDiscovery) Register(instance registry.ServiceInstance) error { + cris := zksd.toCuratorInstance(instance) + return zksd.csd.RegisterService(cris) +} + +func (zksd zookeeperServiceDiscovery) Update(instance registry.ServiceInstance) error { + cris := zksd.toCuratorInstance(instance) + return zksd.csd.UpdateService(cris) +} + +func (zksd zookeeperServiceDiscovery) Unregister(instance registry.ServiceInstance) error { + cris := zksd.toCuratorInstance(instance) + return zksd.csd.UnregisterService(cris) +} + +func (zksd zookeeperServiceDiscovery) GetDefaultPageSize() int { + return registry.DefaultPageSize +} + +func (zksd zookeeperServiceDiscovery) GetServices() *gxset.HashSet { + services, err := zksd.csd.QueryForNames() + res := gxset.NewSet() + if err != nil { + logger.Errorf("[zkServiceDiscovery] Could not query the services: %v", err) + return res + } + for _, service := range services { + res.Add(service) + } + return res +} + +func (zksd zookeeperServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { + criss, err := zksd.csd.QueryForInstances(serviceName) + if err != nil { + logger.Errorf("[zkServiceDiscovery] Could not query the instances for service{%s}, error = err{%v} ", + serviceName, err) + return make([]registry.ServiceInstance, 0, 0) + } + iss := make([]registry.ServiceInstance, 0, len(criss)) + for _, cris := range criss { + iss = append(iss, zksd.toZookeeperInstance(cris)) + } + return iss +} + +func (zksd zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { + all := zksd.GetInstances(serviceName) + res := make([]interface{}, 0, pageSize) + // could not use res = all[a:b] here because the res should be []interface{}, not []ServiceInstance + for i := offset; i < len(all) && i < offset+pageSize; i++ { + res = append(res, all[i]) + } + return gxpage.New(offset, pageSize, res, len(all)) +} + +func (zksd zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, _ bool) gxpage.Pager { + return zksd.GetInstancesByPage(serviceName, offset, pageSize) +} + +func (zksd zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { + res := make(map[string]gxpage.Pager, len(serviceNames)) + for _, name := range serviceNames { + res[name] = zksd.GetInstancesByPage(name, offset, requestedSize) + } + return res +} + +func (zksd zookeeperServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + return nil +} + +func (zksd zookeeperServiceDiscovery) DispatchEventByServiceName(serviceName string) error { + return zksd.DispatchEventForInstances(serviceName, zksd.GetInstances(serviceName)) +} + +func (zksd zookeeperServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { + return zksd.DispatchEvent(registry.NewServiceInstancesChangedEvent(serviceName, instances)) +} + +func (zksd zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { + extension.GetGlobalDispatcher().Dispatch(event) + return nil +} + +func (zksd zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { + path := eventType.Path + name := strings.Split(path, "/")[1] + id := strings.Split(path, "/")[2] + zksd.csd.UpdateInternalService(name, id) + err := zksd.DispatchEventByServiceName(name) + if err != nil { + logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", name, err) + } + return true +} + +func (zksd zookeeperServiceDiscovery) toCuratorInstance(instance registry.ServiceInstance) *curator_discovery.ServiceInstance { + id := instance.GetHost() + ":" + strconv.Itoa(instance.GetPort()) + pl := make(map[string]interface{}) + pl["id"] = id + pl["name"] = instance.GetServiceName() + pl["metadata"] = instance.GetMetadata() + cuis := &curator_discovery.ServiceInstance{ + Name: instance.GetServiceName(), + Id: id, + Address: instance.GetHost(), + Port: instance.GetPort(), + Payload: pl, + RegistrationTimeUTC: 0, + } + return cuis +} + +func (zksd zookeeperServiceDiscovery) toZookeeperInstance(cris *curator_discovery.ServiceInstance) registry.ServiceInstance { + pl, ok := cris.Payload.(map[string]interface{}) + if !ok { + logger.Errorf("[zkServiceDiscovery] toZookeeperInstance{%s} payload is not map", cris.Id) + } + md, ok := pl["metadata"].(map[string]string) + return ®istry.DefaultServiceInstance{ + Id: cris.Id, + ServiceName: cris.Name, + Host: cris.Address, + Port: cris.Port, + Enable: true, + Healthy: true, + Metadata: md, + } +} diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index f4aea5903d..918345f25b 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -108,7 +108,7 @@ func WithZkName(name string) Option { } // ValidateZookeeperClient ... -func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { +func ValidateZookeeperClient(container ZkClientFacade, opts ...Option) error { var err error options := &Options{} for _, opt := range opts { @@ -604,6 +604,11 @@ func (z *ZookeeperClient) GetContent(zkPath string) ([]byte, *zk.Stat, error) { return z.Conn.Get(zkPath) } +// GetContent ... +func (z *ZookeeperClient) SetContent(zkPath string, content []byte, version int32) (*zk.Stat, error) { + return z.Conn.Set(zkPath, content, version) +} + // getConn gets zookeeper connection safely func (z *ZookeeperClient) getConn() *zk.Conn { z.RLock() diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go new file mode 100644 index 0000000000..e300af122f --- /dev/null +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -0,0 +1,149 @@ +/* + * 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 curator_discovery + +import ( + "encoding/json" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/remoting/zookeeper" + perrors "github.com/pkg/errors" + "sync" +) + +type ServiceDiscovery struct { + client *zookeeper.ZookeeperClient + mutex *sync.Mutex + basePath string + services *sync.Map +} + +func NewServiceDiscovery(client *zookeeper.ZookeeperClient, basePath string) *ServiceDiscovery { + return &ServiceDiscovery{ + client: client, + mutex: &sync.Mutex{}, + basePath: basePath, + services: &sync.Map{}, + } +} + +func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { + path := sd.basePath + "/" + instance.Name + "/" + instance.Id + data, err := json.Marshal(instance) + if err != nil { + return err + } + err = sd.client.CreateWithValue(path, data) + if err != nil { + return err + } + return nil +} + +func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { + sd.services.Store(instance.Id, instance) + return sd.registerService(instance) +} + +func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { + sd.services.Store(instance.Id, instance) + path := sd.basePath + "/" + instance.Name + "/" + instance.Id + data, err := json.Marshal(instance) + if err != nil { + return err + } + _, err = sd.client.SetContent(path, data, -1) + if err != nil { + return err + } + return nil +} + +func (sd *ServiceDiscovery) UpdateInternalService(name, id string) { + _, ok := sd.services.Load(id) + if !ok { + return + } + instance, err := sd.QueryForInstance(name, id) + if err != nil { + logger.Infof("[zkServiceDiscovery] UpdateInternalService{%s} error = err{%v}", id, err) + return + } + sd.services.Store(instance.Id, instance) + return +} + +func (sd *ServiceDiscovery) UnregisterService(instance *ServiceInstance) error { + sd.services.Delete(instance.Id) + return sd.unregisterService(instance) +} + +func (sd *ServiceDiscovery) unregisterService(instance *ServiceInstance) error { + path := sd.basePath + "/" + instance.Name + "/" + instance.Id + return sd.client.Delete(path) +} + +func (sd *ServiceDiscovery) ReRegisterService() { + sd.services.Range(func(key, value interface{}) bool { + instance, ok := value.(*ServiceInstance) + if !ok { + + } + err := sd.registerService(instance) + if err != nil { + logger.Errorf("[zkServiceDiscovery] registerService{%s} error = err{%v}", instance.Id, perrors.WithStack(err)) + } + return true + }) +} + +func (sd *ServiceDiscovery) QueryForInstances(name string) ([]*ServiceInstance, error) { + ids, err := sd.client.GetChildren(sd.basePath + "/" + name) + if err != nil { + return nil, err + } + var ( + instance *ServiceInstance + instances []*ServiceInstance + ) + for _, id := range ids { + instance, err = sd.QueryForInstance(name, id) + if err != nil { + return nil, err + } + instances = append(instances, instance) + } + return instances, nil +} + +func (sd *ServiceDiscovery) QueryForInstance(name string, id string) (*ServiceInstance, error) { + path := sd.basePath + "/" + name + "/" + id + data, _, err := sd.client.GetContent(path) + if err != nil { + return nil, err + } + instance := &ServiceInstance{} + err = json.Unmarshal(data, instance) + if err != nil { + return nil, err + } + return instance, nil +} + +func (sd *ServiceDiscovery) QueryForNames() ([]string, error) { + return sd.client.GetChildren(sd.basePath) +} diff --git a/remoting/zookeeper/curator_discovery/service_instance.go b/remoting/zookeeper/curator_discovery/service_instance.go new file mode 100644 index 0000000000..1ba7a16f9a --- /dev/null +++ b/remoting/zookeeper/curator_discovery/service_instance.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 curator_discovery + +type ServiceInstance struct { + Name string + Id string + Address string + Port int + Payload interface{} + RegistrationTimeUTC int64 +} diff --git a/remoting/zookeeper/facade.go b/remoting/zookeeper/facade.go index 4e3945388f..504395f76e 100644 --- a/remoting/zookeeper/facade.go +++ b/remoting/zookeeper/facade.go @@ -18,6 +18,7 @@ package zookeeper import ( + "github.com/apache/dubbo-go/common" "sync" ) import ( @@ -26,22 +27,21 @@ import ( ) import ( - "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/logger" ) -type zkClientFacade interface { +type ZkClientFacade interface { ZkClient() *ZookeeperClient SetZkClient(*ZookeeperClient) ZkClientLock() *sync.Mutex WaitGroup() *sync.WaitGroup //for wait group control, zk client listener & zk client container Done() chan struct{} //for zk client control RestartCallBack() bool - common.Node + GetUrl() common.URL } // HandleClientRestart ... -func HandleClientRestart(r zkClientFacade) { +func HandleClientRestart(r ZkClientFacade) { var ( err error diff --git a/remoting/zookeeper/facade_test.go b/remoting/zookeeper/facade_test.go index 01d46da6cc..1cd8f064bb 100644 --- a/remoting/zookeeper/facade_test.go +++ b/remoting/zookeeper/facade_test.go @@ -38,7 +38,7 @@ type mockFacade struct { done chan struct{} } -func newMockFacade(client *ZookeeperClient, url *common.URL) zkClientFacade { +func newMockFacade(client *ZookeeperClient, url *common.URL) ZkClientFacade { mock := &mockFacade{ client: client, URL: url, From b8f53463a8714c35539d3bc717e0d7864c1a42c8 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 16:16:53 +0800 Subject: [PATCH 134/209] fix bug --- metadata/service/remote/service_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 308c631e41..0c1de355c1 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -39,7 +39,7 @@ import ( ) var serviceMetadata = make(map[*identifier.ServiceMetadataIdentifier]common.URL, 4) -var subscribedMetadata = make(map[*identifier.SubscriberMetadataIdentifier][]common.URL, 4) +var subscribedMetadata = make(map[*identifier.SubscriberMetadataIdentifier]string, 4) func getMetadataReportFactory() factory.MetadataReportFactory { return &metadataReportFactory{} @@ -77,9 +77,9 @@ func (metadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []s return nil } -func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urls []common.URL) error { - logger.Infof("SaveSubscribedData, , url is %v", urls) - subscribedMetadata[id] = urls +func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urlListStr string) error { + logger.Infof("SaveSubscribedData, , url is %v", urlListStr) + subscribedMetadata[id] = urlListStr return nil } @@ -93,8 +93,7 @@ func (metadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) strin func TestMetadataService(t *testing.T) { extension.SetMetadataReportFactory("mock", getMetadataReportFactory) - u, err := common.NewURL(fmt.Sprintf( - "mock://127.0.0.1:20000/?sync.report=true")) + u, err := common.NewURL(fmt.Sprintf("mock://127.0.0.1:20000/?sync.report=true")) assert.NoError(t, err) instance.GetMetadataReportInstance(&u) mts, err := NewMetadataService() From b2a04fd033a1b223253648a51bf15dc80fa44445 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 17:40:30 +0800 Subject: [PATCH 135/209] consul metadata report --- metadata/report/consul/report.go | 132 ++++++++++++++++++++++++++ metadata/report/consul/report_test.go | 18 ++++ metadata/report/nacos/report.go | 28 +++--- 3 files changed, 162 insertions(+), 16 deletions(-) create mode 100644 metadata/report/consul/report.go create mode 100644 metadata/report/consul/report_test.go diff --git a/metadata/report/consul/report.go b/metadata/report/consul/report.go new file mode 100644 index 0000000000..8225b22a07 --- /dev/null +++ b/metadata/report/consul/report.go @@ -0,0 +1,132 @@ +/* + * 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 consul + +import ( + consul "github.com/hashicorp/consul/api" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" +) + +func init() { + mf := &consulMetadataReportFactory{} + extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { + return mf + }) +} + +// consulMetadataReport is the implementation of +// MetadataReport based on Consul. +type consulMetadataReport struct { + client *consul.Client +} + +// StoreProviderMetadata stores the metadata. +func (m *consulMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { + kv := &consul.KVPair{Key: providerIdentifier.GetIdentifierKey(), Value: []byte(serviceDefinitions)} + _, err := m.client.KV().Put(kv, nil) + return err +} + +// StoreConsumerMetadata stores the metadata. +func (m *consulMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { + kv := &consul.KVPair{Key: consumerMetadataIdentifier.GetIdentifierKey(), Value: []byte(serviceParameterString)} + _, err := m.client.KV().Put(kv, nil) + return err +} + +// SaveServiceMetadata saves the metadata. +func (m *consulMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { + kv := &consul.KVPair{Key: metadataIdentifier.GetIdentifierKey(), Value: []byte(url.String())} + _, err := m.client.KV().Put(kv, nil) + return err +} + +// RemoveServiceMetadata removes the metadata. +func (m *consulMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier) error { + k := metadataIdentifier.GetIdentifierKey() + _, err := m.client.KV().Delete(k, nil) + return err +} + +// GetExportedURLs gets the urls. +func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { + k := metadataIdentifier.GetIdentifierKey() + kv, _, err := m.client.KV().Get(k, nil) + if err != nil { + panic(err) + } + + if kv == nil { + return []string{} + } + return []string{string(kv.Value)} +} + +// SaveSubscribedData saves the urls. +func (m *consulMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlListStr string) error { + kv := &consul.KVPair{Key: subscriberMetadataIdentifier.GetIdentifierKey(), Value: []byte(urlListStr)} + _, err := m.client.KV().Put(kv, nil) + return err +} + +// GetSubscribedURLs gets the urls. +func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { + k := subscriberMetadataIdentifier.GetIdentifierKey() + kv, _, err := m.client.KV().Get(k, nil) + if err != nil { + panic(err) + } + + if kv == nil { + return []string{} + } + return []string{string(kv.Value)} +} + +// GetServiceDefinition gets the service definition. +func (m *consulMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { + k := metadataIdentifier.GetIdentifierKey() + kv, _, err := m.client.KV().Get(k, nil) + if err != nil { + panic(err) + } + + if kv == nil { + return "" + } + return string(kv.Value) +} + +type consulMetadataReportFactory struct { +} + +func (m *consulMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { + config := &consul.Config{Address: url.Location} + client, err := consul.NewClient(config) + if err != nil { + panic(err) + } + return &consulMetadataReport{client: client} +} \ No newline at end of file diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go new file mode 100644 index 0000000000..d51c32c4f1 --- /dev/null +++ b/metadata/report/consul/report_test.go @@ -0,0 +1,18 @@ +/* + * 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 consul diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 312fd27c84..f5a065b273 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -38,19 +38,19 @@ import ( ) func init() { - ftry := &nacosMetadataReportFactory{} + mf := &nacosMetadataReportFactory{} extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory { - return ftry + return mf }) } -// nacosMetadataReport is the implementation of MetadataReport based Nacos +// nacosMetadataReport is the implementation +// of MetadataReport based on Nacos. type nacosMetadataReport struct { client config_client.IConfigClient } -// StoreProviderMetadata will store the metadata -// metadata including the basic info of the server, provider info, and other user custom info +// StoreProviderMetadata stores the metadata. func (n *nacosMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { return n.storeMetadata(vo.ConfigParam{ DataId: providerIdentifier.GetIdentifierKey(), @@ -59,8 +59,7 @@ func (n *nacosMetadataReport) StoreProviderMetadata(providerIdentifier *identifi }) } -// StoreConsumerMetadata will store the metadata -// metadata including the basic info of the server, consumer info, and other user custom info +// StoreConsumerMetadata stores the metadata. func (n *nacosMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { return n.storeMetadata(vo.ConfigParam{ DataId: consumerMetadataIdentifier.GetIdentifierKey(), @@ -69,8 +68,7 @@ func (n *nacosMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier * }) } -// SaveServiceMetadata will store the metadata -// metadata including the basic info of the server, service info, and other user custom info +// SaveServiceMetadata saves the metadata. func (n *nacosMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { return n.storeMetadata(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), @@ -79,7 +77,7 @@ func (n *nacosMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier }) } -// RemoveServiceMetadata will remove the service metadata +// RemoveServiceMetadata removes the metadata. func (n *nacosMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier) error { return n.deleteMetadata(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), @@ -87,8 +85,7 @@ func (n *nacosMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifi }) } -// GetExportedURLs will look up the exported urls. -// if not found, an empty list will be returned. +// GetExportedURLs gets the urls. func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { return n.getConfigAsArray(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), @@ -96,7 +93,7 @@ func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.Ser }) } -// SaveSubscribedData will convert the urlList to json array and then store it +// SaveSubscribedData saves the urls. func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlListStr string) error { return n.storeMetadata(vo.ConfigParam{ DataId: subscriberMetadataIdentifier.GetIdentifierKey(), @@ -105,8 +102,7 @@ func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *i }) } -// GetSubscribedURLs will lookup the url -// if not found, an empty list will be returned +// GetSubscribedURLs gets the urls. func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { return n.getConfigAsArray(vo.ConfigParam{ DataId: subscriberMetadataIdentifier.GetIdentifierKey(), @@ -114,7 +110,7 @@ func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *id }) } -// GetServiceDefinition will lookup the service definition +// GetServiceDefinition gets the service definition. func (n *nacosMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { return n.getConfig(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), From 117f85f2cbfa3f7ba59d496e614d34a40c7926ee Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 18:36:13 +0800 Subject: [PATCH 136/209] zookeeper metadata report --- metadata/report/consul/report.go | 10 +- metadata/report/nacos/report.go | 6 +- metadata/report/zookeeper/report.go | 126 +++++++++++++++++++++++ metadata/report/zookeeper/report_test.go | 18 ++++ remoting/zookeeper/client.go | 6 +- 5 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 metadata/report/zookeeper/report.go create mode 100644 metadata/report/zookeeper/report_test.go diff --git a/metadata/report/consul/report.go b/metadata/report/consul/report.go index 8225b22a07..ca57f40363 100644 --- a/metadata/report/consul/report.go +++ b/metadata/report/consul/report.go @@ -37,7 +37,7 @@ func init() { } // consulMetadataReport is the implementation of -// MetadataReport based on Consul. +// MetadataReport based on consul. type consulMetadataReport struct { client *consul.Client } @@ -85,8 +85,8 @@ func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.Se } // SaveSubscribedData saves the urls. -func (m *consulMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlListStr string) error { - kv := &consul.KVPair{Key: subscriberMetadataIdentifier.GetIdentifierKey(), Value: []byte(urlListStr)} +func (m *consulMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urls string) error { + kv := &consul.KVPair{Key: subscriberMetadataIdentifier.GetIdentifierKey(), Value: []byte(urls)} _, err := m.client.KV().Put(kv, nil) return err } @@ -122,11 +122,11 @@ func (m *consulMetadataReport) GetServiceDefinition(metadataIdentifier *identifi type consulMetadataReportFactory struct { } -func (m *consulMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { +func (mf *consulMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { config := &consul.Config{Address: url.Location} client, err := consul.NewClient(config) if err != nil { panic(err) } return &consulMetadataReport{client: client} -} \ No newline at end of file +} diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index f5a065b273..7db4c85d9a 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -45,7 +45,7 @@ func init() { } // nacosMetadataReport is the implementation -// of MetadataReport based on Nacos. +// of MetadataReport based on nacos. type nacosMetadataReport struct { client config_client.IConfigClient } @@ -94,11 +94,11 @@ func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.Ser } // SaveSubscribedData saves the urls. -func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urlListStr string) error { +func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urls string) error { return n.storeMetadata(vo.ConfigParam{ DataId: subscriberMetadataIdentifier.GetIdentifierKey(), Group: subscriberMetadataIdentifier.Group, - Content: urlListStr, + Content: urls, }) } diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go new file mode 100644 index 0000000000..76948379ed --- /dev/null +++ b/metadata/report/zookeeper/report.go @@ -0,0 +1,126 @@ +/* + * 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 zookeeper + +import ( + "strings" +) + +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/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/metadata/report/factory" + "github.com/apache/dubbo-go/remoting/zookeeper" +) + +func init() { + mf := &zookeeperMetadataReportFactory{} + extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { + return mf + }) +} + +// zookeeperMetadataReport is the implementation of +// MetadataReport based on zookeeper. +type zookeeperMetadataReport struct { + client *zookeeper.ZookeeperClient + rootDir string +} + +// StoreProviderMetadata stores the metadata. +func (m *zookeeperMetadataReport) StoreProviderMetadata(providerIdentifier *identifier.MetadataIdentifier, serviceDefinitions string) error { + k := m.rootDir + providerIdentifier.GetFilePathKey() + return m.client.CreateWithValue(k, []byte(serviceDefinitions)) +} + +// StoreConsumerMetadata stores the metadata. +func (m *zookeeperMetadataReport) StoreConsumerMetadata(consumerMetadataIdentifier *identifier.MetadataIdentifier, serviceParameterString string) error { + k := m.rootDir + consumerMetadataIdentifier.GetFilePathKey() + return m.client.CreateWithValue(k, []byte(serviceParameterString)) +} + +// SaveServiceMetadata saves the metadata. +func (m *zookeeperMetadataReport) SaveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier, url common.URL) error { + k := m.rootDir + metadataIdentifier.GetFilePathKey() + return m.client.CreateWithValue(k, []byte(url.String())) +} + +// RemoveServiceMetadata removes the metadata. +func (m *zookeeperMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifier.ServiceMetadataIdentifier) error { + k := m.rootDir + metadataIdentifier.GetFilePathKey() + return m.client.Delete(k) +} + +// GetExportedURLs gets the urls. +func (m *zookeeperMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { + k := m.rootDir + metadataIdentifier.GetFilePathKey() + v, _, err := m.client.GetContent(k) + if err != nil { + panic(err) + } + return []string{string(v)} +} + +// SaveSubscribedData saves the urls. +func (m *zookeeperMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier, urls string) error { + k := m.rootDir + subscriberMetadataIdentifier.GetFilePathKey() + return m.client.CreateWithValue(k, []byte(urls)) +} + +// GetSubscribedURLs gets the urls. +func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { + k := m.rootDir + subscriberMetadataIdentifier.GetFilePathKey() + v, _, err := m.client.GetContent(k) + if err != nil { + panic(err) + } + return []string{string(v)} +} + +// GetServiceDefinition gets the service definition. +func (m *zookeeperMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { + k := m.rootDir + metadataIdentifier.GetFilePathKey() + v, _, err := m.client.GetContent(k) + if err != nil { + panic(err) + } + return string(v) +} + +type zookeeperMetadataReportFactory struct { +} + +func (mf *zookeeperMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { + client, err := zookeeper.NewZookeeperClient("zookeeperMetadataReport", strings.Split(url.Location, ","), 15) + if err != nil { + panic(err) + } + + rootDir := url.GetParam(constant.GROUP_KEY, "dubbo") + if !strings.HasPrefix(rootDir, constant.PATH_SEPARATOR) { + rootDir = constant.PATH_SEPARATOR + rootDir + } + if rootDir != constant.PATH_SEPARATOR { + rootDir = rootDir + constant.PATH_SEPARATOR + } + + return &zookeeperMetadataReport{client: client, rootDir: rootDir} +} diff --git a/metadata/report/zookeeper/report_test.go b/metadata/report/zookeeper/report_test.go new file mode 100644 index 0000000000..e386d95ef8 --- /dev/null +++ b/metadata/report/zookeeper/report_test.go @@ -0,0 +1,18 @@ +/* + * 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 zookeeper diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 7904dc74e8..b6c49e7056 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -89,8 +89,6 @@ func StateToString(state zk.State) string { default: return state.String() } - - return "zookeeper unknown state" } // Options ... @@ -137,7 +135,7 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location) } zkAddresses := strings.Split(url.Location, ",") - newClient, err := newZookeeperClient(options.zkName, zkAddresses, timeout) + newClient, err := NewZookeeperClient(options.zkName, zkAddresses, timeout) if err != nil { logger.Warnf("newZookeeperClient(name{%s}, zk address{%v}, timeout{%d}) = error{%v}", options.zkName, url.Location, timeout.String(), err) @@ -165,7 +163,7 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.PrimitiveURL) } -func newZookeeperClient(name string, zkAddrs []string, timeout time.Duration) (*ZookeeperClient, error) { +func NewZookeeperClient(name string, zkAddrs []string, timeout time.Duration) (*ZookeeperClient, error) { var ( err error event <-chan zk.Event From f1576d1b63612de8770f402ac915c3f76b4b2025 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 19:03:05 +0800 Subject: [PATCH 137/209] fix --- metadata/service/remote/service_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 0c1de355c1..12ef472ecb 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -77,9 +77,9 @@ func (metadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []s return nil } -func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urlListStr string) error { - logger.Infof("SaveSubscribedData, , url is %v", urlListStr) - subscribedMetadata[id] = urlListStr +func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urls string) error { + logger.Infof("SaveSubscribedData, , url is %v", urls) + subscribedMetadata[id] = urls return nil } From 242e9f27d26684a40ab8c5813c73f51bc855c18d Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 22:54:47 +0800 Subject: [PATCH 138/209] fix --- metadata/report/nacos/report_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 254b92363b..5a646c9a38 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -42,6 +42,7 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { providerMi := newMetadataIdentifier("server") providerMeta := "provider" err := rpt.StoreProviderMetadata(providerMi, providerMeta) + assert.Nil(t, err) consumerMi := newMetadataIdentifier("client") consumerMeta := "consumer" @@ -50,7 +51,6 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { serviceMi := newServiceMetadataIdentifier() serviceUrl, _ := common.NewURL("registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) - err = rpt.SaveServiceMetadata(serviceMi, serviceUrl) assert.Nil(t, err) @@ -68,7 +68,6 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { err = rpt.RemoveServiceMetadata(serviceMi) assert.Nil(t, err) - } func newSubscribeMetadataIdentifier() *identifier.SubscriberMetadataIdentifier { @@ -76,7 +75,6 @@ func newSubscribeMetadataIdentifier() *identifier.SubscriberMetadataIdentifier { Revision: "subscribe", MetadataIdentifier: *newMetadataIdentifier("provider"), } - } func newServiceMetadataIdentifier() *identifier.ServiceMetadataIdentifier { From 81a458c43b0dd2ccdc28ba784cfbbc690595899f Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Fri, 26 Jun 2020 23:25:48 +0800 Subject: [PATCH 139/209] import sort --- metadata/report/delegate/delegate_report.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 282e751443..08092a7ddc 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -19,7 +19,6 @@ package delegate import ( "encoding/json" - perrors "github.com/pkg/errors" "runtime/debug" "sync" "time" @@ -27,6 +26,7 @@ import ( import ( "github.com/go-co-op/gocron" + perrors "github.com/pkg/errors" "go.uber.org/atomic" ) From 404cd00af894e42933f292e9cb1053f6fae78698 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 27 Jun 2020 21:59:54 +0800 Subject: [PATCH 140/209] consul metadata report unit test --- metadata/report/consul/report_test.go | 144 ++++++++++++++++++++++++++ metadata/report/nacos/report_test.go | 4 +- registry/consul/utils_test.go | 43 +------- remoting/consul/agent.go | 70 +++++++++++++ remoting/consul/agent_test.go | 32 ++++++ 5 files changed, 253 insertions(+), 40 deletions(-) create mode 100644 remoting/consul/agent.go create mode 100644 remoting/consul/agent_test.go diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go index d51c32c4f1..5d7a9a3517 100644 --- a/metadata/report/consul/report_test.go +++ b/metadata/report/consul/report_test.go @@ -16,3 +16,147 @@ */ package consul + +import ( + "encoding/json" + "net/url" + "strconv" + "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/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" + "github.com/apache/dubbo-go/remoting/consul" +) + +func newProviderRegistryUrl(host string, port int) *common.URL { + url1 := common.NewURLWithOptions( + common.WithIp(host), + common.WithPort(strconv.Itoa(port)), + common.WithParams(url.Values{}), + common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)), + ) + return url1 +} + +func newBaseMetadataIdentifier(side string) *identifier.BaseMetadataIdentifier { + return &identifier.BaseMetadataIdentifier{ + ServiceInterface: "org.apache.HelloWorld", + Version: "1.0.0", + Group: "group", + Side: side, + } +} + +func newMetadataIdentifier(side string) *identifier.MetadataIdentifier { + return &identifier.MetadataIdentifier{ + Application: "application", + BaseMetadataIdentifier: *newBaseMetadataIdentifier(side), + } +} + +func newServiceMetadataIdentifier(side string) *identifier.ServiceMetadataIdentifier { + return &identifier.ServiceMetadataIdentifier{ + Revision: "1.0", + Protocol: "dubbo", + BaseMetadataIdentifier: *newBaseMetadataIdentifier(side), + } +} + +func newSubscribeMetadataIdentifier(side string) *identifier.SubscriberMetadataIdentifier { + return &identifier.SubscriberMetadataIdentifier{ + Revision: "1.0", + MetadataIdentifier: *newMetadataIdentifier(side), + } +} + +type consulMetadataReportTestSuite struct { + t *testing.T + m report.MetadataReport +} + +func newConsulMetadataReportTestSuite(t *testing.T, m report.MetadataReport) *consulMetadataReportTestSuite { + return &consulMetadataReportTestSuite{t: t, m: m} +} + +func (suite *consulMetadataReportTestSuite) testStoreProviderMetadata() { + providerMi := newMetadataIdentifier("provider") + providerMeta := "provider" + err := suite.m.StoreProviderMetadata(providerMi, providerMeta) + assert.NoError(suite.t, err) +} + +func (suite *consulMetadataReportTestSuite) testStoreConsumerMetadata() { + consumerMi := newMetadataIdentifier("consumer") + consumerMeta := "consumer" + err := suite.m.StoreProviderMetadata(consumerMi, consumerMeta) + assert.NoError(suite.t, err) +} + +func (suite *consulMetadataReportTestSuite) testSaveServiceMetadata(url common.URL) { + serviceMi := newServiceMetadataIdentifier("provider") + err := suite.m.SaveServiceMetadata(serviceMi, url) + assert.NoError(suite.t, err) +} + +func (suite *consulMetadataReportTestSuite) testRemoveServiceMetadata() { + serviceMi := newServiceMetadataIdentifier("provider") + err := suite.m.RemoveServiceMetadata(serviceMi) + assert.NoError(suite.t, err) +} + +func (suite *consulMetadataReportTestSuite) testGetExportedURLs() { + serviceMi := newServiceMetadataIdentifier("provider") + urls := suite.m.GetExportedURLs(serviceMi) + assert.Equal(suite.t, 1, len(urls)) +} + +func (suite *consulMetadataReportTestSuite) testSaveSubscribedData(url common.URL) { + subscribeMi := newSubscribeMetadataIdentifier("provider") + urls := []string{url.String()} + bytes, _ := json.Marshal(urls) + err := suite.m.SaveSubscribedData(subscribeMi, string(bytes)) + assert.Nil(suite.t, err) +} + +func (suite *consulMetadataReportTestSuite) testGetSubscribedURLs() { + subscribeMi := newSubscribeMetadataIdentifier("provider") + urls := suite.m.GetSubscribedURLs(subscribeMi) + assert.Equal(suite.t, 1, len(urls)) +} + +func (suite *consulMetadataReportTestSuite) testGetServiceDefinition() { + providerMi := newMetadataIdentifier("provider") + providerMeta := suite.m.GetServiceDefinition(providerMi) + assert.Equal(suite.t, "provider", providerMeta) +} + +func test1(t *testing.T) { + consulAgent := consul.NewConsulAgent(t, 8500) + defer consulAgent.Close() + + url := newProviderRegistryUrl("localhost", 8500) + mf := extension.GetMetadataReportFactory("consul") + m := mf.CreateMetadataReport(url) + + suite := newConsulMetadataReportTestSuite(t, m) + suite.testStoreProviderMetadata() + suite.testStoreConsumerMetadata() + suite.testSaveServiceMetadata(*url) + suite.testGetExportedURLs() + suite.testRemoveServiceMetadata() + suite.testSaveSubscribedData(*url) + suite.testGetServiceDefinition() +} + +func TestConsulMetadataReport(t *testing.T) { + t.Run("test1", test1) +} diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 5a646c9a38..971c7bfe8f 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -58,8 +58,8 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { assert.Equal(t, 1, len(exportedUrls)) subMi := newSubscribeMetadataIdentifier() - urlList := []string{serviceUrl.String()} - bytes, _ := json.Marshal(urlList) + urls := []string{serviceUrl.String()} + bytes, _ := json.Marshal(urls) err = rpt.SaveSubscribedData(subMi, string(bytes)) assert.Nil(t, err) diff --git a/registry/consul/utils_test.go b/registry/consul/utils_test.go index d66600b773..1ef2004139 100644 --- a/registry/consul/utils_test.go +++ b/registry/consul/utils_test.go @@ -19,24 +19,19 @@ package consul import ( "fmt" - "io/ioutil" "net" "net/url" - "os" "strconv" "sync" "testing" ) -import ( - "github.com/hashicorp/consul/agent" -) - import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/remoting" + "github.com/apache/dubbo-go/remoting/consul" ) var ( @@ -90,34 +85,6 @@ func newConsumerUrl(host string, port int, service string, protocol string) comm return *url1 } -type testConsulAgent struct { - dataDir string - testAgent *agent.TestAgent -} - -func newConsulAgent(t *testing.T, port int) *testConsulAgent { - dataDir, _ := ioutil.TempDir("./", "agent") - hcl := ` - ports { - http = ` + strconv.Itoa(port) + ` - } - data_dir = "` + dataDir + `" - ` - testAgent := &agent.TestAgent{Name: t.Name(), DataDir: dataDir, HCL: hcl} - testAgent.Start(t) - - consulAgent := &testConsulAgent{ - dataDir: dataDir, - testAgent: testAgent, - } - return consulAgent -} - -func (consulAgent *testConsulAgent) close() { - consulAgent.testAgent.Shutdown() - os.RemoveAll(consulAgent.dataDir) -} - type testServer struct { listener net.Listener wg sync.WaitGroup @@ -184,8 +151,8 @@ func (suite *consulRegistryTestSuite) close() { // register -> subscribe -> unregister func test1(t *testing.T) { - consulAgent := newConsulAgent(t, registryPort) - defer consulAgent.close() + consulAgent := consul.NewConsulAgent(t, registryPort) + defer consulAgent.Close() server := newServer(providerHost, providerPort) defer server.close() @@ -204,8 +171,8 @@ func test1(t *testing.T) { // subscribe -> register func test2(t *testing.T) { - consulAgent := newConsulAgent(t, registryPort) - defer consulAgent.close() + consulAgent := consul.NewConsulAgent(t, registryPort) + defer consulAgent.Close() server := newServer(providerHost, providerPort) defer server.close() diff --git a/remoting/consul/agent.go b/remoting/consul/agent.go new file mode 100644 index 0000000000..fd0694bde3 --- /dev/null +++ b/remoting/consul/agent.go @@ -0,0 +1,70 @@ +/* + * 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 consul + +import ( + "io/ioutil" + "os" + "strconv" + "testing" +) + +import ( + "github.com/hashicorp/consul/agent" +) + +// Consul agent, used for test, simulates +// an embedded consul server. +type ConsulAgent struct { + dataDir string + testAgent *agent.TestAgent +} + +func NewConsulAgent(t *testing.T, port int) *ConsulAgent { + dataDir, _ := ioutil.TempDir("./", "agent") + hcl := ` + ports { + http = ` + strconv.Itoa(port) + ` + } + data_dir = "` + dataDir + `" + ` + testAgent := &agent.TestAgent{Name: t.Name(), DataDir: dataDir, HCL: hcl} + testAgent.Start(t) + + consulAgent := &ConsulAgent{ + dataDir: dataDir, + testAgent: testAgent, + } + return consulAgent +} + +func (consulAgent *ConsulAgent) Close() error { + var err error + + err = consulAgent.testAgent.Shutdown() + if err != nil { + return err + } + + err = os.RemoveAll(consulAgent.dataDir) + if err != nil { + return err + } + + return nil +} diff --git a/remoting/consul/agent_test.go b/remoting/consul/agent_test.go new file mode 100644 index 0000000000..8cf0ac6cd8 --- /dev/null +++ b/remoting/consul/agent_test.go @@ -0,0 +1,32 @@ +/* + * 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 consul + +import ( + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +func TestNewConsulAgent(t *testing.T) { + consulAgent := NewConsulAgent(t, 8500) + err := consulAgent.Close() + assert.NoError(t, err) +} From 4e782b358e90d1b1af288d20751517d363cbfbb9 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 27 Jun 2020 23:00:56 +0800 Subject: [PATCH 141/209] zookeeper's service_discovery modify --- registry/zookeeper/service_discovery.go | 106 ++++++++++-------- registry/zookeeper/service_discovery_test.go | 96 ++++++++++++++++ .../curator_discovery/service_discovery.go | 69 ++++++++++-- 3 files changed, 217 insertions(+), 54 deletions(-) create mode 100644 registry/zookeeper/service_discovery_test.go diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index 5daf3e1a2c..687f21c854 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -19,6 +19,7 @@ package zookeeper import ( "fmt" + "net/url" "strconv" "strings" "sync" @@ -59,14 +60,15 @@ func init() { } type zookeeperServiceDiscovery struct { - client *zookeeper.ZookeeperClient - csd *curator_discovery.ServiceDiscovery - listener *zookeeper.ZkEventListener - url *common.URL - wg sync.WaitGroup - cltLock sync.Mutex - done chan struct{} - rootPath string + client *zookeeper.ZookeeperClient + csd *curator_discovery.ServiceDiscovery + listener *zookeeper.ZkEventListener + url *common.URL + wg sync.WaitGroup + cltLock sync.Mutex + done chan struct{} + rootPath string + listenNames []string } func newZookeeperServiceDiscovery(name string) (registry.ServiceDiscovery, error) { @@ -92,86 +94,87 @@ func newZookeeperServiceDiscovery(name string) (registry.ServiceDiscovery, error if !ok { return nil, perrors.New("could not find the remote config for name: " + sdc.RemoteRef) } - basePath := remoteConfig.GetParam("rootPath", "/services") + rootPath := remoteConfig.GetParam("rootPath", "/services") url := common.NewURLWithOptions( - common.WithLocation(remoteConfig.Address), + common.WithParams(make(url.Values)), common.WithPassword(remoteConfig.Password), common.WithUsername(remoteConfig.Username), common.WithParamsValue(constant.REGISTRY_TIMEOUT_KEY, remoteConfig.TimeoutStr)) + url.Location = remoteConfig.Address zksd := &zookeeperServiceDiscovery{ url: url, - rootPath: basePath, + rootPath: rootPath, } err := zookeeper.ValidateZookeeperClient(zksd, zookeeper.WithZkName(ServiceDiscoveryZkClient)) if err != nil { return nil, err } go zookeeper.HandleClientRestart(zksd) - zksd.listener = zookeeper.NewZkEventListener(zksd.client) - zksd.listener.ListenServiceEvent(nil, basePath, zksd) - zksd.csd = curator_discovery.NewServiceDiscovery(zksd.client, basePath) + zksd.csd = curator_discovery.NewServiceDiscovery(zksd.client, rootPath) return zksd, nil } -func (zksd zookeeperServiceDiscovery) ZkClient() *zookeeper.ZookeeperClient { +func (zksd *zookeeperServiceDiscovery) ZkClient() *zookeeper.ZookeeperClient { return zksd.client } -func (zksd zookeeperServiceDiscovery) SetZkClient(client *zookeeper.ZookeeperClient) { +func (zksd *zookeeperServiceDiscovery) SetZkClient(client *zookeeper.ZookeeperClient) { zksd.client = client } -func (zksd zookeeperServiceDiscovery) ZkClientLock() *sync.Mutex { +func (zksd *zookeeperServiceDiscovery) ZkClientLock() *sync.Mutex { return &zksd.cltLock } -func (zksd zookeeperServiceDiscovery) WaitGroup() *sync.WaitGroup { +func (zksd *zookeeperServiceDiscovery) WaitGroup() *sync.WaitGroup { return &zksd.wg } -func (zksd zookeeperServiceDiscovery) Done() chan struct{} { +func (zksd *zookeeperServiceDiscovery) Done() chan struct{} { return zksd.done } -func (zksd zookeeperServiceDiscovery) RestartCallBack() bool { +func (zksd *zookeeperServiceDiscovery) RestartCallBack() bool { zksd.csd.ReRegisterService() - zksd.listener.ListenServiceEvent(nil, zksd.rootPath, zksd) + for _, name := range zksd.listenNames { + zksd.csd.ListenServiceEvent(name, zksd) + } return true } -func (zksd zookeeperServiceDiscovery) GetUrl() common.URL { +func (zksd *zookeeperServiceDiscovery) GetUrl() common.URL { return *zksd.url } -func (zksd zookeeperServiceDiscovery) String() string { +func (zksd *zookeeperServiceDiscovery) String() string { return fmt.Sprintf("zookeeper-service-discovery[%s]", zksd.url) } -func (zksd zookeeperServiceDiscovery) Destroy() error { +func (zksd *zookeeperServiceDiscovery) Destroy() error { zksd.client.Close() return nil } -func (zksd zookeeperServiceDiscovery) Register(instance registry.ServiceInstance) error { +func (zksd *zookeeperServiceDiscovery) Register(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.RegisterService(cris) } -func (zksd zookeeperServiceDiscovery) Update(instance registry.ServiceInstance) error { +func (zksd *zookeeperServiceDiscovery) Update(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.UpdateService(cris) } -func (zksd zookeeperServiceDiscovery) Unregister(instance registry.ServiceInstance) error { +func (zksd *zookeeperServiceDiscovery) Unregister(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.UnregisterService(cris) } -func (zksd zookeeperServiceDiscovery) GetDefaultPageSize() int { +func (zksd *zookeeperServiceDiscovery) GetDefaultPageSize() int { return registry.DefaultPageSize } -func (zksd zookeeperServiceDiscovery) GetServices() *gxset.HashSet { +func (zksd *zookeeperServiceDiscovery) GetServices() *gxset.HashSet { services, err := zksd.csd.QueryForNames() res := gxset.NewSet() if err != nil { @@ -184,7 +187,7 @@ func (zksd zookeeperServiceDiscovery) GetServices() *gxset.HashSet { return res } -func (zksd zookeeperServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { +func (zksd *zookeeperServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { criss, err := zksd.csd.QueryForInstances(serviceName) if err != nil { logger.Errorf("[zkServiceDiscovery] Could not query the instances for service{%s}, error = err{%v} ", @@ -198,7 +201,7 @@ func (zksd zookeeperServiceDiscovery) GetInstances(serviceName string) []registr return iss } -func (zksd zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { +func (zksd *zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { all := zksd.GetInstances(serviceName) res := make([]interface{}, 0, pageSize) // could not use res = all[a:b] here because the res should be []interface{}, not []ServiceInstance @@ -208,11 +211,26 @@ func (zksd zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, off return gxpage.New(offset, pageSize, res, len(all)) } -func (zksd zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, _ bool) gxpage.Pager { - return zksd.GetInstancesByPage(serviceName, offset, pageSize) +func (zksd *zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { + all := zksd.GetInstances(serviceName) + res := make([]interface{}, 0, pageSize) + // could not use res = all[a:b] here because the res should be []interface{}, not []ServiceInstance + var ( + i = offset + count = 0 + ) + for i < len(all) && count < pageSize { + ins := all[i] + if ins.IsHealthy() == healthy { + res = append(res, all[i]) + count++ + } + i++ + } + return gxpage.New(offset, pageSize, res, len(all)) } -func (zksd zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { +func (zksd *zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { res := make(map[string]gxpage.Pager, len(serviceNames)) for _, name := range serviceNames { res[name] = zksd.GetInstancesByPage(name, offset, requestedSize) @@ -220,28 +238,28 @@ func (zksd zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string, return res } -func (zksd zookeeperServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { +func (zksd *zookeeperServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + zksd.listenNames = append(zksd.listenNames, listener.ServiceName) + zksd.csd.ListenServiceEvent(listener.ServiceName, zksd) return nil } -func (zksd zookeeperServiceDiscovery) DispatchEventByServiceName(serviceName string) error { +func (zksd *zookeeperServiceDiscovery) DispatchEventByServiceName(serviceName string) error { return zksd.DispatchEventForInstances(serviceName, zksd.GetInstances(serviceName)) } -func (zksd zookeeperServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { +func (zksd *zookeeperServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { return zksd.DispatchEvent(registry.NewServiceInstancesChangedEvent(serviceName, instances)) } -func (zksd zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { +func (zksd *zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { extension.GetGlobalDispatcher().Dispatch(event) return nil } -func (zksd zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { +func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { path := eventType.Path - name := strings.Split(path, "/")[1] - id := strings.Split(path, "/")[2] - zksd.csd.UpdateInternalService(name, id) + name := strings.Split(path, "/")[2] err := zksd.DispatchEventByServiceName(name) if err != nil { logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", name, err) @@ -249,7 +267,7 @@ func (zksd zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool return true } -func (zksd zookeeperServiceDiscovery) toCuratorInstance(instance registry.ServiceInstance) *curator_discovery.ServiceInstance { +func (zksd *zookeeperServiceDiscovery) toCuratorInstance(instance registry.ServiceInstance) *curator_discovery.ServiceInstance { id := instance.GetHost() + ":" + strconv.Itoa(instance.GetPort()) pl := make(map[string]interface{}) pl["id"] = id @@ -266,7 +284,7 @@ func (zksd zookeeperServiceDiscovery) toCuratorInstance(instance registry.Servic return cuis } -func (zksd zookeeperServiceDiscovery) toZookeeperInstance(cris *curator_discovery.ServiceInstance) registry.ServiceInstance { +func (zksd *zookeeperServiceDiscovery) toZookeeperInstance(cris *curator_discovery.ServiceInstance) registry.ServiceInstance { pl, ok := cris.Payload.(map[string]interface{}) if !ok { logger.Errorf("[zkServiceDiscovery] toZookeeperInstance{%s} payload is not map", cris.Id) diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go new file mode 100644 index 0000000000..586b85ec9f --- /dev/null +++ b/registry/zookeeper/service_discovery_test.go @@ -0,0 +1,96 @@ +/* + * 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 zookeeper + +import ( + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/registry" + "github.com/dubbogo/go-zookeeper/zk" + "github.com/stretchr/testify/assert" + "strconv" + "testing" +) + +var testName = "test" + +func prepareData(t *testing.T) *zk.TestCluster { + ts, err := zk.StartTestCluster(1, nil, nil) + assert.NoError(t, err) + assert.NotNil(t, ts.Servers[0]) + address := "127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port) + + config.GetBaseConfig().ServiceDiscoveries[testName] = &config.ServiceDiscoveryConfig{ + Protocol: "zookeeper", + RemoteRef: "test", + } + + config.GetBaseConfig().Remotes[testName] = &config.RemoteConfig{ + Address: address, + TimeoutStr: "10s", + } + return ts +} + +func TestNewZookeeperServiceDiscovery(t *testing.T) { + name := "zookeeper1" + _, err := newZookeeperServiceDiscovery(name) + + // the ServiceDiscoveryConfig not found + assert.NotNil(t, err) + + sdc := &config.ServiceDiscoveryConfig{ + Protocol: "zookeeper", + RemoteRef: "mock", + } + config.GetBaseConfig().ServiceDiscoveries[name] = sdc + _, err = newZookeeperServiceDiscovery(name) + + // RemoteConfig not found + assert.NotNil(t, err) +} + +func TestCURDZookeeperServiceDiscovery(t *testing.T) { + ts := prepareData(t) + defer ts.Stop() + sd, err := newZookeeperServiceDiscovery(testName) + assert.Nil(t, err) + md := make(map[string]string) + md["t1"] = "test1" + err = sd.Register(®istry.DefaultServiceInstance{ + Id: "testId", + ServiceName: testName, + Host: "127.0.0.1", + Port: 2233, + Enable: true, + Healthy: true, + Metadata: md, + }) + assert.Nil(t, err) + tests := sd.GetInstances(testName) + assert.Equal(t, tests[0].GetId(), "127.0.0.1:2233") + err = sd.Unregister(®istry.DefaultServiceInstance{ + Id: "testId", + ServiceName: testName, + Host: "127.0.0.1", + Port: 2233, + Enable: true, + Healthy: true, + Metadata: nil, + }) + assert.Nil(t, err) +} diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index e300af122f..2301a21ae7 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -19,10 +19,19 @@ package curator_discovery import ( "encoding/json" + "strings" + "sync" +) + +import ( + perrors "github.com/pkg/errors" +) + +import ( + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/remoting" "github.com/apache/dubbo-go/remoting/zookeeper" - perrors "github.com/pkg/errors" - "sync" ) type ServiceDiscovery struct { @@ -30,6 +39,7 @@ type ServiceDiscovery struct { mutex *sync.Mutex basePath string services *sync.Map + listener *zookeeper.ZkEventListener } func NewServiceDiscovery(client *zookeeper.ZookeeperClient, basePath string) *ServiceDiscovery { @@ -38,11 +48,12 @@ func NewServiceDiscovery(client *zookeeper.ZookeeperClient, basePath string) *Se mutex: &sync.Mutex{}, basePath: basePath, services: &sync.Map{}, + listener: zookeeper.NewZkEventListener(client), } } func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { - path := sd.basePath + "/" + instance.Name + "/" + instance.Id + path := sd.pathForInstance(instance.Name, instance.Id) data, err := json.Marshal(instance) if err != nil { return err @@ -55,13 +66,20 @@ func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { } func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { - sd.services.Store(instance.Id, instance) - return sd.registerService(instance) + _, loaded := sd.services.LoadOrStore(instance.Id, instance) + err := sd.registerService(instance) + if err != nil { + return err + } + if !loaded { + sd.ListenServiceInstanceEvent(instance.Name, instance.Id, sd) + } + return nil } func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { sd.services.Store(instance.Id, instance) - path := sd.basePath + "/" + instance.Name + "/" + instance.Id + path := sd.pathForInstance(instance.Name, instance.Id) data, err := json.Marshal(instance) if err != nil { return err @@ -73,7 +91,7 @@ func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { return nil } -func (sd *ServiceDiscovery) UpdateInternalService(name, id string) { +func (sd *ServiceDiscovery) updateInternalService(name, id string) { _, ok := sd.services.Load(id) if !ok { return @@ -93,7 +111,7 @@ func (sd *ServiceDiscovery) UnregisterService(instance *ServiceInstance) error { } func (sd *ServiceDiscovery) unregisterService(instance *ServiceInstance) error { - path := sd.basePath + "/" + instance.Name + "/" + instance.Id + path := sd.pathForInstance(instance.Name, instance.Id) return sd.client.Delete(path) } @@ -107,12 +125,13 @@ func (sd *ServiceDiscovery) ReRegisterService() { if err != nil { logger.Errorf("[zkServiceDiscovery] registerService{%s} error = err{%v}", instance.Id, perrors.WithStack(err)) } + sd.ListenServiceInstanceEvent(instance.Name, instance.Id, sd) return true }) } func (sd *ServiceDiscovery) QueryForInstances(name string) ([]*ServiceInstance, error) { - ids, err := sd.client.GetChildren(sd.basePath + "/" + name) + ids, err := sd.client.GetChildren(sd.pathForName(name)) if err != nil { return nil, err } @@ -131,7 +150,7 @@ func (sd *ServiceDiscovery) QueryForInstances(name string) ([]*ServiceInstance, } func (sd *ServiceDiscovery) QueryForInstance(name string, id string) (*ServiceInstance, error) { - path := sd.basePath + "/" + name + "/" + id + path := sd.pathForInstance(name, id) data, _, err := sd.client.GetContent(path) if err != nil { return nil, err @@ -147,3 +166,33 @@ func (sd *ServiceDiscovery) QueryForInstance(name string, id string) (*ServiceIn func (sd *ServiceDiscovery) QueryForNames() ([]string, error) { return sd.client.GetChildren(sd.basePath) } + +func (sd *ServiceDiscovery) ListenServiceEvent(name string, listener remoting.DataListener) { + sd.listener.ListenServiceEvent(nil, sd.pathForName(name), listener) +} + +func (sd *ServiceDiscovery) ListenServiceInstanceEvent(name, id string, listener remoting.DataListener) { + sd.listener.ListenServiceEvent(nil, sd.pathForInstance(name, id), listener) +} + +func (sd *ServiceDiscovery) DataChange(eventType remoting.Event) bool { + path := eventType.Path + name, id := sd.getNameAndId(path) + sd.updateInternalService(name, id) + return true +} + +func (sd *ServiceDiscovery) getNameAndId(path string) (string, string) { + pathSlice := strings.Split(path, constant.PATH_SEPARATOR) + name := pathSlice[2] + id := pathSlice[3] + return name, id +} + +func (sd *ServiceDiscovery) pathForInstance(name, id string) string { + return sd.basePath + constant.PATH_SEPARATOR + name + constant.PATH_SEPARATOR + id +} + +func (sd *ServiceDiscovery) pathForName(name string) string { + return sd.basePath + constant.PATH_SEPARATOR + name +} From c066b505f7b6714094f10cb9a48ec70a06c64279 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 27 Jun 2020 23:08:32 +0800 Subject: [PATCH 142/209] zookeeper's service_discovery modify --- registry/zookeeper/service_discovery_test.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go index 586b85ec9f..2f1639ad1e 100644 --- a/registry/zookeeper/service_discovery_test.go +++ b/registry/zookeeper/service_discovery_test.go @@ -18,14 +18,20 @@ package zookeeper import ( - "github.com/apache/dubbo-go/config" - "github.com/apache/dubbo-go/registry" - "github.com/dubbogo/go-zookeeper/zk" - "github.com/stretchr/testify/assert" "strconv" "testing" ) +import ( + "github.com/dubbogo/go-zookeeper/zk" + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/registry" +) + var testName = "test" func prepareData(t *testing.T) *zk.TestCluster { From 7ac57ce9dc5911db952e8ed3325eec2d818d46ab Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 28 Jun 2020 12:01:32 +0800 Subject: [PATCH 143/209] zookeeper's service_discovery fix --- registry/zookeeper/service_discovery.go | 8 +- registry/zookeeper/service_discovery_test.go | 10 +++ remoting/etcdv3/listener.go | 6 +- .../curator_discovery/service_discovery.go | 80 +++++++++++++++---- remoting/zookeeper/listener.go | 24 ++++-- 5 files changed, 103 insertions(+), 25 deletions(-) diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index 687f21c854..1e827340dd 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -66,6 +66,7 @@ type zookeeperServiceDiscovery struct { url *common.URL wg sync.WaitGroup cltLock sync.Mutex + listenLock sync.Mutex done chan struct{} rootPath string listenNames []string @@ -239,6 +240,8 @@ func (zksd *zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string } func (zksd *zookeeperServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { + zksd.listenLock.Lock() + defer zksd.listenLock.Unlock() zksd.listenNames = append(zksd.listenNames, listener.ServiceName) zksd.csd.ListenServiceEvent(listener.ServiceName, zksd) return nil @@ -258,8 +261,9 @@ func (zksd *zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInst } func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { - path := eventType.Path - name := strings.Split(path, "/")[2] + path := strings.TrimPrefix(eventType.Path, zksd.rootPath) + path = strings.TrimPrefix(eventType.Path, constant.PATH_SEPARATOR) + name := strings.Split(path, constant.PATH_SEPARATOR)[0] err := zksd.DispatchEventByServiceName(name) if err != nil { logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", name, err) diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go index 2f1639ad1e..a90d1e0ee1 100644 --- a/registry/zookeeper/service_discovery_test.go +++ b/registry/zookeeper/service_discovery_test.go @@ -89,6 +89,16 @@ func TestCURDZookeeperServiceDiscovery(t *testing.T) { assert.Nil(t, err) tests := sd.GetInstances(testName) assert.Equal(t, tests[0].GetId(), "127.0.0.1:2233") + err = sd.Update(®istry.DefaultServiceInstance{ + Id: "testId", + ServiceName: testName, + Host: "127.0.0.1", + Port: 2233, + Enable: true, + Healthy: true, + Metadata: nil, + }) + assert.Nil(t, err) err = sd.Unregister(®istry.DefaultServiceInstance{ Id: "testId", ServiceName: testName, diff --git a/remoting/etcdv3/listener.go b/remoting/etcdv3/listener.go index e3cb74e4f6..c65c4d127c 100644 --- a/remoting/etcdv3/listener.go +++ b/remoting/etcdv3/listener.go @@ -49,7 +49,7 @@ func NewEventListener(client *Client) *EventListener { } } -// ListenServiceNodeEvent Listen on a spec key +// listenServiceNodeEvent Listen on a spec key // this method will return true when spec key deleted, // this method will return false when deep layer connection lose func (l *EventListener) ListenServiceNodeEvent(key string, listener ...remoting.DataListener) bool { @@ -180,9 +180,9 @@ func timeSecondDuration(sec int) time.Duration { } // ListenServiceEvent is invoked by etcdv3 ConsumerRegistry::Registe/ etcdv3 ConsumerRegistry::get/etcdv3 ConsumerRegistry::getListener -// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> ListenServiceNodeEvent +// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> listenServiceNodeEvent // | -// --------> ListenServiceNodeEvent +// --------> listenServiceNodeEvent func (l *EventListener) ListenServiceEvent(key string, listener remoting.DataListener) { l.keyMapLock.Lock() diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 2301a21ae7..19df071125 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -19,6 +19,7 @@ package curator_discovery import ( "encoding/json" + "path" "strings" "sync" ) @@ -34,6 +35,11 @@ import ( "github.com/apache/dubbo-go/remoting/zookeeper" ) +type Entry struct { + sync.Mutex + instance *ServiceInstance +} + type ServiceDiscovery struct { client *zookeeper.ZookeeperClient mutex *sync.Mutex @@ -66,7 +72,14 @@ func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { } func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { - _, loaded := sd.services.LoadOrStore(instance.Id, instance) + value, loaded := sd.services.LoadOrStore(instance.Id, &Entry{}) + entry, ok := value.(*Entry) + if !ok { + return perrors.New("[ServiceDiscovery] services value not entry") + } + entry.Lock() + defer entry.Unlock() + entry.instance = instance err := sd.registerService(instance) if err != nil { return err @@ -78,7 +91,17 @@ func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { } func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { - sd.services.Store(instance.Id, instance) + value, ok := sd.services.Load(instance.Id) + if !ok { + return perrors.Errorf("[ServiceDiscovery] Service{%s} not registered", instance.Id) + } + entry, ok := value.(*Entry) + if !ok { + return perrors.New("[ServiceDiscovery] services value not entry") + } + entry.Lock() + defer entry.Unlock() + entry.instance = instance path := sd.pathForInstance(instance.Name, instance.Id) data, err := json.Marshal(instance) if err != nil { @@ -92,7 +115,11 @@ func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { } func (sd *ServiceDiscovery) updateInternalService(name, id string) { - _, ok := sd.services.Load(id) + value, ok := sd.services.Load(id) + if !ok { + return + } + entry, ok := value.(*Entry) if !ok { return } @@ -101,11 +128,23 @@ func (sd *ServiceDiscovery) updateInternalService(name, id string) { logger.Infof("[zkServiceDiscovery] UpdateInternalService{%s} error = err{%v}", id, err) return } - sd.services.Store(instance.Id, instance) + entry.Lock() + entry.instance = instance + entry.Unlock() return } func (sd *ServiceDiscovery) UnregisterService(instance *ServiceInstance) error { + value, ok := sd.services.Load(instance.Id) + if !ok { + return nil + } + entry, ok := value.(*Entry) + if !ok { + return perrors.New("[ServiceDiscovery] services value not entry") + } + entry.Lock() + entry.Unlock() sd.services.Delete(instance.Id) return sd.unregisterService(instance) } @@ -117,13 +156,17 @@ func (sd *ServiceDiscovery) unregisterService(instance *ServiceInstance) error { func (sd *ServiceDiscovery) ReRegisterService() { sd.services.Range(func(key, value interface{}) bool { - instance, ok := value.(*ServiceInstance) + entry, ok := value.(*Entry) if !ok { - + return true } + entry.Lock() + instance := entry.instance + entry.Unlock() err := sd.registerService(instance) if err != nil { logger.Errorf("[zkServiceDiscovery] registerService{%s} error = err{%v}", instance.Id, perrors.WithStack(err)) + return true } sd.ListenServiceInstanceEvent(instance.Name, instance.Id, sd) return true @@ -172,27 +215,36 @@ func (sd *ServiceDiscovery) ListenServiceEvent(name string, listener remoting.Da } func (sd *ServiceDiscovery) ListenServiceInstanceEvent(name, id string, listener remoting.DataListener) { - sd.listener.ListenServiceEvent(nil, sd.pathForInstance(name, id), listener) + sd.listener.ListenServiceNodeEvent(sd.pathForInstance(name, id), listener) } func (sd *ServiceDiscovery) DataChange(eventType remoting.Event) bool { path := eventType.Path - name, id := sd.getNameAndId(path) + name, id, err := sd.getNameAndId(path) + if err != nil { + logger.Errorf("[ServiceDiscovery] data change error = {%v}", err) + return true + } sd.updateInternalService(name, id) return true } -func (sd *ServiceDiscovery) getNameAndId(path string) (string, string) { +func (sd *ServiceDiscovery) getNameAndId(path string) (string, string, error) { + path = strings.TrimPrefix(path, sd.basePath) + path = strings.TrimPrefix(path, constant.PATH_SEPARATOR) pathSlice := strings.Split(path, constant.PATH_SEPARATOR) - name := pathSlice[2] - id := pathSlice[3] - return name, id + if len(pathSlice) < 2 { + return "", "", perrors.Errorf("[ServiceDiscovery] path{%s} dont contain name and id", path) + } + name := pathSlice[0] + id := pathSlice[1] + return name, id, nil } func (sd *ServiceDiscovery) pathForInstance(name, id string) string { - return sd.basePath + constant.PATH_SEPARATOR + name + constant.PATH_SEPARATOR + id + return path.Join(sd.basePath, name, id) } func (sd *ServiceDiscovery) pathForName(name string) string { - return sd.basePath + constant.PATH_SEPARATOR + name + return path.Join(sd.basePath, name) } diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index f9d57ba5c2..fd7f0db319 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -58,8 +58,20 @@ func (l *ZkEventListener) SetClient(client *ZookeeperClient) { l.client = client } -// ListenServiceNodeEvent ... -func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool { +// ListenServiceNodeEvent listen a path node event +func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener remoting.DataListener) { + // listen l service node + l.wg.Add(1) + go func(zkPath string, listener remoting.DataListener) { + if l.listenServiceNodeEvent(zkPath, listener) { + listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel}) + } + logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath) + }(zkPath, listener) +} + +// listenServiceNodeEvent ... +func (l *ZkEventListener) listenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool { defer l.wg.Done() var zkEvent zk.Event for { @@ -146,7 +158,7 @@ func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, li l.wg.Add(1) go func(node string, zkPath string, listener remoting.DataListener) { logger.Infof("delete zkNode{%s}", node) - if l.ListenServiceNodeEvent(node, listener) { + if l.listenServiceNodeEvent(node, listener) { logger.Infof("delete content{%s}", node) listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel}) } @@ -259,7 +271,7 @@ func (l *ZkEventListener) listenDirEvent(conf *common.URL, zkPath string, listen logger.Infof("listen dubbo service key{%s}", dubboPath) l.wg.Add(1) go func(zkPath string, listener remoting.DataListener) { - if l.ListenServiceNodeEvent(zkPath) { + if l.listenServiceNodeEvent(zkPath) { listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel}) } logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath) @@ -296,9 +308,9 @@ func timeSecondDuration(sec int) time.Duration { } // ListenServiceEvent is invoked by ZkConsumerRegistry::Register/ZkConsumerRegistry::get/ZkConsumerRegistry::getListener -// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> ListenServiceNodeEvent +// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> listenServiceNodeEvent // | -// --------> ListenServiceNodeEvent +// --------> listenServiceNodeEvent func (l *ZkEventListener) ListenServiceEvent(conf *common.URL, zkPath string, listener remoting.DataListener) { logger.Infof("listen dubbo path{%s}", zkPath) l.wg.Add(1) From f004237e5bca0ba0fa22c8addf83ab09f07de774 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 28 Jun 2020 15:31:41 +0800 Subject: [PATCH 144/209] zookeeper metadata report unit test --- .gitignore | 4 +- before_ut.bat | 5 +- before_ut.sh | 9 +- metadata/report/zookeeper/report.go | 9 +- metadata/report/zookeeper/report_test.go | 145 +++++++++++++++++++++++ remoting/zookeeper/client.go | 2 +- 6 files changed, 164 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 568e9f2454..f7622f8ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,15 +20,13 @@ classes # go mod, go test vendor/ -coverage.txt - logs/ .vscode/ -coverage.txt # unit test remoting/zookeeper/zookeeper-4unittest/ config_center/zookeeper/zookeeper-4unittest/ registry/zookeeper/zookeeper-4unittest/ +metadata/report/zookeeper/zookeeper-4unittest/ registry/consul/agent* config_center/apollo/mockDubbog.properties.json diff --git a/before_ut.bat b/before_ut.bat index 5e1c877af2..b7c70e8d13 100644 --- a/before_ut.bat +++ b/before_ut.bat @@ -34,4 +34,7 @@ md cluster\router\chain\zookeeper-4unittest\contrib\fatjar xcopy /f "%zkJar%" "cluster/router/chain/zookeeper-4unittest/contrib/fatjar/" md cluster\router\condition\zookeeper-4unittest\contrib\fatjar -xcopy /f "%zkJar%" "cluster/router/condition/zookeeper-4unittest/contrib/fatjar/" \ No newline at end of file +xcopy /f "%zkJar%" "cluster/router/condition/zookeeper-4unittest/contrib/fatjar/" + +md metadata\report\zookeeper\zookeeper-4unittest\contrib\fatjar +xcopy /f "%zkJar%" "metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar/" \ No newline at end of file diff --git a/before_ut.sh b/before_ut.sh index 7ee92e57a2..210e9e723b 100755 --- a/before_ut.sh +++ b/before_ut.sh @@ -25,13 +25,16 @@ if [ ! -f "${zkJar}" ]; then fi mkdir -p config_center/zookeeper/zookeeper-4unittest/contrib/fatjar -cp ${zkJar} config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/ +cp ${zkJar} config_center/zookeeper/zookeeper-4unittest/contrib/fatjar mkdir -p registry/zookeeper/zookeeper-4unittest/contrib/fatjar -cp ${zkJar} registry/zookeeper/zookeeper-4unittest/contrib/fatjar/ +cp ${zkJar} registry/zookeeper/zookeeper-4unittest/contrib/fatjar mkdir -p cluster/router/chain/zookeeper-4unittest/contrib/fatjar cp ${zkJar} cluster/router/chain/zookeeper-4unittest/contrib/fatjar mkdir -p cluster/router/condition/zookeeper-4unittest/contrib/fatjar -cp ${zkJar} cluster/router/condition/zookeeper-4unittest/contrib/fatjar \ No newline at end of file +cp ${zkJar} cluster/router/condition/zookeeper-4unittest/contrib/fatjar + +mkdir -p metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar +cp ${zkJar} metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar \ No newline at end of file diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go index 76948379ed..911a8d83ca 100644 --- a/metadata/report/zookeeper/report.go +++ b/metadata/report/zookeeper/report.go @@ -19,6 +19,7 @@ package zookeeper import ( "strings" + "time" ) import ( @@ -33,7 +34,7 @@ import ( func init() { mf := &zookeeperMetadataReportFactory{} - extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { + extension.SetMetadataReportFactory("zookeeper", func() factory.MetadataReportFactory { return mf }) } @@ -109,7 +110,11 @@ type zookeeperMetadataReportFactory struct { } func (mf *zookeeperMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { - client, err := zookeeper.NewZookeeperClient("zookeeperMetadataReport", strings.Split(url.Location, ","), 15) + client, err := zookeeper.NewZookeeperClient( + "zookeeperMetadataReport", + strings.Split(url.Location, ","), + 15 * time.Second, + ) if err != nil { panic(err) } diff --git a/metadata/report/zookeeper/report_test.go b/metadata/report/zookeeper/report_test.go index e386d95ef8..2de70451e0 100644 --- a/metadata/report/zookeeper/report_test.go +++ b/metadata/report/zookeeper/report_test.go @@ -16,3 +16,148 @@ */ package zookeeper + +import ( + "encoding/json" + "net/url" + "strconv" + "testing" +) + +import ( + "github.com/dubbogo/go-zookeeper/zk" + "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/metadata/identifier" + "github.com/apache/dubbo-go/metadata/report" +) + +func newProviderRegistryUrl(host string, port int) *common.URL { + url1 := common.NewURLWithOptions( + common.WithIp(host), + common.WithPort(strconv.Itoa(port)), + common.WithParams(url.Values{}), + common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)), + ) + return url1 +} + +func newBaseMetadataIdentifier(side string) *identifier.BaseMetadataIdentifier { + return &identifier.BaseMetadataIdentifier{ + ServiceInterface: "org.apache.HelloWorld", + Version: "1.0.0", + Group: "group", + Side: side, + } +} + +func newMetadataIdentifier(side string) *identifier.MetadataIdentifier { + return &identifier.MetadataIdentifier{ + Application: "application", + BaseMetadataIdentifier: *newBaseMetadataIdentifier(side), + } +} + +func newServiceMetadataIdentifier(side string) *identifier.ServiceMetadataIdentifier { + return &identifier.ServiceMetadataIdentifier{ + Revision: "1.0", + Protocol: "dubbo", + BaseMetadataIdentifier: *newBaseMetadataIdentifier(side), + } +} + +func newSubscribeMetadataIdentifier(side string) *identifier.SubscriberMetadataIdentifier { + return &identifier.SubscriberMetadataIdentifier{ + Revision: "1.0", + MetadataIdentifier: *newMetadataIdentifier(side), + } +} + +type zookeeperMetadataReportTestSuite struct { + t *testing.T + m report.MetadataReport +} + +func newZookeeperMetadataReportTestSuite(t *testing.T, m report.MetadataReport) *zookeeperMetadataReportTestSuite { + return &zookeeperMetadataReportTestSuite{t: t, m: m} +} + +func (suite *zookeeperMetadataReportTestSuite) testStoreProviderMetadata() { + providerMi := newMetadataIdentifier("provider") + providerMeta := "provider" + err := suite.m.StoreProviderMetadata(providerMi, providerMeta) + assert.NoError(suite.t, err) +} + +func (suite *zookeeperMetadataReportTestSuite) testStoreConsumerMetadata() { + consumerMi := newMetadataIdentifier("consumer") + consumerMeta := "consumer" + err := suite.m.StoreProviderMetadata(consumerMi, consumerMeta) + assert.NoError(suite.t, err) +} + +func (suite *zookeeperMetadataReportTestSuite) testSaveServiceMetadata(url common.URL) { + serviceMi := newServiceMetadataIdentifier("provider") + err := suite.m.SaveServiceMetadata(serviceMi, url) + assert.NoError(suite.t, err) +} + +func (suite *zookeeperMetadataReportTestSuite) testRemoveServiceMetadata() { + serviceMi := newServiceMetadataIdentifier("provider") + err := suite.m.RemoveServiceMetadata(serviceMi) + assert.NoError(suite.t, err) +} + +func (suite *zookeeperMetadataReportTestSuite) testGetExportedURLs() { + serviceMi := newServiceMetadataIdentifier("provider") + urls := suite.m.GetExportedURLs(serviceMi) + assert.Equal(suite.t, 1, len(urls)) +} + +func (suite *zookeeperMetadataReportTestSuite) testSaveSubscribedData(url common.URL) { + subscribeMi := newSubscribeMetadataIdentifier("provider") + urls := []string{url.String()} + bytes, _ := json.Marshal(urls) + err := suite.m.SaveSubscribedData(subscribeMi, string(bytes)) + assert.Nil(suite.t, err) +} + +func (suite *zookeeperMetadataReportTestSuite) testGetSubscribedURLs() { + subscribeMi := newSubscribeMetadataIdentifier("provider") + urls := suite.m.GetSubscribedURLs(subscribeMi) + assert.Equal(suite.t, 1, len(urls)) +} + +func (suite *zookeeperMetadataReportTestSuite) testGetServiceDefinition() { + providerMi := newMetadataIdentifier("provider") + providerMeta := suite.m.GetServiceDefinition(providerMi) + assert.Equal(suite.t, "provider", providerMeta) +} + +func test1(t *testing.T) { + testCluster, err := zk.StartTestCluster(1, nil, nil) + assert.NoError(t, err) + defer testCluster.Stop() + + url := newProviderRegistryUrl("127.0.0.1", testCluster.Servers[0].Port) + mf := extension.GetMetadataReportFactory("zookeeper") + m := mf.CreateMetadataReport(url) + + suite := newZookeeperMetadataReportTestSuite(t, m) + suite.testStoreProviderMetadata() + suite.testStoreConsumerMetadata() + suite.testSaveServiceMetadata(*url) + suite.testGetExportedURLs() + suite.testRemoveServiceMetadata() + suite.testSaveSubscribedData(*url) + suite.testGetServiceDefinition() +} + +func TestZookeeperMetadataReport(t *testing.T) { + t.Run("test1", test1) +} diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index b6c49e7056..feceeb1197 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -253,7 +253,7 @@ func (z *ZookeeperClient) HandleZkEvent(session <-chan zk.Event) { case <-z.exit: return case event = <-session: - logger.Warnf("client{%s} get a zookeeper event{type:%s, server:%s, path:%s, state:%d-%s, err:%v}", + logger.Infof("client{%s} get a zookeeper event{type:%s, server:%s, path:%s, state:%d-%s, err:%v}", z.name, event.Type, event.Server, event.Path, event.State, StateToString(event.State), event.Err) switch (int)(event.State) { case (int)(zk.StateDisconnected): From ecf7fa15689c0969384602a2506dc17fc87d4fe1 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 28 Jun 2020 15:45:40 +0800 Subject: [PATCH 145/209] go fmt --- metadata/report/zookeeper/report.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go index 911a8d83ca..7873dd7899 100644 --- a/metadata/report/zookeeper/report.go +++ b/metadata/report/zookeeper/report.go @@ -113,7 +113,7 @@ func (mf *zookeeperMetadataReportFactory) CreateMetadataReport(url *common.URL) client, err := zookeeper.NewZookeeperClient( "zookeeperMetadataReport", strings.Split(url.Location, ","), - 15 * time.Second, + 15*time.Second, ) if err != nil { panic(err) From ae1df23caaf97a0a70b718ca56bf19da94c2e3b9 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 28 Jun 2020 19:03:52 +0800 Subject: [PATCH 146/209] add comment and adjust service_discovery's critical area --- registry/zookeeper/service_discovery.go | 43 +++++++++++++++++-- .../curator_discovery/service_discovery.go | 36 +++++++++++----- .../curator_discovery/service_instance.go | 2 + 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index 1e827340dd..a126e39fb3 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -72,6 +72,7 @@ type zookeeperServiceDiscovery struct { listenNames []string } +// newZookeeperServiceDiscovery the constructor of newZookeeperServiceDiscovery func newZookeeperServiceDiscovery(name string) (registry.ServiceDiscovery, error) { instance, ok := instanceMap[name] if ok { @@ -115,66 +116,85 @@ func newZookeeperServiceDiscovery(name string) (registry.ServiceDiscovery, error return zksd, nil } +// nolint func (zksd *zookeeperServiceDiscovery) ZkClient() *zookeeper.ZookeeperClient { return zksd.client } +// nolint func (zksd *zookeeperServiceDiscovery) SetZkClient(client *zookeeper.ZookeeperClient) { zksd.client = client } +// nolint func (zksd *zookeeperServiceDiscovery) ZkClientLock() *sync.Mutex { return &zksd.cltLock } +// nolint func (zksd *zookeeperServiceDiscovery) WaitGroup() *sync.WaitGroup { return &zksd.wg } +// nolint func (zksd *zookeeperServiceDiscovery) Done() chan struct{} { return zksd.done } +// RestartCallBack when zookeeper connection reconnect this function will be invoked. +// try to re-register service, and listen services func (zksd *zookeeperServiceDiscovery) RestartCallBack() bool { - zksd.csd.ReRegisterService() + zksd.csd.ReRegisterServices() + zksd.listenLock.Lock() + defer zksd.listenLock.Unlock() for _, name := range zksd.listenNames { zksd.csd.ListenServiceEvent(name, zksd) } return true } +// nolint func (zksd *zookeeperServiceDiscovery) GetUrl() common.URL { return *zksd.url } +// nolint func (zksd *zookeeperServiceDiscovery) String() string { return fmt.Sprintf("zookeeper-service-discovery[%s]", zksd.url) } +// Close client be closed func (zksd *zookeeperServiceDiscovery) Destroy() error { zksd.client.Close() return nil } +// Register will register service in zookeeper, instance convert to curator's service instance +// which define in curator-x-discovery. func (zksd *zookeeperServiceDiscovery) Register(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.RegisterService(cris) } +// Register will update service in zookeeper, instance convert to curator's service instance +// which define in curator-x-discovery, please refer to https://github.com/apache/curator. func (zksd *zookeeperServiceDiscovery) Update(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.UpdateService(cris) } +// Unregister will unregister the instance in zookeeper func (zksd *zookeeperServiceDiscovery) Unregister(instance registry.ServiceInstance) error { cris := zksd.toCuratorInstance(instance) return zksd.csd.UnregisterService(cris) } +// GetDefaultPageSize will return the constant registry.DefaultPageSize func (zksd *zookeeperServiceDiscovery) GetDefaultPageSize() int { return registry.DefaultPageSize } +// GetServices will return the all services in zookeeper func (zksd *zookeeperServiceDiscovery) GetServices() *gxset.HashSet { services, err := zksd.csd.QueryForNames() res := gxset.NewSet() @@ -188,6 +208,7 @@ func (zksd *zookeeperServiceDiscovery) GetServices() *gxset.HashSet { return res } +// GetInstances will return the instances in a service func (zksd *zookeeperServiceDiscovery) GetInstances(serviceName string) []registry.ServiceInstance { criss, err := zksd.csd.QueryForInstances(serviceName) if err != nil { @@ -202,6 +223,7 @@ func (zksd *zookeeperServiceDiscovery) GetInstances(serviceName string) []regist return iss } +// GetInstancesByPage will return the instances func (zksd *zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager { all := zksd.GetInstances(serviceName) res := make([]interface{}, 0, pageSize) @@ -212,6 +234,10 @@ func (zksd *zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, of return gxpage.New(offset, pageSize, res, len(all)) } +// GetHealthyInstancesByPage will return the instance +// In zookeeper, all service instance's is healthy. +// However, the healthy parameter in this method maybe false. So we can not use that API. +// Thus, we must query all instances and then do filter func (zksd *zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { all := zksd.GetInstances(serviceName) res := make([]interface{}, 0, pageSize) @@ -231,6 +257,7 @@ func (zksd *zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName str return gxpage.New(offset, pageSize, res, len(all)) } +// GetRequestInstances will return the instances func (zksd *zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { res := make(map[string]gxpage.Pager, len(serviceNames)) for _, name := range serviceNames { @@ -239,6 +266,7 @@ func (zksd *zookeeperServiceDiscovery) GetRequestInstances(serviceNames []string return res } +// AddListener ListenServiceEvent will add a data listener in service func (zksd *zookeeperServiceDiscovery) AddListener(listener *registry.ServiceInstancesChangedListener) error { zksd.listenLock.Lock() defer zksd.listenLock.Unlock() @@ -251,26 +279,32 @@ func (zksd *zookeeperServiceDiscovery) DispatchEventByServiceName(serviceName st return zksd.DispatchEventForInstances(serviceName, zksd.GetInstances(serviceName)) } +// DispatchEventForInstances dispatch ServiceInstancesChangedEvent func (zksd *zookeeperServiceDiscovery) DispatchEventForInstances(serviceName string, instances []registry.ServiceInstance) error { return zksd.DispatchEvent(registry.NewServiceInstancesChangedEvent(serviceName, instances)) } +// nolint func (zksd *zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInstancesChangedEvent) error { extension.GetGlobalDispatcher().Dispatch(event) return nil } +// DataChange implement DataListener's DataChange function +// to resolve event to do DispatchEventByServiceName func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { path := strings.TrimPrefix(eventType.Path, zksd.rootPath) path = strings.TrimPrefix(eventType.Path, constant.PATH_SEPARATOR) - name := strings.Split(path, constant.PATH_SEPARATOR)[0] - err := zksd.DispatchEventByServiceName(name) + // get service name in zk path + serviceName := strings.Split(path, constant.PATH_SEPARATOR)[0] + err := zksd.DispatchEventByServiceName(serviceName) if err != nil { - logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", name, err) + logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", serviceName, err) } return true } +// toCuratorInstance convert to curator's service instance func (zksd *zookeeperServiceDiscovery) toCuratorInstance(instance registry.ServiceInstance) *curator_discovery.ServiceInstance { id := instance.GetHost() + ":" + strconv.Itoa(instance.GetPort()) pl := make(map[string]interface{}) @@ -288,6 +322,7 @@ func (zksd *zookeeperServiceDiscovery) toCuratorInstance(instance registry.Servi return cuis } +// toZookeeperInstance convert to registry's service instance func (zksd *zookeeperServiceDiscovery) toZookeeperInstance(cris *curator_discovery.ServiceInstance) registry.ServiceInstance { pl, ok := cris.Payload.(map[string]interface{}) if !ok { diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 19df071125..3ece95b917 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -35,11 +35,14 @@ import ( "github.com/apache/dubbo-go/remoting/zookeeper" ) +// Entry contain a service instance type Entry struct { sync.Mutex instance *ServiceInstance } +// ServiceInstance which define in curator-x-discovery, please refer to +// https://github.com/apache/curator/blob/master/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceDiscovery.java type ServiceDiscovery struct { client *zookeeper.ZookeeperClient mutex *sync.Mutex @@ -48,6 +51,7 @@ type ServiceDiscovery struct { listener *zookeeper.ZkEventListener } +// NewServiceDiscovery the constructor of service discovery func NewServiceDiscovery(client *zookeeper.ZookeeperClient, basePath string) *ServiceDiscovery { return &ServiceDiscovery{ client: client, @@ -58,6 +62,7 @@ func NewServiceDiscovery(client *zookeeper.ZookeeperClient, basePath string) *Se } } +// registerService register service to zookeeper func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { path := sd.pathForInstance(instance.Name, instance.Id) data, err := json.Marshal(instance) @@ -71,6 +76,7 @@ func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { return nil } +// RegisterService register service to zookeeper, and ensure cache is consistent with zookeeper func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { value, loaded := sd.services.LoadOrStore(instance.Id, &Entry{}) entry, ok := value.(*Entry) @@ -90,6 +96,7 @@ func (sd *ServiceDiscovery) RegisterService(instance *ServiceInstance) error { return nil } +// UpdateService update service in zookeeper, and ensure cache is consistent with zookeeper func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { value, ok := sd.services.Load(instance.Id) if !ok { @@ -114,6 +121,7 @@ func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { return nil } +// updateInternalService update service in cache func (sd *ServiceDiscovery) updateInternalService(name, id string) { value, ok := sd.services.Load(id) if !ok { @@ -123,46 +131,43 @@ func (sd *ServiceDiscovery) updateInternalService(name, id string) { if !ok { return } + entry.Lock() + defer entry.Unlock() instance, err := sd.QueryForInstance(name, id) if err != nil { logger.Infof("[zkServiceDiscovery] UpdateInternalService{%s} error = err{%v}", id, err) return } - entry.Lock() entry.instance = instance - entry.Unlock() return } +// UnregisterService un-register service in zookeeper and delete service in cache func (sd *ServiceDiscovery) UnregisterService(instance *ServiceInstance) error { - value, ok := sd.services.Load(instance.Id) + _, ok := sd.services.Load(instance.Id) if !ok { return nil } - entry, ok := value.(*Entry) - if !ok { - return perrors.New("[ServiceDiscovery] services value not entry") - } - entry.Lock() - entry.Unlock() sd.services.Delete(instance.Id) return sd.unregisterService(instance) } +// unregisterService un-register service in zookeeper func (sd *ServiceDiscovery) unregisterService(instance *ServiceInstance) error { path := sd.pathForInstance(instance.Name, instance.Id) return sd.client.Delete(path) } -func (sd *ServiceDiscovery) ReRegisterService() { +// ReRegisterServices re-register all cache services to zookeeper +func (sd *ServiceDiscovery) ReRegisterServices() { sd.services.Range(func(key, value interface{}) bool { entry, ok := value.(*Entry) if !ok { return true } entry.Lock() + defer entry.Unlock() instance := entry.instance - entry.Unlock() err := sd.registerService(instance) if err != nil { logger.Errorf("[zkServiceDiscovery] registerService{%s} error = err{%v}", instance.Id, perrors.WithStack(err)) @@ -173,6 +178,7 @@ func (sd *ServiceDiscovery) ReRegisterService() { }) } +// QueryForInstances query instances in zookeeper by name func (sd *ServiceDiscovery) QueryForInstances(name string) ([]*ServiceInstance, error) { ids, err := sd.client.GetChildren(sd.pathForName(name)) if err != nil { @@ -192,6 +198,7 @@ func (sd *ServiceDiscovery) QueryForInstances(name string) ([]*ServiceInstance, return instances, nil } +// QueryForInstance query instances in zookeeper by name and id func (sd *ServiceDiscovery) QueryForInstance(name string, id string) (*ServiceInstance, error) { path := sd.pathForInstance(name, id) data, _, err := sd.client.GetContent(path) @@ -206,18 +213,22 @@ func (sd *ServiceDiscovery) QueryForInstance(name string, id string) (*ServiceIn return instance, nil } +// QueryForInstance query all service name in zookeeper func (sd *ServiceDiscovery) QueryForNames() ([]string, error) { return sd.client.GetChildren(sd.basePath) } +// ListenServiceEvent add a listener in a service func (sd *ServiceDiscovery) ListenServiceEvent(name string, listener remoting.DataListener) { sd.listener.ListenServiceEvent(nil, sd.pathForName(name), listener) } +// ListenServiceEvent add a listener in a instance func (sd *ServiceDiscovery) ListenServiceInstanceEvent(name, id string, listener remoting.DataListener) { sd.listener.ListenServiceNodeEvent(sd.pathForInstance(name, id), listener) } +// DataChange implement DataListener's DataChange function func (sd *ServiceDiscovery) DataChange(eventType remoting.Event) bool { path := eventType.Path name, id, err := sd.getNameAndId(path) @@ -229,6 +240,7 @@ func (sd *ServiceDiscovery) DataChange(eventType remoting.Event) bool { return true } +// getNameAndId get service name and instance id by path func (sd *ServiceDiscovery) getNameAndId(path string) (string, string, error) { path = strings.TrimPrefix(path, sd.basePath) path = strings.TrimPrefix(path, constant.PATH_SEPARATOR) @@ -241,10 +253,12 @@ func (sd *ServiceDiscovery) getNameAndId(path string) (string, string, error) { return name, id, nil } +// nolint func (sd *ServiceDiscovery) pathForInstance(name, id string) string { return path.Join(sd.basePath, name, id) } +// nolint func (sd *ServiceDiscovery) pathForName(name string) string { return path.Join(sd.basePath, name) } diff --git a/remoting/zookeeper/curator_discovery/service_instance.go b/remoting/zookeeper/curator_discovery/service_instance.go index 1ba7a16f9a..f8d2bc723e 100644 --- a/remoting/zookeeper/curator_discovery/service_instance.go +++ b/remoting/zookeeper/curator_discovery/service_instance.go @@ -17,6 +17,8 @@ package curator_discovery +// ServiceInstance which define in curator-x-discovery, please refer to +// https://github.com/apache/curator/blob/master/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java type ServiceInstance struct { Name string Id string From 3c3552cc7c35053c933f30e0d5913e14a73650cd Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 28 Jun 2020 19:09:40 +0800 Subject: [PATCH 147/209] modify comment --- remoting/zookeeper/curator_discovery/service_discovery.go | 1 + 1 file changed, 1 insertion(+) diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 3ece95b917..fc37d5c1d6 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -43,6 +43,7 @@ type Entry struct { // ServiceInstance which define in curator-x-discovery, please refer to // https://github.com/apache/curator/blob/master/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceDiscovery.java +// It's not exactly the same as curator-x-discovery's service discovery type ServiceDiscovery struct { client *zookeeper.ZookeeperClient mutex *sync.Mutex From 44dbdfe1aebb46efa995990e397db33396147fda Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 28 Jun 2020 19:28:15 +0800 Subject: [PATCH 148/209] global var for empty slice --- metadata/report/consul/report.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/metadata/report/consul/report.go b/metadata/report/consul/report.go index ca57f40363..690534220b 100644 --- a/metadata/report/consul/report.go +++ b/metadata/report/consul/report.go @@ -29,6 +29,10 @@ import ( "github.com/apache/dubbo-go/metadata/report/factory" ) +var ( + emptyStrSlice = make([]string, 0) +) + func init() { mf := &consulMetadataReportFactory{} extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { @@ -79,7 +83,7 @@ func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.Se } if kv == nil { - return []string{} + return emptyStrSlice } return []string{string(kv.Value)} } @@ -100,7 +104,7 @@ func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *i } if kv == nil { - return []string{} + return emptyStrSlice } return []string{string(kv.Value)} } From dd6e4bdcbac0528bad4c21be20024d8a8b2a9f1a Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 28 Jun 2020 19:56:56 +0800 Subject: [PATCH 149/209] add unit tests --- registry/zookeeper/service_discovery.go | 15 +++- registry/zookeeper/service_discovery_test.go | 91 +++++++++++++++++++- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index a126e39fb3..aff92049aa 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -294,7 +294,7 @@ func (zksd *zookeeperServiceDiscovery) DispatchEvent(event *registry.ServiceInst // to resolve event to do DispatchEventByServiceName func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool { path := strings.TrimPrefix(eventType.Path, zksd.rootPath) - path = strings.TrimPrefix(eventType.Path, constant.PATH_SEPARATOR) + path = strings.TrimPrefix(path, constant.PATH_SEPARATOR) // get service name in zk path serviceName := strings.Split(path, constant.PATH_SEPARATOR)[0] err := zksd.DispatchEventByServiceName(serviceName) @@ -326,9 +326,18 @@ func (zksd *zookeeperServiceDiscovery) toCuratorInstance(instance registry.Servi func (zksd *zookeeperServiceDiscovery) toZookeeperInstance(cris *curator_discovery.ServiceInstance) registry.ServiceInstance { pl, ok := cris.Payload.(map[string]interface{}) if !ok { - logger.Errorf("[zkServiceDiscovery] toZookeeperInstance{%s} payload is not map", cris.Id) + logger.Errorf("[zkServiceDiscovery] toZookeeperInstance{%s} payload is not map[string]interface{}", cris.Id) + return nil + } + mdi, ok := pl["metadata"].(map[string]interface{}) + if !ok { + logger.Errorf("[zkServiceDiscovery] toZookeeperInstance{%s} metadata is not map[string]interface{}", cris.Id) + return nil + } + md := make(map[string]string, len(mdi)) + for k, v := range mdi { + md[k] = fmt.Sprint(v) } - md, ok := pl["metadata"].(map[string]string) return ®istry.DefaultServiceInstance{ Id: cris.Id, ServiceName: cris.Name, diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go index a90d1e0ee1..6649407800 100644 --- a/registry/zookeeper/service_discovery_test.go +++ b/registry/zookeeper/service_discovery_test.go @@ -18,7 +18,10 @@ package zookeeper import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" "strconv" + "sync" "testing" ) @@ -75,6 +78,7 @@ func TestCURDZookeeperServiceDiscovery(t *testing.T) { defer ts.Stop() sd, err := newZookeeperServiceDiscovery(testName) assert.Nil(t, err) + defer sd.Destroy() md := make(map[string]string) md["t1"] = "test1" err = sd.Register(®istry.DefaultServiceInstance{ @@ -87,8 +91,15 @@ func TestCURDZookeeperServiceDiscovery(t *testing.T) { Metadata: md, }) assert.Nil(t, err) - tests := sd.GetInstances(testName) - assert.Equal(t, tests[0].GetId(), "127.0.0.1:2233") + + testsPager := sd.GetHealthyInstancesByPage(testName, 0, 1, true) + assert.Equal(t, 1, testsPager.GetDataSize()) + assert.Equal(t, 1, testsPager.GetTotalPages()) + test := testsPager.GetData()[0].(registry.ServiceInstance) + assert.Equal(t, "127.0.0.1:2233", test.GetId()) + assert.Equal(t, "test1", test.GetMetadata()["t1"]) + + md["t1"] = "test12" err = sd.Update(®istry.DefaultServiceInstance{ Id: "testId", ServiceName: testName, @@ -96,9 +107,25 @@ func TestCURDZookeeperServiceDiscovery(t *testing.T) { Port: 2233, Enable: true, Healthy: true, - Metadata: nil, + Metadata: md, }) assert.Nil(t, err) + + testsPager = sd.GetInstancesByPage(testName, 0, 1) + assert.Equal(t, 1, testsPager.GetDataSize()) + test = testsPager.GetData()[0].(registry.ServiceInstance) + assert.Equal(t, "test12", test.GetMetadata()["t1"]) + + testsMap := sd.GetRequestInstances([]string{testName}, 0, 1) + assert.Equal(t, 1, len(testsMap)) + assert.Equal(t, 1, testsMap[testName].GetDataSize()) + test = testsMap[testName].GetData()[0].(registry.ServiceInstance) + assert.Equal(t, "test12", test.GetMetadata()["t1"]) + + names := sd.GetServices() + assert.Equal(t, 1, names.Size()) + assert.Equal(t, testName, names.Values()[0]) + err = sd.Unregister(®istry.DefaultServiceInstance{ Id: "testId", ServiceName: testName, @@ -110,3 +137,61 @@ func TestCURDZookeeperServiceDiscovery(t *testing.T) { }) assert.Nil(t, err) } + +func TestAddListenerZookeeperServiceDiscovery(t *testing.T) { + ts := prepareData(t) + defer ts.Stop() + sd, err := newZookeeperServiceDiscovery(testName) + assert.Nil(t, err) + defer sd.Destroy() + + err = sd.Register(®istry.DefaultServiceInstance{ + Id: "testId", + ServiceName: testName, + Host: "127.0.0.1", + Port: 2233, + Enable: true, + Healthy: true, + Metadata: nil, + }) + assert.Nil(t, err) + + assert.Nil(t, err) + wg := &sync.WaitGroup{} + wg.Add(1) + tn := &testNotify{ + wg: wg, + t: t, + } + sicl := ®istry.ServiceInstancesChangedListener{ + ServiceName: testName, + ChangedNotify: tn, + } + extension.SetAndInitGlobalDispatcher("direct") + extension.GetGlobalDispatcher().AddEventListener(sicl) + err = sd.AddListener(sicl) + assert.Nil(t, err) + + err = sd.Update(®istry.DefaultServiceInstance{ + Id: "testId", + ServiceName: testName, + Host: "127.0.0.1", + Port: 2233, + Enable: true, + Healthy: true, + Metadata: nil, + }) + tn.wg.Wait() +} + +type testNotify struct { + wg *sync.WaitGroup + t *testing.T +} + +func (tn *testNotify) Notify(e observer.Event) { + ice := e.(*registry.ServiceInstancesChangedEvent) + assert.Equal(tn.t, 1, len(ice.Instances)) + assert.Equal(tn.t, "127.0.0.1:2233", ice.Instances[0].GetId()) + tn.wg.Done() +} From f440a3141f0472e47f3abb84c88ed6c12b9b9910 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 28 Jun 2020 20:10:40 +0800 Subject: [PATCH 150/209] fix --- metadata/report/consul/report_test.go | 1 + metadata/report/zookeeper/report.go | 12 ++++++++++++ metadata/report/zookeeper/report_test.go | 1 + 3 files changed, 14 insertions(+) diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go index 5d7a9a3517..7996421f72 100644 --- a/metadata/report/consul/report_test.go +++ b/metadata/report/consul/report_test.go @@ -154,6 +154,7 @@ func test1(t *testing.T) { suite.testGetExportedURLs() suite.testRemoveServiceMetadata() suite.testSaveSubscribedData(*url) + suite.testGetSubscribedURLs() suite.testGetServiceDefinition() } diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go index 7873dd7899..955393f79c 100644 --- a/metadata/report/zookeeper/report.go +++ b/metadata/report/zookeeper/report.go @@ -32,6 +32,10 @@ import ( "github.com/apache/dubbo-go/remoting/zookeeper" ) +var ( + emptyStrSlice = make([]string, 0) +) + func init() { mf := &zookeeperMetadataReportFactory{} extension.SetMetadataReportFactory("zookeeper", func() factory.MetadataReportFactory { @@ -77,6 +81,10 @@ func (m *zookeeperMetadataReport) GetExportedURLs(metadataIdentifier *identifier if err != nil { panic(err) } + + if len(v) == 0 { + return emptyStrSlice + } return []string{string(v)} } @@ -93,6 +101,10 @@ func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier if err != nil { panic(err) } + + if len(v) == 0 { + return emptyStrSlice + } return []string{string(v)} } diff --git a/metadata/report/zookeeper/report_test.go b/metadata/report/zookeeper/report_test.go index 2de70451e0..c83022bd34 100644 --- a/metadata/report/zookeeper/report_test.go +++ b/metadata/report/zookeeper/report_test.go @@ -155,6 +155,7 @@ func test1(t *testing.T) { suite.testGetExportedURLs() suite.testRemoveServiceMetadata() suite.testSaveSubscribedData(*url) + suite.testGetSubscribedURLs() suite.testGetServiceDefinition() } From e030e25c50a0a64a9770d86a50a176fb08402e53 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Mon, 29 Jun 2020 12:30:23 +0800 Subject: [PATCH 151/209] remove panic --- metadata/report/consul/report.go | 27 +++++++++---------- metadata/report/consul/report_test.go | 9 ++++--- metadata/report/delegate/delegate_report.go | 6 ++--- metadata/report/nacos/report.go | 29 ++++++++++++--------- metadata/report/nacos/report_test.go | 6 +++-- metadata/report/report.go | 6 ++--- metadata/report/zookeeper/report.go | 25 +++++++++--------- metadata/report/zookeeper/report_test.go | 9 ++++--- 8 files changed, 64 insertions(+), 53 deletions(-) diff --git a/metadata/report/consul/report.go b/metadata/report/consul/report.go index 690534220b..2d3d00d608 100644 --- a/metadata/report/consul/report.go +++ b/metadata/report/consul/report.go @@ -34,9 +34,8 @@ var ( ) func init() { - mf := &consulMetadataReportFactory{} extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { - return mf + return &consulMetadataReportFactory{} }) } @@ -75,17 +74,17 @@ func (m *consulMetadataReport) RemoveServiceMetadata(metadataIdentifier *identif } // GetExportedURLs gets the urls. -func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { +func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) ([]string, error) { k := metadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) if err != nil { - panic(err) + return emptyStrSlice, err } if kv == nil { - return emptyStrSlice + return emptyStrSlice, nil } - return []string{string(kv.Value)} + return []string{string(kv.Value)}, nil } // SaveSubscribedData saves the urls. @@ -96,31 +95,31 @@ func (m *consulMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier * } // GetSubscribedURLs gets the urls. -func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { +func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { k := subscriberMetadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) if err != nil { - panic(err) + return emptyStrSlice, err } if kv == nil { - return emptyStrSlice + return emptyStrSlice, nil } - return []string{string(kv.Value)} + return []string{string(kv.Value)}, nil } // GetServiceDefinition gets the service definition. -func (m *consulMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { +func (m *consulMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) (string, error) { k := metadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) if err != nil { - panic(err) + return "", err } if kv == nil { - return "" + return "", nil } - return string(kv.Value) + return string(kv.Value), nil } type consulMetadataReportFactory struct { diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go index 7996421f72..b982d71765 100644 --- a/metadata/report/consul/report_test.go +++ b/metadata/report/consul/report_test.go @@ -115,8 +115,9 @@ func (suite *consulMetadataReportTestSuite) testRemoveServiceMetadata() { func (suite *consulMetadataReportTestSuite) testGetExportedURLs() { serviceMi := newServiceMetadataIdentifier("provider") - urls := suite.m.GetExportedURLs(serviceMi) + urls, err := suite.m.GetExportedURLs(serviceMi) assert.Equal(suite.t, 1, len(urls)) + assert.NoError(suite.t, err) } func (suite *consulMetadataReportTestSuite) testSaveSubscribedData(url common.URL) { @@ -129,14 +130,16 @@ func (suite *consulMetadataReportTestSuite) testSaveSubscribedData(url common.UR func (suite *consulMetadataReportTestSuite) testGetSubscribedURLs() { subscribeMi := newSubscribeMetadataIdentifier("provider") - urls := suite.m.GetSubscribedURLs(subscribeMi) + urls, err := suite.m.GetSubscribedURLs(subscribeMi) assert.Equal(suite.t, 1, len(urls)) + assert.NoError(suite.t, err) } func (suite *consulMetadataReportTestSuite) testGetServiceDefinition() { providerMi := newMetadataIdentifier("provider") - providerMeta := suite.m.GetServiceDefinition(providerMi) + providerMeta, err := suite.m.GetServiceDefinition(providerMi) assert.Equal(suite.t, "provider", providerMeta) + assert.NoError(suite.t, err) } func test1(t *testing.T) { diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 08092a7ddc..64103b259a 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -235,7 +235,7 @@ func (mr *MetadataReport) RemoveServiceMetadata(identifier *identifier.ServiceMe } // GetExportedURLs will delegate to call remote metadata's sdk to get exported urls -func (mr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadataIdentifier) []string { +func (mr *MetadataReport) GetExportedURLs(identifier *identifier.ServiceMetadataIdentifier) ([]string, error) { report := instance.GetMetadataReportInstance() return report.GetExportedURLs(identifier) } @@ -260,13 +260,13 @@ func (mr *MetadataReport) SaveSubscribedData(identifier *identifier.SubscriberMe } // GetSubscribedURLs will delegate to call remote metadata's sdk to get subscribed urls -func (MetadataReport) GetSubscribedURLs(identifier *identifier.SubscriberMetadataIdentifier) []string { +func (MetadataReport) GetSubscribedURLs(identifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { report := instance.GetMetadataReportInstance() return report.GetSubscribedURLs(identifier) } // GetServiceDefinition will delegate to call remote metadata's sdk to get service definitions -func (MetadataReport) GetServiceDefinition(identifier *identifier.MetadataIdentifier) string { +func (MetadataReport) GetServiceDefinition(identifier *identifier.MetadataIdentifier) (string, error) { report := instance.GetMetadataReportInstance() return report.GetServiceDefinition(identifier) } diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 7db4c85d9a..988ea12838 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -38,9 +38,8 @@ import ( ) func init() { - mf := &nacosMetadataReportFactory{} extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory { - return mf + return &nacosMetadataReportFactory{} }) } @@ -86,7 +85,7 @@ func (n *nacosMetadataReport) RemoveServiceMetadata(metadataIdentifier *identifi } // GetExportedURLs gets the urls. -func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { +func (n *nacosMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) ([]string, error) { return n.getConfigAsArray(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), Group: metadataIdentifier.Group, @@ -103,7 +102,7 @@ func (n *nacosMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier *i } // GetSubscribedURLs gets the urls. -func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { +func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { return n.getConfigAsArray(vo.ConfigParam{ DataId: subscriberMetadataIdentifier.GetIdentifierKey(), Group: subscriberMetadataIdentifier.Group, @@ -111,7 +110,7 @@ func (n *nacosMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *id } // GetServiceDefinition gets the service definition. -func (n *nacosMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { +func (n *nacosMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) (string, error) { return n.getConfig(vo.ConfigParam{ DataId: metadataIdentifier.GetIdentifierKey(), Group: metadataIdentifier.Group, @@ -145,28 +144,34 @@ func (n *nacosMetadataReport) deleteMetadata(param vo.ConfigParam) error { // getConfigAsArray will read the config and then convert it as an one-element array // error or config not found, an empty list will be returned. -func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) []string { - cfg := n.getConfig(param) +func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) ([]string, error) { res := make([]string, 0, 1) + + cfg, err := n.getConfig(param) + if err != nil { + return res, err + } if len(cfg) == 0 { - return res + return res, nil } + decodeCfg, err := url.QueryUnescape(cfg) if err != nil { logger.Errorf("The config is invalid: %s", cfg) - return res + return res, err } res = append(res, decodeCfg) - return res + return res, nil } // getConfig will read the config -func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) string { +func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) (string, error) { cfg, err := n.client.GetConfig(param) if err != nil { logger.Errorf("Finding the configuration failed: %v", param) + return "", err } - return cfg + return cfg, nil } type nacosMetadataReportFactory struct { diff --git a/metadata/report/nacos/report_test.go b/metadata/report/nacos/report_test.go index 971c7bfe8f..be01eb22f7 100644 --- a/metadata/report/nacos/report_test.go +++ b/metadata/report/nacos/report_test.go @@ -54,8 +54,9 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { err = rpt.SaveServiceMetadata(serviceMi, serviceUrl) assert.Nil(t, err) - exportedUrls := rpt.GetExportedURLs(serviceMi) + exportedUrls, err := rpt.GetExportedURLs(serviceMi) assert.Equal(t, 1, len(exportedUrls)) + assert.Nil(t, err) subMi := newSubscribeMetadataIdentifier() urls := []string{serviceUrl.String()} @@ -63,8 +64,9 @@ func TestNacosMetadataReport_CRUD(t *testing.T) { err = rpt.SaveSubscribedData(subMi, string(bytes)) assert.Nil(t, err) - subscribeUrl := rpt.GetSubscribedURLs(subMi) + subscribeUrl, err := rpt.GetSubscribedURLs(subMi) assert.Equal(t, 1, len(subscribeUrl)) + assert.Nil(t, err) err = rpt.RemoveServiceMetadata(serviceMi) assert.Nil(t, err) diff --git a/metadata/report/report.go b/metadata/report/report.go index d5930dc1fd..3ef8f5925e 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -28,8 +28,8 @@ type MetadataReport interface { StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error - GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string + GetExportedURLs(*identifier.ServiceMetadataIdentifier) ([]string, error) SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, string) error - GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string - GetServiceDefinition(*identifier.MetadataIdentifier) string + GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) ([]string, error) + GetServiceDefinition(*identifier.MetadataIdentifier) (string, error) } diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go index 955393f79c..58c4791c2b 100644 --- a/metadata/report/zookeeper/report.go +++ b/metadata/report/zookeeper/report.go @@ -37,9 +37,8 @@ var ( ) func init() { - mf := &zookeeperMetadataReportFactory{} extension.SetMetadataReportFactory("zookeeper", func() factory.MetadataReportFactory { - return mf + return &zookeeperMetadataReportFactory{} }) } @@ -75,17 +74,17 @@ func (m *zookeeperMetadataReport) RemoveServiceMetadata(metadataIdentifier *iden } // GetExportedURLs gets the urls. -func (m *zookeeperMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) []string { +func (m *zookeeperMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) ([]string, error) { k := m.rootDir + metadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) if err != nil { - panic(err) + return emptyStrSlice, err } if len(v) == 0 { - return emptyStrSlice + return emptyStrSlice, nil } - return []string{string(v)} + return []string{string(v)}, nil } // SaveSubscribedData saves the urls. @@ -95,27 +94,27 @@ func (m *zookeeperMetadataReport) SaveSubscribedData(subscriberMetadataIdentifie } // GetSubscribedURLs gets the urls. -func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) []string { +func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { k := m.rootDir + subscriberMetadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) if err != nil { - panic(err) + return emptyStrSlice, err } if len(v) == 0 { - return emptyStrSlice + return emptyStrSlice, nil } - return []string{string(v)} + return []string{string(v)}, nil } // GetServiceDefinition gets the service definition. -func (m *zookeeperMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) string { +func (m *zookeeperMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) (string, error) { k := m.rootDir + metadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) if err != nil { - panic(err) + return "", err } - return string(v) + return string(v), nil } type zookeeperMetadataReportFactory struct { diff --git a/metadata/report/zookeeper/report_test.go b/metadata/report/zookeeper/report_test.go index c83022bd34..5d25e3c496 100644 --- a/metadata/report/zookeeper/report_test.go +++ b/metadata/report/zookeeper/report_test.go @@ -115,8 +115,9 @@ func (suite *zookeeperMetadataReportTestSuite) testRemoveServiceMetadata() { func (suite *zookeeperMetadataReportTestSuite) testGetExportedURLs() { serviceMi := newServiceMetadataIdentifier("provider") - urls := suite.m.GetExportedURLs(serviceMi) + urls, err := suite.m.GetExportedURLs(serviceMi) assert.Equal(suite.t, 1, len(urls)) + assert.NoError(suite.t, err) } func (suite *zookeeperMetadataReportTestSuite) testSaveSubscribedData(url common.URL) { @@ -129,14 +130,16 @@ func (suite *zookeeperMetadataReportTestSuite) testSaveSubscribedData(url common func (suite *zookeeperMetadataReportTestSuite) testGetSubscribedURLs() { subscribeMi := newSubscribeMetadataIdentifier("provider") - urls := suite.m.GetSubscribedURLs(subscribeMi) + urls, err := suite.m.GetSubscribedURLs(subscribeMi) assert.Equal(suite.t, 1, len(urls)) + assert.NoError(suite.t, err) } func (suite *zookeeperMetadataReportTestSuite) testGetServiceDefinition() { providerMi := newMetadataIdentifier("provider") - providerMeta := suite.m.GetServiceDefinition(providerMi) + providerMeta, err := suite.m.GetServiceDefinition(providerMi) assert.Equal(suite.t, "provider", providerMeta) + assert.NoError(suite.t, err) } func test1(t *testing.T) { From a601a33732672421c8b5e652063f3682221fd35e Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Mon, 29 Jun 2020 13:19:29 +0800 Subject: [PATCH 152/209] fix bug --- metadata/service/remote/service_test.go | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go index 12ef472ecb..3b4a12045c 100644 --- a/metadata/service/remote/service_test.go +++ b/metadata/service/remote/service_test.go @@ -73,8 +73,8 @@ func (metadataReport) RemoveServiceMetadata(*identifier.ServiceMetadataIdentifie return nil } -func (metadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) []string { - return nil +func (metadataReport) GetExportedURLs(*identifier.ServiceMetadataIdentifier) ([]string, error) { + return nil, nil } func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataIdentifier, urls string) error { @@ -83,12 +83,12 @@ func (mr *metadataReport) SaveSubscribedData(id *identifier.SubscriberMetadataId return nil } -func (metadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) []string { - return nil +func (metadataReport) GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) ([]string, error) { + return nil, nil } -func (metadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) string { - return "" +func (metadataReport) GetServiceDefinition(*identifier.MetadataIdentifier) (string, error) { + return "", nil } func TestMetadataService(t *testing.T) { @@ -111,6 +111,7 @@ func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { version := "0.0.1" protocol := "dubbo" beanName := "UserProvider" + userProvider := &definition.UserProvider{} u, err := common.NewURL(fmt.Sprintf( "%v://127.0.0.1:20000/com.ikurento.user.UserProvider1?anyhost=true&"+ @@ -119,13 +120,17 @@ func mockInmemoryProc(t *testing.T) *inmemory.MetadataService { "owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245&group=%v&version=%v&bean.name=%v", protocol, serviceName, group, version, beanName)) assert.NoError(t, err) - mts.ExportURL(u) - mts.SubscribeURL(u) + _, err = mts.ExportURL(u) + assert.NoError(t, err) + _, err = mts.SubscribeURL(u) + assert.NoError(t, err) + + _, err = common.ServiceMap.Register(serviceName, protocol, userProvider) + assert.NoError(t, err) + err = mts.PublishServiceDefinition(u) + assert.NoError(t, err) - userProvider := &definition.UserProvider{} - common.ServiceMap.Register(serviceName, protocol, userProvider) - mts.PublishServiceDefinition(u) expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," + "\"Methods\":[{\"Name\":\"GetUser\",\"ParameterTypes\":[\"slice\"],\"ReturnType\":\"ptr\"," + "\"Parameters\":null}],\"Types\":null}" From f00d104bfb91ffda9245ac7697cd793f6508d087 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Mon, 29 Jun 2020 13:32:16 +0800 Subject: [PATCH 153/209] rename consul agent for test --- metadata/report/factory/report_factory.go | 4 ---- remoting/consul/{agent.go => test_agent.go} | 0 remoting/consul/{agent_test.go => test_agent_test.go} | 0 3 files changed, 4 deletions(-) rename remoting/consul/{agent.go => test_agent.go} (100%) rename remoting/consul/{agent_test.go => test_agent_test.go} (100%) diff --git a/metadata/report/factory/report_factory.go b/metadata/report/factory/report_factory.go index 8769ebdd2f..9f00007cef 100644 --- a/metadata/report/factory/report_factory.go +++ b/metadata/report/factory/report_factory.go @@ -22,10 +22,6 @@ import ( "github.com/apache/dubbo-go/metadata/report" ) -var ( - MetadataReportInstance report.MetadataReport -) - // MetadataReportFactory interface will create metadata report type MetadataReportFactory interface { CreateMetadataReport(*common.URL) report.MetadataReport diff --git a/remoting/consul/agent.go b/remoting/consul/test_agent.go similarity index 100% rename from remoting/consul/agent.go rename to remoting/consul/test_agent.go diff --git a/remoting/consul/agent_test.go b/remoting/consul/test_agent_test.go similarity index 100% rename from remoting/consul/agent_test.go rename to remoting/consul/test_agent_test.go From a23c6d23bcd1520712d71209117054ad20b7a0dc Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Wed, 1 Jul 2020 21:02:39 +0800 Subject: [PATCH 154/209] fix --- metadata/report/consul/report.go | 22 ++++++---------------- metadata/report/nacos/report.go | 10 +++++----- metadata/report/zookeeper/report.go | 21 ++++++--------------- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/metadata/report/consul/report.go b/metadata/report/consul/report.go index 2d3d00d608..eb2bdc25ec 100644 --- a/metadata/report/consul/report.go +++ b/metadata/report/consul/report.go @@ -34,8 +34,9 @@ var ( ) func init() { + mf := &consulMetadataReportFactory{} extension.SetMetadataReportFactory("consul", func() factory.MetadataReportFactory { - return &consulMetadataReportFactory{} + return mf }) } @@ -77,13 +78,9 @@ func (m *consulMetadataReport) RemoveServiceMetadata(metadataIdentifier *identif func (m *consulMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) ([]string, error) { k := metadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) - if err != nil { + if err != nil || kv == nil { return emptyStrSlice, err } - - if kv == nil { - return emptyStrSlice, nil - } return []string{string(kv.Value)}, nil } @@ -98,13 +95,9 @@ func (m *consulMetadataReport) SaveSubscribedData(subscriberMetadataIdentifier * func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { k := subscriberMetadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) - if err != nil { + if err != nil || kv == nil { return emptyStrSlice, err } - - if kv == nil { - return emptyStrSlice, nil - } return []string{string(kv.Value)}, nil } @@ -112,19 +105,16 @@ func (m *consulMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *i func (m *consulMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) (string, error) { k := metadataIdentifier.GetIdentifierKey() kv, _, err := m.client.KV().Get(k, nil) - if err != nil { + if err != nil || kv == nil { return "", err } - - if kv == nil { - return "", nil - } return string(kv.Value), nil } type consulMetadataReportFactory struct { } +// nolint func (mf *consulMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { config := &consul.Config{Address: url.Location} client, err := consul.NewClient(config) diff --git a/metadata/report/nacos/report.go b/metadata/report/nacos/report.go index 988ea12838..d69913bd8f 100644 --- a/metadata/report/nacos/report.go +++ b/metadata/report/nacos/report.go @@ -38,8 +38,9 @@ import ( ) func init() { + mf := &nacosMetadataReportFactory{} extension.SetMetadataReportFactory("nacos", func() factory.MetadataReportFactory { - return &nacosMetadataReportFactory{} + return mf }) } @@ -148,18 +149,16 @@ func (n *nacosMetadataReport) getConfigAsArray(param vo.ConfigParam) ([]string, res := make([]string, 0, 1) cfg, err := n.getConfig(param) - if err != nil { + if err != nil || len(cfg) == 0 { return res, err } - if len(cfg) == 0 { - return res, nil - } decodeCfg, err := url.QueryUnescape(cfg) if err != nil { logger.Errorf("The config is invalid: %s", cfg) return res, err } + res = append(res, decodeCfg) return res, nil } @@ -177,6 +176,7 @@ func (n *nacosMetadataReport) getConfig(param vo.ConfigParam) (string, error) { type nacosMetadataReportFactory struct { } +// nolint func (n *nacosMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { client, err := nacos.NewNacosConfigClient(url) if err != nil { diff --git a/metadata/report/zookeeper/report.go b/metadata/report/zookeeper/report.go index 58c4791c2b..8f46bb0230 100644 --- a/metadata/report/zookeeper/report.go +++ b/metadata/report/zookeeper/report.go @@ -37,8 +37,9 @@ var ( ) func init() { + mf := &zookeeperMetadataReportFactory{} extension.SetMetadataReportFactory("zookeeper", func() factory.MetadataReportFactory { - return &zookeeperMetadataReportFactory{} + return mf }) } @@ -77,13 +78,9 @@ func (m *zookeeperMetadataReport) RemoveServiceMetadata(metadataIdentifier *iden func (m *zookeeperMetadataReport) GetExportedURLs(metadataIdentifier *identifier.ServiceMetadataIdentifier) ([]string, error) { k := m.rootDir + metadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) - if err != nil { + if err != nil || len(v) == 0 { return emptyStrSlice, err } - - if len(v) == 0 { - return emptyStrSlice, nil - } return []string{string(v)}, nil } @@ -97,13 +94,9 @@ func (m *zookeeperMetadataReport) SaveSubscribedData(subscriberMetadataIdentifie func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier *identifier.SubscriberMetadataIdentifier) ([]string, error) { k := m.rootDir + subscriberMetadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) - if err != nil { + if err != nil || len(v) == 0 { return emptyStrSlice, err } - - if len(v) == 0 { - return emptyStrSlice, nil - } return []string{string(v)}, nil } @@ -111,15 +104,13 @@ func (m *zookeeperMetadataReport) GetSubscribedURLs(subscriberMetadataIdentifier func (m *zookeeperMetadataReport) GetServiceDefinition(metadataIdentifier *identifier.MetadataIdentifier) (string, error) { k := m.rootDir + metadataIdentifier.GetFilePathKey() v, _, err := m.client.GetContent(k) - if err != nil { - return "", err - } - return string(v), nil + return string(v), err } type zookeeperMetadataReportFactory struct { } +// nolint func (mf *zookeeperMetadataReportFactory) CreateMetadataReport(url *common.URL) report.MetadataReport { client, err := zookeeper.NewZookeeperClient( "zookeeperMetadataReport", From 724854429c4c471c481e8d40385ecbe2acd6e701 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Wed, 1 Jul 2020 21:04:37 +0800 Subject: [PATCH 155/209] fix typo --- metadata/report/delegate/delegate_report_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata/report/delegate/delegate_report_test.go b/metadata/report/delegate/delegate_report_test.go index 04c9e64839..3dfca577ba 100644 --- a/metadata/report/delegate/delegate_report_test.go +++ b/metadata/report/delegate/delegate_report_test.go @@ -75,14 +75,14 @@ func TestMetadataReport_MetadataReportRetryWithLimit(t *testing.T) { func mockNewMetadataReport(t *testing.T) *MetadataReport { syncReportKey := "false" - retryPeroidKey := "3" + retryPeriodKey := "3" retryTimesKey := "100" cycleReportKey := "true" url, err := common.NewURL(fmt.Sprintf( "test://127.0.0.1:20000/?"+constant.SYNC_REPORT_KEY+"=%v&"+constant.RETRY_PERIOD_KEY+"=%v&"+ constant.RETRY_TIMES_KEY+"=%v&"+constant.CYCLE_REPORT_KEY+"=%v", - syncReportKey, retryPeroidKey, retryTimesKey, cycleReportKey)) + syncReportKey, retryPeriodKey, retryTimesKey, cycleReportKey)) assert.NoError(t, err) instance.SetMetadataReportUrl(url) mtr, err := NewMetadataReport() From f66dda85423af05e7776b11508eedc25553b3716 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Wed, 1 Jul 2020 21:18:02 +0800 Subject: [PATCH 156/209] update zk library version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ba3cf3e219..85efde193c 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/creasty/defaults v1.3.0 github.com/dubbogo/getty v1.3.5 - github.com/dubbogo/go-zookeeper v1.0.0 + github.com/dubbogo/go-zookeeper v1.0.1 github.com/dubbogo/gost v1.9.0 github.com/emicklei/go-restful/v3 v3.0.0 github.com/go-co-op/gocron v0.1.1 diff --git a/go.sum b/go.sum index eb84bde1fb..00b1eb02ee 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dubbogo/getty v1.3.5 h1:xJxdDj9jm7wlrRSsVZSk2TDNxJbbac5GpxV0QpjO+Tw= github.com/dubbogo/getty v1.3.5/go.mod h1:T55vN8Q6tZjf2AQZiGmkujneD3LfqYbv2b3QjacwYOY= -github.com/dubbogo/go-zookeeper v1.0.0 h1:RsYdlGwhDW+iKXM3eIIcvt34P2swLdmQfuIJxsHlGoM= -github.com/dubbogo/go-zookeeper v1.0.0/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= +github.com/dubbogo/go-zookeeper v1.0.1 h1:irLzvOsDOTNsN8Sv9tvYYxVu6DCQfLtziZQtUHmZgz8= +github.com/dubbogo/go-zookeeper v1.0.1/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= github.com/dubbogo/gost v1.5.1/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/dubbogo/gost v1.9.0 h1:UT+dWwvLyJiDotxJERO75jB3Yxgsdy10KztR5ycxRAk= github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= From 302dbc220e46e022c8cbb86a430b1aa0e39733c2 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Wed, 1 Jul 2020 23:38:42 +0800 Subject: [PATCH 157/209] simplify and comment --- metadata/report/consul/report_test.go | 3 +-- metadata/report/report.go | 27 +++++++++++++++++++++++- metadata/report/zookeeper/report_test.go | 3 +-- registry/consul/utils_test.go | 12 ++++------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go index b982d71765..34ee29de94 100644 --- a/metadata/report/consul/report_test.go +++ b/metadata/report/consul/report_test.go @@ -38,13 +38,12 @@ import ( ) func newProviderRegistryUrl(host string, port int) *common.URL { - url1 := common.NewURLWithOptions( + return common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithParams(url.Values{}), common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)), ) - return url1 } func newBaseMetadataIdentifier(side string) *identifier.BaseMetadataIdentifier { diff --git a/metadata/report/report.go b/metadata/report/report.go index 3ef8f5925e..62a9055e84 100644 --- a/metadata/report/report.go +++ b/metadata/report/report.go @@ -22,14 +22,39 @@ import ( "github.com/apache/dubbo-go/metadata/identifier" ) -// MetadataReport is an interface of remote metadata report +// MetadataReport is an interface of +// remote metadata report. type MetadataReport interface { + // StoreProviderMetadata stores the metadata. + // Metadata includes the basic info of the server, + // provider info, and other user custom info. StoreProviderMetadata(*identifier.MetadataIdentifier, string) error + + // StoreConsumerMetadata stores the metadata. + // Metadata includes the basic info of the server, + // consumer info, and other user custom info. StoreConsumerMetadata(*identifier.MetadataIdentifier, string) error + + // SaveServiceMetadata saves the metadata. + // Metadata includes the basic info of the server, + // service info, and other user custom info. SaveServiceMetadata(*identifier.ServiceMetadataIdentifier, common.URL) error + + // RemoveServiceMetadata removes the metadata. RemoveServiceMetadata(*identifier.ServiceMetadataIdentifier) error + + // GetExportedURLs gets the urls. + // If not found, an empty list will be returned. GetExportedURLs(*identifier.ServiceMetadataIdentifier) ([]string, error) + + // SaveSubscribedData saves the urls. + // If not found, an empty str will be returned. SaveSubscribedData(*identifier.SubscriberMetadataIdentifier, string) error + + // GetSubscribedURLs gets the urls. + // If not found, an empty list will be returned. GetSubscribedURLs(*identifier.SubscriberMetadataIdentifier) ([]string, error) + + // GetServiceDefinition gets the service definition. GetServiceDefinition(*identifier.MetadataIdentifier) (string, error) } diff --git a/metadata/report/zookeeper/report_test.go b/metadata/report/zookeeper/report_test.go index 5d25e3c496..a1e46e2e8d 100644 --- a/metadata/report/zookeeper/report_test.go +++ b/metadata/report/zookeeper/report_test.go @@ -38,13 +38,12 @@ import ( ) func newProviderRegistryUrl(host string, port int) *common.URL { - url1 := common.NewURLWithOptions( + return common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithParams(url.Values{}), common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)), ) - return url1 } func newBaseMetadataIdentifier(side string) *identifier.BaseMetadataIdentifier { diff --git a/registry/consul/utils_test.go b/registry/consul/utils_test.go index 1ef2004139..327dd95f71 100644 --- a/registry/consul/utils_test.go +++ b/registry/consul/utils_test.go @@ -46,43 +46,39 @@ var ( ) func newProviderRegistryUrl(host string, port int) *common.URL { - url1 := common.NewURLWithOptions( + return common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithParams(url.Values{}), common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)), ) - return url1 } func newConsumerRegistryUrl(host string, port int) *common.URL { - url1 := common.NewURLWithOptions( + return common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithParams(url.Values{}), common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)), ) - return url1 } func newProviderUrl(host string, port int, service string, protocol string) common.URL { - url1 := common.NewURLWithOptions( + return *common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithPath(service), common.WithProtocol(protocol), ) - return *url1 } func newConsumerUrl(host string, port int, service string, protocol string) common.URL { - url1 := common.NewURLWithOptions( + return *common.NewURLWithOptions( common.WithIp(host), common.WithPort(strconv.Itoa(port)), common.WithPath(service), common.WithProtocol(protocol), ) - return *url1 } type testServer struct { From 8906429cd5d29951e2b5101abc8c122e33901cf3 Mon Sep 17 00:00:00 2001 From: Patrick Date: Thu, 2 Jul 2020 09:51:07 +0800 Subject: [PATCH 158/209] add CreateTempWithValue in zookeeper client --- remoting/zookeeper/client.go | 38 +++++++++++++++++++ .../curator_discovery/service_discovery.go | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 349faff2b0..ea71429939 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -432,6 +432,44 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { return nil } +// CreateTempWithValue will create the node recursively, which means that if the parent node is absent, +// it will create parent node first,and set value in last child path +func (z *ZookeeperClient) CreateTempWithValue(basePath string, value []byte) error { + var ( + err error + tmpPath string + ) + + logger.Debugf("zookeeperClient.Create(basePath{%s})", basePath) + conn := z.getConn() + err = errNilZkClientConn + if conn == nil { + return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath) + } + + pathSlice := strings.Split(basePath, "/")[1:] + length := len(pathSlice) + for i, str := range pathSlice { + tmpPath = path.Join(tmpPath, "/", str) + // last child need be ephemeral + if i == length-1 { + _, err = conn.Create(tmpPath, value, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) + } else { + _, err = conn.Create(tmpPath, []byte{}, 0, zk.WorldACL(zk.PermAll)) + } + if err != nil { + if err == zk.ErrNodeExists { + logger.Debugf("zk.create(\"%s\") exists", tmpPath) + } else { + logger.Errorf("zk.create(\"%s\") error(%v)", tmpPath, perrors.WithStack(err)) + return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath) + } + } + } + + return nil +} + // nolint func (z *ZookeeperClient) Delete(basePath string) error { err := errNilZkClientConn diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index fc37d5c1d6..6c7ec15e9a 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -70,7 +70,7 @@ func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { if err != nil { return err } - err = sd.client.CreateWithValue(path, data) + err = sd.client.CreateTempWithValue(path, data) if err != nil { return err } From 378466946d726442c6da640936eaf2ebb3b1ba4e Mon Sep 17 00:00:00 2001 From: coffee Date: Thu, 2 Jul 2020 13:08:54 +0800 Subject: [PATCH 159/209] add namespaceId config for nacos --- common/constant/key.go | 1 + registry/nacos/base_registry.go | 1 + 2 files changed, 2 insertions(+) diff --git a/common/constant/key.go b/common/constant/key.go index 5be63fe82c..8da0e89caf 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -150,6 +150,7 @@ const ( NACOS_CATEGORY_KEY = "category" NACOS_PROTOCOL_KEY = "protocol" NACOS_PATH_KEY = "path" + NACOS_NAMESPACE_ID = "namespaceId" ) const ( diff --git a/registry/nacos/base_registry.go b/registry/nacos/base_registry.go index 63f4999675..f09754ebfb 100644 --- a/registry/nacos/base_registry.go +++ b/registry/nacos/base_registry.go @@ -95,6 +95,7 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") + clientConfig.NamespaceId = url.GetParam(constant.NACOS_NAMESPACE_ID, "") clientConfig.NotLoadCacheAtStart = true configMap["clientConfig"] = clientConfig From cb18057a3ffa87c47f247c57eddd8104230b9c6f Mon Sep 17 00:00:00 2001 From: willson-chen Date: Thu, 2 Jul 2020 22:23:26 +0800 Subject: [PATCH 160/209] Update logic of ANYHOST_KEY --- registry/base_configuration_listener.go | 1 - 1 file changed, 1 deletion(-) diff --git a/registry/base_configuration_listener.go b/registry/base_configuration_listener.go index d8c8cc8776..b36929d3d4 100644 --- a/registry/base_configuration_listener.go +++ b/registry/base_configuration_listener.go @@ -104,7 +104,6 @@ func ToConfigurators(urls []*common.URL, f func(url *common.URL) config_center.C override := url.GetParams() delete(override, constant.ANYHOST_KEY) if len(override) == 0 { - configurators = nil continue } configurators = append(configurators, f(url)) From 7aab5775f5d897a3b0da519576c10adb311fe095 Mon Sep 17 00:00:00 2001 From: pantianying Date: Sat, 4 Jul 2020 14:46:47 +0800 Subject: [PATCH 161/209] fix waitGroup --- registry/zookeeper/listener.go | 1 - registry/zookeeper/registry.go | 3 ++- remoting/zookeeper/listener.go | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go index c5b2f33c61..816e39bef5 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -111,7 +111,6 @@ type RegistryConfigurationListener struct { // NewRegistryConfigurationListener for listening the event of zk. func NewRegistryConfigurationListener(client *zk.ZookeeperClient, reg *zkRegistry) *RegistryConfigurationListener { - reg.WaitGroup().Add(1) return &RegistryConfigurationListener{client: client, registry: reg, events: make(chan *config_center.ConfigChangeEvent, 32), isClosed: false, close: make(chan struct{}, 1)} } diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 1e7bd08ade..04316bd9d8 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -134,6 +134,7 @@ func (r *zkRegistry) InitListeners() { regConfigListener.Close() } newDataListener.SubscribeURL(conf, NewRegistryConfigurationListener(r.client, r)) + r.WaitGroup().Add(1) go r.listener.ListenServiceEvent(conf, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(conf.Service())), newDataListener) } @@ -259,7 +260,7 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen //Interested register to dataconfig. r.dataListener.SubscribeURL(conf, zkListener) - + r.WaitGroup().Add(1) go r.listener.ListenServiceEvent(conf, fmt.Sprintf("/dubbo/%s/"+constant.DEFAULT_CATEGORY, url.QueryEscape(conf.Service())), r.dataListener) return zkListener, nil diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 5188ce8c44..1ffea88a86 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -77,13 +77,21 @@ func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remo case zk.EventNodeDataChanged: logger.Warnf("zk.ExistW(key{%s}) = event{EventNodeDataChanged}", zkPath) if len(listener) > 0 { - content, _, _ := l.client.Conn.Get(zkEvent.Path) + content, _, err := l.client.Conn.Get(zkEvent.Path) + if err != nil { + logger.Warnf("zk.Conn.Get{key:%s} = error{%v}", zkPath, err) + return false + } listener[0].DataChange(remoting.Event{Path: zkEvent.Path, Action: remoting.EventTypeUpdate, Content: string(content)}) } case zk.EventNodeCreated: logger.Warnf("zk.ExistW(key{%s}) = event{EventNodeCreated}", zkPath) if len(listener) > 0 { - content, _, _ := l.client.Conn.Get(zkEvent.Path) + content, _, err := l.client.Conn.Get(zkEvent.Path) + if err != nil { + logger.Warnf("zk.Conn.Get{key:%s} = error{%v}", zkPath, err) + return false + } listener[0].DataChange(remoting.Event{Path: zkEvent.Path, Action: remoting.EventTypeAdd, Content: string(content)}) } case zk.EventNotWatching: From d32161e043891ab836541091d2ec413a9c5c7518 Mon Sep 17 00:00:00 2001 From: lzp0412 <641785844@qq.com> Date: Sun, 5 Jul 2020 18:00:40 +0800 Subject: [PATCH 162/209] update nacos sdk version --- common/constant/key.go | 2 + common/url.go | 5 +- config_center/nacos/client.go | 95 ++++++++++++++------------------- go.mod | 16 ++---- go.sum | 14 +++-- registry/nacos/base_registry.go | 3 ++ 6 files changed, 59 insertions(+), 76 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index 8da0e89caf..8123d66557 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -151,6 +151,8 @@ const ( NACOS_PROTOCOL_KEY = "protocol" NACOS_PATH_KEY = "path" NACOS_NAMESPACE_ID = "namespaceId" + NACOS_PASSWORD = "password" + NACOS_USERNAME = "username" ) const ( diff --git a/common/url.go b/common/url.go index 983d1d798d..d5b9792f53 100644 --- a/common/url.go +++ b/common/url.go @@ -178,7 +178,10 @@ func WithToken(token string) option { if len(token) > 0 { value := token if strings.ToLower(token) == "true" || strings.ToLower(token) == "default" { - value = uuid.NewV4().String() + UUID, err := uuid.NewV4() + if err == nil { + value = UUID.String() + } } url.SetParam(constant.TOKEN_KEY, value) } diff --git a/config_center/nacos/client.go b/config_center/nacos/client.go index 3b432819f4..6fe5c4d7df 100644 --- a/config_center/nacos/client.go +++ b/config_center/nacos/client.go @@ -33,6 +33,7 @@ import ( ) import ( + "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" ) @@ -89,20 +90,17 @@ func ValidateNacosClient(container nacosClientFacade, opts ...option) error { } url := container.GetUrl() - logDir = url.GetParam(constant.CONFIG_LOG_DIR_KEY, logDir) - + timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) + if err != nil { + logger.Errorf("invalid timeout config %+v,got err %+v", + url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err) + return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location) + } + nacosAddresses := strings.Split(url.Location, ",") if container.NacosClient() == nil { - //in dubbo ,every registry only connect one node ,so this is []string{r.Address} - timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) - if err != nil { - logger.Errorf("timeout config %v is invalid ,err is %v", - url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err.Error()) - return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location) - } - nacosAddresses := strings.Split(url.Location, ",") - newClient, err := newNacosClient(os.nacosName, nacosAddresses, timeout) + newClient, err := newNacosClient(os.nacosName, nacosAddresses, timeout, url) if err != nil { - logger.Warnf("newNacosClient(name{%s}, nacos address{%v}, timeout{%d}) = error{%v}", + logger.Errorf("newNacosClient(name{%s}, nacos address{%v}, timeout{%d}) = error{%v}", os.nacosName, url.Location, timeout.String(), err) return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location) } @@ -110,41 +108,19 @@ func ValidateNacosClient(container nacosClientFacade, opts ...option) error { } if container.NacosClient().Client() == nil { - svrConfList := []nacosconst.ServerConfig{} - for _, nacosAddr := range container.NacosClient().NacosAddrs { - split := strings.Split(nacosAddr, ":") - port, err := strconv.ParseUint(split[1], 10, 64) - if err != nil { - logger.Warnf("nacos addr port parse error ,error message is %v", err) - continue - } - svrconf := nacosconst.ServerConfig{ - IpAddr: split[0], - Port: port, - } - svrConfList = append(svrConfList, svrconf) - } - - client, err := clients.CreateConfigClient(map[string]interface{}{ - "serverConfigs": svrConfList, - "clientConfig": nacosconst.ClientConfig{ - TimeoutMs: uint64(int32(container.NacosClient().Timeout / time.Millisecond)), - ListenInterval: 10000, - NotLoadCacheAtStart: true, - LogDir: logDir, - }, - }) - - container.NacosClient().SetClient(&client) + configClient, err := initNacosConfigClient(nacosAddresses, timeout, url) if err != nil { - logger.Errorf("nacos create config client error:%v", err) + logger.Errorf("initNacosConfigClient(addr:%+v,timeout:%v,url:%v) = err %+v", + nacosAddresses, timeout.String(), url, err) + return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location) } + container.NacosClient().SetClient(&configClient) } return perrors.WithMessagef(nil, "newNacosClient(address:%+v)", url.PrimitiveURL) } -func newNacosClient(name string, nacosAddrs []string, timeout time.Duration) (*NacosClient, error) { +func newNacosClient(name string, nacosAddrs []string, timeout time.Duration, url common.URL) (*NacosClient, error) { var ( err error n *NacosClient @@ -160,12 +136,24 @@ func newNacosClient(name string, nacosAddrs []string, timeout time.Duration) (*N }, } - svrConfList := make([]nacosconst.ServerConfig, 0, len(n.NacosAddrs)) - for _, nacosAddr := range n.NacosAddrs { + configClient, err := initNacosConfigClient(nacosAddrs, timeout, url) + if err != nil { + logger.Errorf("initNacosConfigClient(addr:%+v,timeout:%v,url:%v) = err %+v", + nacosAddrs, timeout.String(), url, err) + return n, perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location) + } + n.SetClient(&configClient) + + return n, nil +} + +func initNacosConfigClient(nacosAddrs []string, timeout time.Duration, url common.URL) (config_client.IConfigClient, error) { + svrConfList := []nacosconst.ServerConfig{} + for _, nacosAddr := range nacosAddrs { split := strings.Split(nacosAddr, ":") port, err := strconv.ParseUint(split[1], 10, 64) if err != nil { - logger.Warnf("convert port , source:%s , error:%v ", split[1], err) + logger.Errorf("strconv.ParseUint(nacos addr port:%+v) = error %+v", split[1], err) continue } svrconf := nacosconst.ServerConfig{ @@ -174,21 +162,21 @@ func newNacosClient(name string, nacosAddrs []string, timeout time.Duration) (*N } svrConfList = append(svrConfList, svrconf) } - client, err := clients.CreateConfigClient(map[string]interface{}{ + + return clients.CreateConfigClient(map[string]interface{}{ "serverConfigs": svrConfList, "clientConfig": nacosconst.ClientConfig{ - TimeoutMs: uint64(timeout / time.Millisecond), - ListenInterval: 20000, + TimeoutMs: uint64(int32(timeout / time.Millisecond)), + ListenInterval: uint64(int32(timeout / time.Millisecond)), NotLoadCacheAtStart: true, - LogDir: logDir, + LogDir: url.GetParam(constant.NACOS_LOG_DIR_KEY, logDir), + CacheDir: url.GetParam(constant.NACOS_CACHE_DIR_KEY, ""), + Endpoint: url.GetParam(constant.NACOS_ENDPOINT, ""), + Username: url.GetParam(constant.NACOS_USERNAME, ""), + Password: url.GetParam(constant.NACOS_PASSWORD, ""), + NamespaceId: url.GetParam(constant.NACOS_NAMESPACE_ID, ""), }, }) - n.SetClient(&client) - if err != nil { - return nil, perrors.WithMessagef(err, "nacos clients.CreateConfigClient(nacosAddrs:%+v)", nacosAddrs) - } - - return n, nil } // Done Get nacos client exit signal @@ -233,5 +221,4 @@ func (n *NacosClient) Close() { n.stop() n.SetClient(nil) - logger.Warnf("nacosClient{name:%s, nacos addr:%s} exit now.", n.name, n.NacosAddrs) } diff --git a/go.mod b/go.mod index 9a9adc3b23..76fb862b00 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/apache/dubbo-go require ( github.com/Workiva/go-datastructures v1.0.50 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 - github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279 - github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible github.com/coreos/go-semver v0.3.0 // indirect @@ -16,8 +14,6 @@ require ( github.com/dubbogo/go-zookeeper v1.0.0 github.com/dubbogo/gost v1.9.0 github.com/emicklei/go-restful/v3 v3.0.0 - github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect - github.com/go-errors/errors v1.0.1 // indirect github.com/go-resty/resty/v2 v2.1.0 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 @@ -29,33 +25,27 @@ require ( github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 github.com/hashicorp/consul v1.5.3 github.com/hashicorp/consul/api v1.1.0 - github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 - github.com/jonboulle/clockwork v0.1.0 // indirect github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect - github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect - github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect - github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect github.com/magiconair/properties v1.8.1 github.com/mitchellh/mapstructure v1.1.2 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd - github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c + github.com/nacos-group/nacos-sdk-go v0.3.2 github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.1.0 - github.com/satori/go.uuid v1.2.0 + github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect github.com/soheilhy/cmux v0.1.4 // indirect github.com/stretchr/testify v1.5.1 - github.com/tebeka/strftime v0.1.3 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect - github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 go.etcd.io/bbolt v1.3.4 // indirect go.uber.org/atomic v1.6.0 go.uber.org/zap v1.15.0 + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect google.golang.org/grpc v1.22.1 gopkg.in/yaml.v2 v2.2.2 k8s.io/api v0.0.0-20190325185214-7544f9db76f6 diff --git a/go.sum b/go.sum index f5610cb4b2..d426cc60b5 100644 --- a/go.sum +++ b/go.sum @@ -36,9 +36,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279 h1:1g3IJdaUjXWs++NA9Ail8+r6WgrkfhjS6hD/YXvRzjk= github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -52,7 +51,6 @@ github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL6 github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -388,8 +386,8 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c h1:WoCa3AvgQMVKNs+RIFlWPRgY9QVJwUxJDrGxHs0fcRo= -github.com/nacos-group/nacos-sdk-go v0.0.0-20191128082542-fe1b325b125c/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= +github.com/nacos-group/nacos-sdk-go v0.3.2 h1:q+ukmIImL6u0zBtbceMZl2frgeAc45QT6cIrTZZz50c= +github.com/nacos-group/nacos-sdk-go v0.3.2/go.mod h1:4TdsN7eZnnVCDlOlBa61b0gsRnvNJI74m9+2+OKZkcw= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0= @@ -454,8 +452,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= +github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880 h1:1Ge4j/3uB2rxzPWD3TC+daeCw+w91z8UCUL/7WH5gn8= diff --git a/registry/nacos/base_registry.go b/registry/nacos/base_registry.go index f09754ebfb..51c1eb8ad3 100644 --- a/registry/nacos/base_registry.go +++ b/registry/nacos/base_registry.go @@ -96,6 +96,9 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") clientConfig.NamespaceId = url.GetParam(constant.NACOS_NAMESPACE_ID, "") + clientConfig.Username = url.GetParam(constant.NACOS_USERNAME, "") + clientConfig.Password = url.GetParam(constant.NACOS_PASSWORD, "") + clientConfig.NamespaceId = url.GetParam(constant.NACOS_NAMESPACE_ID, "") clientConfig.NotLoadCacheAtStart = true configMap["clientConfig"] = clientConfig From 75776fb1425375f454bf8f20613a5ec51bdff6d1 Mon Sep 17 00:00:00 2001 From: lzp0412 <641785844@qq.com> Date: Sun, 5 Jul 2020 18:39:51 +0800 Subject: [PATCH 163/209] fix unitTest bug --- config_center/nacos/client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config_center/nacos/client_test.go b/config_center/nacos/client_test.go index 2e7f464514..856522587d 100644 --- a/config_center/nacos/client_test.go +++ b/config_center/nacos/client_test.go @@ -56,7 +56,7 @@ func TestNewNacosClient(t *testing.T) { func TestSetNacosClient(t *testing.T) { server := mockCommonNacosServer() - nacosURL := server.Listener.Addr().String() + nacosURL := "registry://" + server.Listener.Addr().String() registryUrl, _ := common.NewURL(nacosURL) c := &nacosDynamicConfiguration{ url: ®istryUrl, From 9a5990d9a9c3d5e6633c0d7d926c156416bcb931 Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 5 Jul 2020 14:05:12 +0800 Subject: [PATCH 164/209] Fix ZK BUG --- .../metadata_service_proxy_factory.go | 4 ++- config/base_config_test.go | 36 +++++++++---------- config/config_loader.go | 6 ++-- registry/etcdv3/service_discovery.go | 2 +- ...vent_publishing_service_deiscovery_test.go | 3 +- registry/zookeeper/service_discovery.go | 1 + registry/zookeeper/service_discovery_test.go | 4 +-- remoting/consul/test_agent.go | 8 +---- remoting/zookeeper/client.go | 6 +++- .../curator_discovery/service_discovery.go | 12 +++++++ remoting/zookeeper/facade.go | 6 ++-- 11 files changed, 50 insertions(+), 38 deletions(-) diff --git a/common/extension/metadata_service_proxy_factory.go b/common/extension/metadata_service_proxy_factory.go index e8c9e73d73..83695b027a 100644 --- a/common/extension/metadata_service_proxy_factory.go +++ b/common/extension/metadata_service_proxy_factory.go @@ -29,8 +29,10 @@ var ( metadataServiceProxyFactoryMap = make(map[string]func() service.MetadataServiceProxyFactory) ) +type MetadataServiceProxyFactoryFunc func() service.MetadataServiceProxyFactory + // SetMetadataServiceProxyFactory store the name-creator pair -func SetMetadataServiceProxyFactory(name string, creator func() service.MetadataServiceProxyFactory) { +func SetMetadataServiceProxyFactory(name string, creator MetadataServiceProxyFactoryFunc) { metadataServiceProxyFactoryMap[name] = creator } diff --git a/config/base_config_test.go b/config/base_config_test.go index 7fa895ad49..15b468753d 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -116,12 +116,12 @@ func TestRefresh(t *testing.T) { config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ - Check: &[]bool{true}[0], + Check: &[]bool{true}[0], BaseConfig: BaseConfig{ - ApplicationConfig:baseAppConfig, + ApplicationConfig: baseAppConfig, }, - Registries: baseRegistries, - References: baseMockRef, + Registries: baseRegistries, + References: baseMockRef, ShutdownConfig: &ShutdownConfig{ Timeout: "12s", StepTimeout: "2s", @@ -150,12 +150,12 @@ func TestAppExternalRefresh(t *testing.T) { mockMap["dubbo.consumer.check"] = "true" config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ - Check: &[]bool{true}[0], + Check: &[]bool{true}[0], BaseConfig: BaseConfig{ - ApplicationConfig:baseAppConfig, + ApplicationConfig: baseAppConfig, }, - Registries: baseRegistries, - References: baseMockRef, + Registries: baseRegistries, + References: baseMockRef, } c.SetFatherConfig(father) @@ -178,12 +178,12 @@ func TestAppExternalWithoutIDRefresh(t *testing.T) { mockMap["dubbo.consumer.check"] = "true" config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ - Check: &[]bool{true}[0], + Check: &[]bool{true}[0], BaseConfig: BaseConfig{ - ApplicationConfig:baseAppConfig, + ApplicationConfig: baseAppConfig, }, - Registries: baseRegistries, - References: baseMockRef, + Registries: baseRegistries, + References: baseMockRef, } c.SetFatherConfig(father) @@ -208,13 +208,13 @@ func TestRefreshSingleRegistry(t *testing.T) { config.GetEnvInstance().UpdateExternalConfigMap(mockMap) father := &ConsumerConfig{ - Check: &[]bool{true}[0], + Check: &[]bool{true}[0], BaseConfig: BaseConfig{ - ApplicationConfig: baseAppConfig, + ApplicationConfig: baseAppConfig, }, - Registries: map[string]*RegistryConfig{}, - Registry: &RegistryConfig{}, - References: baseMockRef, + Registries: map[string]*RegistryConfig{}, + Registry: &RegistryConfig{}, + References: baseMockRef, } c.SetFatherConfig(father) @@ -242,7 +242,7 @@ func TestRefreshProvider(t *testing.T) { BaseConfig: BaseConfig{ ApplicationConfig: baseAppConfig, }, - Registries: baseRegistries, + Registries: baseRegistries, Services: map[string]*ServiceConfig{ "MockService": { InterfaceName: "com.MockService", diff --git a/config/config_loader.go b/config/config_loader.go index d5f8c68c1b..b9195aec3f 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -148,9 +148,9 @@ func loadConsumerConfig() { checkok = false count++ if count > maxWait { - errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) - logger.Error(errMsg) - panic(errMsg) + // errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) + // logger.Error(errMsg) + // panic(errMsg) } time.Sleep(time.Second * 1) break diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index 5699f1c427..10396049fb 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -158,7 +158,7 @@ func (e *etcdV3ServiceDiscovery) GetInstances(serviceName string) []registry.Ser } return serviceInstances } - perrors.New(fmt.Sprintf("could not getChildrenKVList the err is:%v", err)) + logger.Infof("could not getChildrenKVList the err is:%v", err) } return make([]registry.ServiceInstance, 0, 0) diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index 8020702080..54752c03c0 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -20,8 +20,6 @@ package event import ( "reflect" "testing" - - "github.com/apache/dubbo-go/metadata/mapping" ) import ( @@ -36,6 +34,7 @@ import ( "github.com/apache/dubbo-go/common/observer" dispatcher2 "github.com/apache/dubbo-go/common/observer/dispatcher" "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/metadata/mapping" _ "github.com/apache/dubbo-go/metadata/service/inmemory" "github.com/apache/dubbo-go/registry" ) diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index aff92049aa..cf2016c361 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -300,6 +300,7 @@ func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool err := zksd.DispatchEventByServiceName(serviceName) if err != nil { logger.Errorf("[zkServiceDiscovery] DispatchEventByServiceName{%s} error = err{%v}", serviceName, err) + return false } return true } diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go index 6649407800..ea3c7ddd48 100644 --- a/registry/zookeeper/service_discovery_test.go +++ b/registry/zookeeper/service_discovery_test.go @@ -18,8 +18,6 @@ package zookeeper import ( - "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/common/observer" "strconv" "sync" "testing" @@ -31,6 +29,8 @@ import ( ) import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/observer" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/registry" ) diff --git a/remoting/consul/test_agent.go b/remoting/consul/test_agent.go index fd0694bde3..1744da7bd9 100644 --- a/remoting/consul/test_agent.go +++ b/remoting/consul/test_agent.go @@ -60,11 +60,5 @@ func (consulAgent *ConsulAgent) Close() error { if err != nil { return err } - - err = os.RemoveAll(consulAgent.dataDir) - if err != nil { - return err - } - - return nil + return os.RemoveAll(consulAgent.dataDir) } diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index a24e9eb828..d574fbcd20 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -156,7 +156,7 @@ func ValidateZookeeperClient(container ZkClientFacade, opts ...Option) error { } if connected { - logger.Info("Connect to zookeeper successfully, name{%s}, zk address{%v}", options.zkName, url.Location) + logger.Infof("Connect to zookeeper successfully, name{%s}, zk address{%v}", options.zkName, url.Location) container.WaitGroup().Add(1) // zk client start successful, then registry wg +1 } @@ -433,6 +433,7 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { // CreateTempWithValue will create the node recursively, which means that if the parent node is absent, // it will create parent node first,and set value in last child path +// If the path exist, it will update data func (z *ZookeeperClient) CreateTempWithValue(basePath string, value []byte) error { var ( err error @@ -453,6 +454,9 @@ func (z *ZookeeperClient) CreateTempWithValue(basePath string, value []byte) err // last child need be ephemeral if i == length-1 { _, err = conn.Create(tmpPath, value, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) + if err == zk.ErrNodeExists { + return err + } } else { _, err = conn.Create(tmpPath, []byte{}, 0, zk.WorldACL(zk.PermAll)) } diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 6c7ec15e9a..1b52a53d80 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -22,6 +22,8 @@ import ( "path" "strings" "sync" + + "github.com/dubbogo/go-zookeeper/zk" ) import ( @@ -71,6 +73,16 @@ func (sd *ServiceDiscovery) registerService(instance *ServiceInstance) error { return err } err = sd.client.CreateTempWithValue(path, data) + if err == zk.ErrNodeExists { + _, state, _ := sd.client.GetContent(path) + if state != nil { + _, err = sd.client.SetContent(path, data, state.Version+1) + if err != nil { + logger.Debugf("Try to update the node data failed. In most cases, it's not a problem. ") + } + } + return nil + } if err != nil { return err } diff --git a/remoting/zookeeper/facade.go b/remoting/zookeeper/facade.go index ac0c5e80e0..d5d9e6e748 100644 --- a/remoting/zookeeper/facade.go +++ b/remoting/zookeeper/facade.go @@ -18,7 +18,6 @@ package zookeeper import ( - "github.com/apache/dubbo-go/common" "sync" ) import ( @@ -27,6 +26,7 @@ import ( ) import ( + "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/logger" ) @@ -34,8 +34,8 @@ type ZkClientFacade interface { ZkClient() *ZookeeperClient SetZkClient(*ZookeeperClient) ZkClientLock() *sync.Mutex - WaitGroup() *sync.WaitGroup //for wait group control, zk client listener & zk client container - Done() chan struct{} //for zk client control + WaitGroup() *sync.WaitGroup // for wait group control, zk client listener & zk client container + Done() chan struct{} // for zk client control RestartCallBack() bool GetUrl() common.URL } From 03fc55215eb9708d9049bf48e1dbc041f684f812 Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Mon, 6 Jul 2020 16:28:48 +0800 Subject: [PATCH 165/209] support distributed transaction, by experimentally [seata-golang](https://github.com/dk-lockdown/seata-golang) --- filter/filter_impl/seata_filter.go | 63 +++++++++++++++++++++++++ filter/filter_impl/seata_filter_test.go | 56 ++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 filter/filter_impl/seata_filter.go create mode 100644 filter/filter_impl/seata_filter_test.go diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go new file mode 100644 index 0000000000..23e2a70b8c --- /dev/null +++ b/filter/filter_impl/seata_filter.go @@ -0,0 +1,63 @@ +/* + * 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 filter_impl + +import ( + "context" +) + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/filter" + "github.com/apache/dubbo-go/protocol" +) + +const ( + SEATA = "SEATA" + SEATA_XID = "SEATA_XID" +) + +func init() { + extension.SetFilter(SEATA, GetSeataFilter) +} + +// SeataFilter ... +type SeataFilter struct {} + +// When use Seata, transfer xid by attachments +// Invoke Get Xid by attachment key `SEATA_XID` +func (sf *SeataFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + logger.Infof("invoking seata filter.") + xid := invocation.AttachmentsByKey(SEATA_XID,"") + if xid != "" { + logger.Debugf("Method: %v,Xid: %v", invocation.MethodName(), xid) + return invoker.Invoke(context.WithValue(ctx,SEATA_XID, xid), invocation) + } + return invoker.Invoke(ctx,invocation) +} + +// OnResponse ... +func (sf *SeataFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return result +} + +// GetSeataFilter ... +func GetSeataFilter() filter.Filter { + return &SeataFilter{} +} \ No newline at end of file diff --git a/filter/filter_impl/seata_filter_test.go b/filter/filter_impl/seata_filter_test.go new file mode 100644 index 0000000000..825b471d43 --- /dev/null +++ b/filter/filter_impl/seata_filter_test.go @@ -0,0 +1,56 @@ +/* + * 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 filter_impl + +import ( + "context" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/invocation" +) + +type testMockSeataInvoker struct { + protocol.BaseInvoker +} + +func (iv *testMockSeataInvoker) Invoke(ctx context.Context, _ protocol.Invocation) protocol.Result { + val := ctx.Value(SEATA_XID) + if val != nil { + xid, ok := val.(string) + if ok { + return &protocol.RPCResult{Rest:xid} + } + } + return &protocol.RPCResult{} +} + +func TestSeataFilter_Invoke(t *testing.T) { + filter := GetSeataFilter() + result := filter.Invoke(context.Background(), &testMockSeataInvoker{}, invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, map[string]string{ + SEATA_XID: "10.30.21.227:8091:2000047792", + })) + assert.Equal(t, "10.30.21.227:8091:2000047792", result.Result()) +} + From 822f1a2dd6a33752c02e769460d87e161c219019 Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 5 Jul 2020 20:29:48 +0800 Subject: [PATCH 166/209] Add Release Notes --- CHANGE.md | 49 +++++++++++++++++++++++++++++++++++++++++ config/config_loader.go | 6 ++--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/CHANGE.md b/CHANGE.md index 00b074d284..3e48db1d3b 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -1,6 +1,55 @@ # Release Notes --- +## 1.5.0 + +### New Features +- [Application-Level Registry Model](https://github.com/apache/dubbo-go/pull/604) + - [DelegateMetadataReport & RemoteMetadataService](https://github.com/apache/dubbo-go/pull/505) + - [Nacos MetadataReport implementation](https://github.com/apache/dubbo-go/pull/522) + - [Nacos service discovery](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/nacos/service_discovery.go) + - [Zk metadata service](https://github.com/apache/dubbo-go/pull/633) + - [Zk service discovery](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/zookeeper/service_discovery.go) + - [Etcd metadata report](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) + - [Etcd metadata service discovery](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/etcdv3/service_discovery.go) +- [Support grpc json protocol](https://github.com/apache/dubbo-go/pull/582) + +### Enhancement +- [Optimize err handling ](https://github.com/apache/dubbo-go/pull/536/) +- [Add attribute method into Invocation and RpcInvocation](https://github.com/apache/dubbo-go/pull/537) +- [Optimize lock for zookeeper registry](https://github.com/apache/dubbo-go/pull/578) +- [Improve code coverage of zookeeper config center](https://github.com/apache/dubbo-go/pull/549) +- [Improve code coverage of nacos config center and configuration parser](https://github.com/apache/dubbo-go/pull/587) +- [Kubernetes as registry enhance](https://github.com/apache/dubbo-go/pull/577) +- [Optimize zk client's lock and tests](https://github.com/apache/dubbo-go/pull/601) +- [Add setInvoker method for invocation](https://github.com/apache/dubbo-go/pull/612) +- [Upgrade getty & hessian2](https://github.com/apache/dubbo-go/pull/626) +- [Optimize router design: Extract priority router](https://github.com/apache/dubbo-go/pull/630) +- [NamespaceId config for nacos](https://github.com/apache/dubbo-go/pull/641) + + +### Bugfixes +- [Fix Gitee problem](https://github.com/apache/dubbo-go/pull/590) +- [Gitee quality analyses -- common](https://github.com/apache/dubbo-go/issues/616) +- [Nacos client logDir path seperator for Windows](https://github.com/apache/dubbo-go/pull/591) +- [Fix various linter warnings](https://github.com/apache/dubbo-go/pull/624) +- [Fixed some issues in config folder that reported by sonar-qube](https://github.com/apache/dubbo-go/pull/634) +- [Zk disconnected, dubbo-go panic when subscribe](https://github.com/apache/dubbo-go/pull/613) +- [Enhancement cluster code analysis](https://github.com/apache/dubbo-go/pull/632) + +### Document & Comment +- [Add comment for common directory](https://github.com/apache/dubbo-go/pull/530) +- [Add comments for config_center](https://github.com/apache/dubbo-go/pull/545) +- [Update the comments in metrics](https://github.com/apache/dubbo-go/pull/547) +- [Add comments for config](https://github.com/apache/dubbo-go/pull/579) +- [Updated the dubbo-go-ext image](https://github.com/apache/dubbo-go/pull/581) +- [Add comment for cluster](https://github.com/apache/dubbo-go/pull/584) +- [Update the comments in filter directory](https://github.com/apache/dubbo-go/pull/586) +- [Add comment for metadata](https://github.com/apache/dubbo-go/pull/588) +- [Update the comments in protocol directory](https://github.com/apache/dubbo-go/pull/602) +- [Add comments for remoting](https://github.com/apache/dubbo-go/pull/605) +- [Update the comments in registy directory](https://github.com/apache/dubbo-go/pull/589) + ## 1.4.0 ### New Features diff --git a/config/config_loader.go b/config/config_loader.go index b9195aec3f..d5f8c68c1b 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -148,9 +148,9 @@ func loadConsumerConfig() { checkok = false count++ if count > maxWait { - // errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) - // logger.Error(errMsg) - // panic(errMsg) + errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) + logger.Error(errMsg) + panic(errMsg) } time.Sleep(time.Second * 1) break From d28ae76a7405fb0281ba4c1ba98e4ad6c341e894 Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Mon, 6 Jul 2020 18:31:54 +0800 Subject: [PATCH 167/209] Remove comments --- config/config_loader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config_loader.go b/config/config_loader.go index b9195aec3f..d5f8c68c1b 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -148,9 +148,9 @@ func loadConsumerConfig() { checkok = false count++ if count > maxWait { - // errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) - // logger.Error(errMsg) - // panic(errMsg) + errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version) + logger.Error(errMsg) + panic(errMsg) } time.Sleep(time.Second * 1) break From 6ffa278879c1c0a050e30737541b548bd11c97c7 Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Mon, 6 Jul 2020 20:49:27 +0800 Subject: [PATCH 168/209] add comments --- filter/filter_impl/seata_filter.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go index 23e2a70b8c..696667f2ad 100644 --- a/filter/filter_impl/seata_filter.go +++ b/filter/filter_impl/seata_filter.go @@ -37,7 +37,7 @@ func init() { extension.SetFilter(SEATA, GetSeataFilter) } -// SeataFilter ... +// SeataFilter when use seata-golang, use this filter to transfer xid type SeataFilter struct {} // When use Seata, transfer xid by attachments @@ -52,12 +52,12 @@ func (sf *SeataFilter) Invoke(ctx context.Context, invoker protocol.Invoker, inv return invoker.Invoke(ctx,invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (sf *SeataFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { return result } -// GetSeataFilter ... +// GetSeataFilter create SeataFilter instance func GetSeataFilter() filter.Filter { return &SeataFilter{} } \ No newline at end of file From 2a46f849246914b0d7a9058d8cb7c18f6c4f742d Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Mon, 6 Jul 2020 22:21:02 +0800 Subject: [PATCH 169/209] formant adjustment --- filter/filter_impl/seata_filter.go | 12 ++++++------ filter/filter_impl/seata_filter_test.go | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go index 696667f2ad..5731468f03 100644 --- a/filter/filter_impl/seata_filter.go +++ b/filter/filter_impl/seata_filter.go @@ -29,7 +29,7 @@ import ( ) const ( - SEATA = "SEATA" + SEATA = "SEATA" SEATA_XID = "SEATA_XID" ) @@ -38,18 +38,18 @@ func init() { } // SeataFilter when use seata-golang, use this filter to transfer xid -type SeataFilter struct {} +type SeataFilter struct{} // When use Seata, transfer xid by attachments // Invoke Get Xid by attachment key `SEATA_XID` func (sf *SeataFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking seata filter.") - xid := invocation.AttachmentsByKey(SEATA_XID,"") + xid := invocation.AttachmentsByKey(SEATA_XID, "") if xid != "" { logger.Debugf("Method: %v,Xid: %v", invocation.MethodName(), xid) - return invoker.Invoke(context.WithValue(ctx,SEATA_XID, xid), invocation) + return invoker.Invoke(context.WithValue(ctx, SEATA_XID, xid), invocation) } - return invoker.Invoke(ctx,invocation) + return invoker.Invoke(ctx, invocation) } // OnResponse dummy process, returns the result directly @@ -60,4 +60,4 @@ func (sf *SeataFilter) OnResponse(ctx context.Context, result protocol.Result, i // GetSeataFilter create SeataFilter instance func GetSeataFilter() filter.Filter { return &SeataFilter{} -} \ No newline at end of file +} diff --git a/filter/filter_impl/seata_filter_test.go b/filter/filter_impl/seata_filter_test.go index 825b471d43..97f524c87c 100644 --- a/filter/filter_impl/seata_filter_test.go +++ b/filter/filter_impl/seata_filter_test.go @@ -40,7 +40,7 @@ func (iv *testMockSeataInvoker) Invoke(ctx context.Context, _ protocol.Invocatio if val != nil { xid, ok := val.(string) if ok { - return &protocol.RPCResult{Rest:xid} + return &protocol.RPCResult{Rest: xid} } } return &protocol.RPCResult{} @@ -53,4 +53,3 @@ func TestSeataFilter_Invoke(t *testing.T) { })) assert.Equal(t, "10.30.21.227:8091:2000047792", result.Result()) } - From 09c5cafeb8ef71d8e6a9aa089b5bfe3b30de1705 Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Tue, 7 Jul 2020 14:18:05 +0800 Subject: [PATCH 170/209] update `GetSeataFilter` to `getSeataFilter` --- filter/filter_impl/seata_filter.go | 6 +++--- filter/filter_impl/seata_filter_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go index 5731468f03..d2771bdf9a 100644 --- a/filter/filter_impl/seata_filter.go +++ b/filter/filter_impl/seata_filter.go @@ -34,7 +34,7 @@ const ( ) func init() { - extension.SetFilter(SEATA, GetSeataFilter) + extension.SetFilter(SEATA, getSeataFilter) } // SeataFilter when use seata-golang, use this filter to transfer xid @@ -57,7 +57,7 @@ func (sf *SeataFilter) OnResponse(ctx context.Context, result protocol.Result, i return result } -// GetSeataFilter create SeataFilter instance -func GetSeataFilter() filter.Filter { +// getSeataFilter create SeataFilter instance +func getSeataFilter() filter.Filter { return &SeataFilter{} } diff --git a/filter/filter_impl/seata_filter_test.go b/filter/filter_impl/seata_filter_test.go index 97f524c87c..6c39897f7a 100644 --- a/filter/filter_impl/seata_filter_test.go +++ b/filter/filter_impl/seata_filter_test.go @@ -47,7 +47,7 @@ func (iv *testMockSeataInvoker) Invoke(ctx context.Context, _ protocol.Invocatio } func TestSeataFilter_Invoke(t *testing.T) { - filter := GetSeataFilter() + filter := getSeataFilter() result := filter.Invoke(context.Background(), &testMockSeataInvoker{}, invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, map[string]string{ SEATA_XID: "10.30.21.227:8091:2000047792", })) From 697fa50696f3a468538453a3e8bdcbdca46e705a Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Thu, 9 Jul 2020 09:11:13 +0800 Subject: [PATCH 171/209] optimization --- filter/filter_impl/seata_filter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go index d2771bdf9a..5cbfdb927e 100644 --- a/filter/filter_impl/seata_filter.go +++ b/filter/filter_impl/seata_filter.go @@ -29,7 +29,7 @@ import ( ) const ( - SEATA = "SEATA" + SEATA = "seata" SEATA_XID = "SEATA_XID" ) From b5a67e368a6a5e762fb378fa07a531773a70e121 Mon Sep 17 00:00:00 2001 From: pantianying Date: Thu, 9 Jul 2020 10:22:31 +0800 Subject: [PATCH 172/209] fix bug for no provider by zookeeper --- common/rpc_service.go | 2 +- remoting/zookeeper/listener.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/rpc_service.go b/common/rpc_service.go index 05ca3721d9..f8b8e0761e 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -272,7 +272,7 @@ func (sm *serviceMap) UnRegister(interfaceName, protocol, serviceId string) erro } } delete(svcs, serviceId) - if len(sm.serviceMap) == 0 { + if len(sm.serviceMap[protocol]) == 0 { delete(sm.serviceMap, protocol) } diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 1ffea88a86..948e0d73a5 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -235,7 +235,7 @@ func (l *ZkEventListener) listenDirEvent(conf *common.URL, zkPath string, listen // Only need to compare Path when subscribing to provider if strings.LastIndex(zkPath, constant.PROVIDER_CATEGORY) != -1 { provider, _ := common.NewURL(c) - if provider.Path != conf.Path { + if provider.ServiceKey() != conf.ServiceKey() { continue } } From 1d2278d946a71d1860edf3b5e8d96bfdd32acf0c Mon Sep 17 00:00:00 2001 From: liuxiaomin Date: Fri, 10 Jul 2020 09:31:46 +0800 Subject: [PATCH 173/209] bugfix --- filter/filter_impl/seata_filter.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/filter/filter_impl/seata_filter.go b/filter/filter_impl/seata_filter.go index 5cbfdb927e..7722d2954f 100644 --- a/filter/filter_impl/seata_filter.go +++ b/filter/filter_impl/seata_filter.go @@ -19,6 +19,7 @@ package filter_impl import ( "context" + "strings" ) import ( @@ -45,7 +46,7 @@ type SeataFilter struct{} func (sf *SeataFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking seata filter.") xid := invocation.AttachmentsByKey(SEATA_XID, "") - if xid != "" { + if strings.TrimSpace(xid) != "" { logger.Debugf("Method: %v,Xid: %v", invocation.MethodName(), xid) return invoker.Invoke(context.WithValue(ctx, SEATA_XID, xid), invocation) } From 744afb25a105ca1fd891c13dab582b340b5ad933 Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 10 Jul 2020 21:26:06 +0800 Subject: [PATCH 174/209] Fix Review --- .../service_discovery_registry.go | 3 ++- .../curator_discovery/service_discovery.go | 15 +++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index d6cce32f92..31c0ed18ee 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -263,9 +263,9 @@ func (s *serviceDiscoveryRegistry) Subscribe(url *common.URL, notify registry.No } s.registerServiceInstancesChangedListener(*url, listener) } - return nil } + func (s *serviceDiscoveryRegistry) registerServiceInstancesChangedListener(url common.URL, listener *registry.ServiceInstancesChangedListener) { listenerId := listener.ServiceName + ":" + getUrlKey(url) if !s.subscribedServices.Contains(listenerId) { @@ -335,6 +335,7 @@ func (s *serviceDiscoveryRegistry) synthesizeSubscribedURLs(subscribedURL *commo } return urls } + func shouldSubscribe(url common.URL) bool { return !shouldRegister(url) } diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 1b52a53d80..6924507b14 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -22,8 +22,6 @@ import ( "path" "strings" "sync" - - "github.com/dubbogo/go-zookeeper/zk" ) import ( @@ -31,6 +29,8 @@ import ( ) import ( + "github.com/dubbogo/go-zookeeper/zk" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/remoting" @@ -119,14 +119,17 @@ func (sd *ServiceDiscovery) UpdateService(instance *ServiceInstance) error { if !ok { return perrors.New("[ServiceDiscovery] services value not entry") } - entry.Lock() - defer entry.Unlock() - entry.instance = instance - path := sd.pathForInstance(instance.Name, instance.Id) data, err := json.Marshal(instance) + if err != nil { return err } + + entry.Lock() + defer entry.Unlock() + entry.instance = instance + path := sd.pathForInstance(instance.Name, instance.Id) + _, err = sd.client.SetContent(path, data, -1) if err != nil { return err From 762e45ebb642692558d76440136d3c430361e15b Mon Sep 17 00:00:00 2001 From: flycash Date: Fri, 10 Jul 2020 23:09:38 +0800 Subject: [PATCH 175/209] Fix Review --- common/extension/metadata_service_proxy_factory.go | 2 +- common/extension/service_instance_selector_factory.go | 2 +- common/extension/service_name_mapping.go | 6 ++++-- common/observer/listenable.go | 2 +- metadata/service/inmemory/service.go | 10 +--------- registry/event/protocol_ports_metadata_customizer.go | 4 ++-- .../servicediscovery/service_discovery_registry.go | 9 ++++----- registry/zookeeper/service_discovery.go | 2 +- remoting/etcdv3/client.go | 1 + remoting/zookeeper/client.go | 4 +++- 10 files changed, 19 insertions(+), 23 deletions(-) diff --git a/common/extension/metadata_service_proxy_factory.go b/common/extension/metadata_service_proxy_factory.go index 83695b027a..2b88d37c9a 100644 --- a/common/extension/metadata_service_proxy_factory.go +++ b/common/extension/metadata_service_proxy_factory.go @@ -26,7 +26,7 @@ import ( ) var ( - metadataServiceProxyFactoryMap = make(map[string]func() service.MetadataServiceProxyFactory) + metadataServiceProxyFactoryMap = make(map[string]func() service.MetadataServiceProxyFactory, 2) ) type MetadataServiceProxyFactoryFunc func() service.MetadataServiceProxyFactory diff --git a/common/extension/service_instance_selector_factory.go b/common/extension/service_instance_selector_factory.go index 7776a408d8..66d3e7646e 100644 --- a/common/extension/service_instance_selector_factory.go +++ b/common/extension/service_instance_selector_factory.go @@ -26,7 +26,7 @@ import ( ) var ( - serviceInstanceSelectorMappings = make(map[string]func() instance.ServiceInstanceSelector) + serviceInstanceSelectorMappings = make(map[string]func() instance.ServiceInstanceSelector, 2) ) // nolint diff --git a/common/extension/service_name_mapping.go b/common/extension/service_name_mapping.go index 9e5aac52f9..99fd4c25e9 100644 --- a/common/extension/service_name_mapping.go +++ b/common/extension/service_name_mapping.go @@ -21,11 +21,13 @@ import ( "github.com/apache/dubbo-go/metadata/mapping" ) +type ServiceNameMappingCreator func() mapping.ServiceNameMapping + var ( - globalNameMappingCreator func() mapping.ServiceNameMapping + globalNameMappingCreator ServiceNameMappingCreator ) -func SetGlobalServiceNameMapping(nameMappingCreator func() mapping.ServiceNameMapping) { +func SetGlobalServiceNameMapping(nameMappingCreator ServiceNameMappingCreator) { globalNameMappingCreator = nameMappingCreator } diff --git a/common/observer/listenable.go b/common/observer/listenable.go index 887f7a377d..bf6ae7219b 100644 --- a/common/observer/listenable.go +++ b/common/observer/listenable.go @@ -110,7 +110,7 @@ func (bl *BaseListener) RemoveEventListeners(listenersSlice []EventListener) { func (bl *BaseListener) RemoveAllEventListeners() { bl.Mutex.Lock() defer bl.Mutex.Unlock() - bl.ListenersCache = make(map[reflect.Type][]EventListener) + bl.ListenersCache = make(map[reflect.Type][]EventListener, 8) } // GetAllEventListeners get all listener diff --git a/metadata/service/inmemory/service.go b/metadata/service/inmemory/service.go index 6fe44cfc71..8269e691f1 100644 --- a/metadata/service/inmemory/service.go +++ b/metadata/service/inmemory/service.go @@ -196,20 +196,12 @@ func (mts *MetadataService) PublishServiceDefinition(url common.URL) error { interfaceName := url.GetParam(constant.INTERFACE_KEY, "") isGeneric := url.GetParamBool(constant.GENERIC_KEY, false) if len(interfaceName) > 0 && !isGeneric { - // judge is consumer or provider - // side := url.GetParam(constant.SIDE_KEY, "") - // var service event.RPCService service := common.ServiceMap.GetService(url.Protocol, url.GetParam(constant.BEAN_NAME_KEY, url.Service())) - // if side == event.RoleType(event.CONSUMER).Role() { - // //TODO:generate the service definition and store it - // - // } else if side == event.RoleType(event.PROVIDER).Role() { - // //TODO:generate the service definition and store it - // } sd := definition.BuildServiceDefinition(*service, url) data, err := sd.ToBytes() if err != nil { logger.Errorf("publishProvider getServiceDescriptor error. providerUrl:%v , error:%v ", url, err) + return nil } mts.serviceDefinitions.Store(url.ServiceKey(), string(data)) return nil diff --git a/registry/event/protocol_ports_metadata_customizer.go b/registry/event/protocol_ports_metadata_customizer.go index cf5d1a8ec1..a58471c2bd 100644 --- a/registry/event/protocol_ports_metadata_customizer.go +++ b/registry/event/protocol_ports_metadata_customizer.go @@ -101,6 +101,6 @@ func endpointsStr(protocolMap map[string]int) string { // nolint type endpoint struct { - Port int `json:"port"` - Protocol string `json:"protocol"` + Port int `json:"port, omitempty"` + Protocol string `json:"protocol, omitempty"` } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 31c0ed18ee..f0467d9b5c 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -95,7 +95,7 @@ func newServiceDiscoveryRegistry(url *common.URL) (registry.Registry, error) { subscribedServices: subscribedServices, subscribedURLsSynthesizers: subscribedURLsSynthesizers, registeredListeners: gxset.NewSet(), - serviceRevisionExportedURLsCache: make(map[string]map[string][]common.URL), + serviceRevisionExportedURLsCache: make(map[string]map[string][]common.URL, 8), serviceNameMapping: serviceNameMapping, metaDataService: metaDataService, }, nil @@ -316,7 +316,6 @@ func (s *serviceDiscoveryRegistry) subscribe(url *common.URL, notify registry.No if len(subscribedURLs) == 0 { subscribedURLs = s.synthesizeSubscribedURLs(url, serviceInstances) } - // TODO make sure it's workable for _, url := range subscribedURLs { notify.Notify(®istry.ServiceEvent{ Action: remoting.EventTypeAdd, @@ -519,7 +518,7 @@ func (s *serviceDiscoveryRegistry) initRevisionExportedURLsByInst(serviceInstanc revision := getExportedServicesRevision(serviceInstance) revisionExportedURLsMap := s.serviceRevisionExportedURLsCache[serviceName] if revisionExportedURLsMap == nil { - revisionExportedURLsMap = make(map[string][]common.URL) + revisionExportedURLsMap = make(map[string][]common.URL, 4) s.serviceRevisionExportedURLsCache[serviceName] = revisionExportedURLsMap } revisionExportedURLs := revisionExportedURLsMap[revision] @@ -592,8 +591,8 @@ func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsa } type endpoint struct { - Port int `json:"port"` - Protocol string `json:"protocol"` + Port int `json:"port, omitempty"` + Protocol string `json:"protocol, omitempty"` } func getProtocolPort(serviceInstance registry.ServiceInstance, protocol string) int { diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index cf2016c361..5ad83ef909 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -308,7 +308,7 @@ func (zksd *zookeeperServiceDiscovery) DataChange(eventType remoting.Event) bool // toCuratorInstance convert to curator's service instance func (zksd *zookeeperServiceDiscovery) toCuratorInstance(instance registry.ServiceInstance) *curator_discovery.ServiceInstance { id := instance.GetHost() + ":" + strconv.Itoa(instance.GetPort()) - pl := make(map[string]interface{}) + pl := make(map[string]interface{}, 8) pl["id"] = id pl["name"] = instance.GetServiceName() pl["metadata"] = instance.GetMetadata() diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index 080c941144..9e639b6e41 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -169,6 +169,7 @@ type Client struct { Wait sync.WaitGroup } +// nolint func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat int) (*Client, error) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index d574fbcd20..875fe4a5c0 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -163,6 +163,8 @@ func ValidateZookeeperClient(container ZkClientFacade, opts ...Option) error { return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.PrimitiveURL) } + +// nolint func NewZookeeperClient(name string, zkAddrs []string, timeout time.Duration) (*ZookeeperClient, error) { var ( err error @@ -634,7 +636,7 @@ func (z *ZookeeperClient) GetContent(zkPath string) ([]byte, *zk.Stat, error) { return z.Conn.Get(zkPath) } -// GetContent ... +// nolint func (z *ZookeeperClient) SetContent(zkPath string, content []byte, version int32) (*zk.Stat, error) { return z.Conn.Set(zkPath, content, version) } From 4140d5d9b11eab3163ba9be03721ef2f830956a5 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sat, 11 Jul 2020 23:21:50 +0800 Subject: [PATCH 176/209] fix travis --- remoting/zookeeper/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 875fe4a5c0..4ca34a6aec 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -163,7 +163,6 @@ func ValidateZookeeperClient(container ZkClientFacade, opts ...Option) error { return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.PrimitiveURL) } - // nolint func NewZookeeperClient(name string, zkAddrs []string, timeout time.Duration) (*ZookeeperClient, error) { var ( From 4c00837b495939dd8d5fc3872241fe33a61f7c7c Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sun, 12 Jul 2020 00:54:39 +0800 Subject: [PATCH 177/209] fix review comment --- registry/servicediscovery/service_discovery_registry.go | 6 +++--- remoting/etcdv3/client.go | 2 +- remoting/zookeeper/curator_discovery/service_discovery.go | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index f0467d9b5c..061d832b03 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -342,7 +342,7 @@ func shouldSubscribe(url common.URL) bool { func (s *serviceDiscoveryRegistry) getServices(url common.URL) *gxset.HashSet { services := gxset.NewSet() serviceNames := url.GetParam(constant.PROVIDER_BY, "") - if len(serviceNames) != 0 { + if len(serviceNames) > 0 { services = parseServices(serviceNames) } if services.Empty() { @@ -486,7 +486,7 @@ func (s *serviceDiscoveryRegistry) initSelectedRevisionExportedURLs(serviceInsta for range serviceInstances { selectServiceInstance := s.selectServiceInstance(serviceInstances) revisionExportedURLs := s.initRevisionExportedURLsByInst(selectServiceInstance) - if len(revisionExportedURLs) != 0 { + if len(revisionExportedURLs) > 0 { // If the result is valid,break break } @@ -565,7 +565,7 @@ func getExportedStoreType(serviceInstance registry.ServiceInstance) string { } func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsances []registry.ServiceInstance) []common.URL { - if serviceInsances == nil || len(serviceInsances) == 0 { + if len(serviceInsances) == 0 { return []common.URL{} } var clonedExportedURLs []common.URL diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index 9e639b6e41..7632a7cd04 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -131,7 +131,7 @@ func ValidateClient(container clientFacade, opts ...Option) error { return nil } -// NewServiceDiscoveryClient +// nolint func NewServiceDiscoveryClient(opts ...Option) *Client { options := &Options{ heartbeat: 1, // default heartbeat diff --git a/remoting/zookeeper/curator_discovery/service_discovery.go b/remoting/zookeeper/curator_discovery/service_discovery.go index 6924507b14..9566b54943 100644 --- a/remoting/zookeeper/curator_discovery/service_discovery.go +++ b/remoting/zookeeper/curator_discovery/service_discovery.go @@ -25,12 +25,11 @@ import ( ) import ( + "github.com/dubbogo/go-zookeeper/zk" perrors "github.com/pkg/errors" ) import ( - "github.com/dubbogo/go-zookeeper/zk" - "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/remoting" From 2f73ae5c92dd0164b52326b14dff643c329b56e7 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Sun, 12 Jul 2020 01:01:56 +0800 Subject: [PATCH 178/209] fix review comment --- .../subscribed_urls_synthesizer_factory.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go index ba7887223c..c9b1449bef 100644 --- a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go +++ b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer_factory.go @@ -17,16 +17,25 @@ package synthesizer +import ( + "sync" +) + var ( - synthesizers []SubscribedURLsSynthesizer + synthesizers []SubscribedURLsSynthesizer + synthesizerMutex sync.RWMutex ) // nolint func AddSynthesizer(synthesizer SubscribedURLsSynthesizer) { + synthesizerMutex.Lock() + defer synthesizerMutex.Unlock() synthesizers = append(synthesizers, synthesizer) } // nolint func GetAllSynthesizer() []SubscribedURLsSynthesizer { + synthesizerMutex.RLock() + defer synthesizerMutex.RUnlock() return synthesizers } From 3587bfec6126aa7faabc7a5aec1e4f81ed44b737 Mon Sep 17 00:00:00 2001 From: flycash Date: Sun, 12 Jul 2020 23:16:20 +0800 Subject: [PATCH 179/209] Upgrade hession to 1.6.1 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9e98e4ef09..e82a04b279 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/Workiva/go-datastructures v1.0.50 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 // indirect - github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279 + github.com/apache/dubbo-go-hessian2 v1.6.1 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible diff --git a/go.sum b/go.sum index eaeae0a226..8c8c4ef132 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,8 @@ github.com/apache/dubbo-go-hessian2 v1.5.0 h1:fzulDG5G7nX0ccgKdiN9XipJ7tZ4WXKgmk github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279 h1:1g3IJdaUjXWs++NA9Ail8+r6WgrkfhjS6hD/YXvRzjk= github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= +github.com/apache/dubbo-go-hessian2 v1.6.1 h1:mFKeCZzaCkk4mMOyP+LQ85GHbRyqKT7858KS21JQYA4= +github.com/apache/dubbo-go-hessian2 v1.6.1/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= From 982c3f155085d95fd825aa7b65902fc23813e533 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Mon, 13 Jul 2020 00:08:54 +0800 Subject: [PATCH 180/209] Fix router bug and revert test case --- config/router_config.go | 2 +- config/router_config_test.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/config/router_config.go b/config/router_config.go index 16943d96be..16a2bec918 100644 --- a/config/router_config.go +++ b/config/router_config.go @@ -44,7 +44,7 @@ func RouterInit(confRouterFile string) error { r, e := factory.NewFileRouter(bytes) if e == nil { url := r.URL() - routerURLSet.Add(url) + routerURLSet.Add(&url) return nil } logger.Warnf("router config type %s create fail {%v}\n", k, e) diff --git a/config/router_config_test.go b/config/router_config_test.go index bf189b600f..72e51c1c82 100644 --- a/config/router_config_test.go +++ b/config/router_config_test.go @@ -52,3 +52,15 @@ func TestString(t *testing.T) { assert.Equal(t, n2[0], "a1") assert.Equal(t, n2[1], "") } + +func TestRouterInit(t *testing.T) { + errPro := RouterInit(errorTestYML) + assert.Error(t, errPro) + + assert.Equal(t, 0, routerURLSet.Size()) + + errPro = RouterInit(testYML) + assert.NoError(t, errPro) + + assert.Equal(t, 1, routerURLSet.Size()) +} From 8347779dcfb415686b31721172a725829bf26f04 Mon Sep 17 00:00:00 2001 From: AlexStocks Date: Mon, 13 Jul 2020 00:51:38 +0800 Subject: [PATCH 181/209] Add: ftr 577 --- CHANGE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGE.md b/CHANGE.md index 3e48db1d3b..4a75ad3519 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -13,6 +13,7 @@ - [Etcd metadata report](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) - [Etcd metadata service discovery](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/etcdv3/service_discovery.go) - [Support grpc json protocol](https://github.com/apache/dubbo-go/pull/582) +- [Ftr: using different labels btw provider and consumer, k8s service discovery across namespaces](https://github.com/apache/dubbo-go/pull/577 ) ### Enhancement - [Optimize err handling ](https://github.com/apache/dubbo-go/pull/536/) From 00f9946dc5efe5138d2076fc77a22dbbd4b849f2 Mon Sep 17 00:00:00 2001 From: cvictory Date: Mon, 13 Jul 2020 14:33:08 +0800 Subject: [PATCH 182/209] modify return error and log --- .../cluster_impl/failover_cluster_invoker.go | 7 +++++-- common/proxy/proxy.go | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go index 66adabd104..5ff6dd1dad 100644 --- a/cluster/cluster_impl/failover_cluster_invoker.go +++ b/cluster/cluster_impl/failover_cluster_invoker.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "strconv" ) @@ -91,8 +92,10 @@ func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation pr invokerSvc := invoker.GetUrl().Service() invokerUrl := invoker.directory.GetUrl() return &protocol.RPCResult{ - Err: perrors.Errorf("Failed to invoke the method %v in the service %v. Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. Last error is %v.", - methodName, invokerSvc, retries, providers, len(providers), len(invokers), invokerUrl, ip, constant.Version, result.Error().Error(), + Err: perrors.Wrap(result.Error(), fmt.Sprintf("Failed to invoke the method %v in the service %v. "+ + "Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. "+ + "Last error is %+v.", methodName, invokerSvc, retries, providers, len(providers), len(invokers), + invokerUrl, ip, constant.Version, result.Error().Error()), )} } diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go index abcf87cd9d..27fa538765 100644 --- a/common/proxy/proxy.go +++ b/common/proxy/proxy.go @@ -23,6 +23,11 @@ import ( "sync" ) +import ( + "github.com/apache/dubbo-go-hessian2/java_exception" + perrors "github.com/pkg/errors" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -154,7 +159,17 @@ func (p *Proxy) Implement(v common.RPCService) { } err = result.Error() - logger.Debugf("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err) + if err != nil { + // the cause reason + err = perrors.Cause(err) + if throwabler, ok := err.(java_exception.Throwabler); ok { + logger.Errorf("invoke service throw exception: %v , stackTraceElements: %v", err.Error(), throwabler.GetStackTrace()) + } else { + logger.Errorf("result err: %v", err) + } + } else { + logger.Debugf("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err) + } if len(outs) == 1 { return []reflect.Value{reflect.ValueOf(&err).Elem()} } From e6e276e345a534a00708f04205772ba4d1898790 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Tue, 14 Jul 2020 10:36:33 +0800 Subject: [PATCH 183/209] delete useless key --- common/constant/default.go | 1 - 1 file changed, 1 deletion(-) diff --git a/common/constant/default.go b/common/constant/default.go index 566baea7f2..c1c404e089 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -58,7 +58,6 @@ const ( const ( ANY_VALUE = "*" - ANYHOST_KEY = "anyhost" ANYHOST_VALUE = "0.0.0.0" LOCAL_HOST_VALUE = "192.168.1.1" REMOVE_VALUE_PREFIX = "-" From d3db1c2ef966b5a3092ddfbb9fa5603f1fd92aad Mon Sep 17 00:00:00 2001 From: relaxedCat <470109166@qq.com> Date: Tue, 14 Jul 2020 10:58:56 +0800 Subject: [PATCH 184/209] fix graceful shutdwon add sigterm signal --- config/graceful_shutdown_signal_darwin.go | 2 +- config/graceful_shutdown_signal_linux.go | 2 +- config/graceful_shutdown_signal_windows.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/graceful_shutdown_signal_darwin.go b/config/graceful_shutdown_signal_darwin.go index 6f1fa982a3..1a557dd3ed 100644 --- a/config/graceful_shutdown_signal_darwin.go +++ b/config/graceful_shutdown_signal_darwin.go @@ -26,7 +26,7 @@ var ( // ShutdownSignals receives shutdown signals to process ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT, syscall.SIGSYS} + syscall.SIGABRT, syscall.SIGSYS, syscall.SIGTERM} // DumpHeapShutdownSignals receives shutdown signals to process DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL, diff --git a/config/graceful_shutdown_signal_linux.go b/config/graceful_shutdown_signal_linux.go index 6f1fa982a3..1a557dd3ed 100644 --- a/config/graceful_shutdown_signal_linux.go +++ b/config/graceful_shutdown_signal_linux.go @@ -26,7 +26,7 @@ var ( // ShutdownSignals receives shutdown signals to process ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT, syscall.SIGSYS} + syscall.SIGABRT, syscall.SIGSYS, syscall.SIGTERM} // DumpHeapShutdownSignals receives shutdown signals to process DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL, diff --git a/config/graceful_shutdown_signal_windows.go b/config/graceful_shutdown_signal_windows.go index 3136e5ae15..89edd27b18 100644 --- a/config/graceful_shutdown_signal_windows.go +++ b/config/graceful_shutdown_signal_windows.go @@ -26,7 +26,7 @@ var ( // ShutdownSignals receives shutdown signals to process ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT} + syscall.SIGABRT, syscall.SIGTERM} // DumpHeapShutdownSignals receives shutdown signals to process DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT} From 9c857ed94c8cbb75f15568644a581d017f377e01 Mon Sep 17 00:00:00 2001 From: cvictory Date: Tue, 14 Jul 2020 11:17:13 +0800 Subject: [PATCH 185/209] change log level --- common/proxy/proxy.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go index 27fa538765..ce0f4d1d3f 100644 --- a/common/proxy/proxy.go +++ b/common/proxy/proxy.go @@ -162,10 +162,11 @@ func (p *Proxy) Implement(v common.RPCService) { if err != nil { // the cause reason err = perrors.Cause(err) + // if some error happened, it should be log some info in the seperate file. if throwabler, ok := err.(java_exception.Throwabler); ok { - logger.Errorf("invoke service throw exception: %v , stackTraceElements: %v", err.Error(), throwabler.GetStackTrace()) + logger.Warnf("invoke service throw exception: %v , stackTraceElements: %v", err.Error(), throwabler.GetStackTrace()) } else { - logger.Errorf("result err: %v", err) + logger.Warnf("result err: %v", err) } } else { logger.Debugf("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err) From 5fa56c6bf2a24861ad4d9e5ea754a825cf15d141 Mon Sep 17 00:00:00 2001 From: jialiang Date: Tue, 14 Jul 2020 13:33:51 +0800 Subject: [PATCH 186/209] fix: panic when checkRegistries --- config/consumer_config.go | 2 +- config/provider_config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/consumer_config.go b/config/consumer_config.go index f8b671bf3c..48f29f0e70 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -47,7 +47,7 @@ type ConsumerConfig struct { ConnectTimeout time.Duration Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` + Registries map[string]*RegistryConfig `default:"{}" yaml:"registries" json:"registries" property:"registries"` Request_Timeout string `yaml:"request_timeout" default:"5s" json:"request_timeout,omitempty" property:"request_timeout"` RequestTimeout time.Duration diff --git a/config/provider_config.go b/config/provider_config.go index 9d8a2429d2..6195080160 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -48,7 +48,7 @@ type ProviderConfig struct { ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` + Registries map[string]*RegistryConfig `default:"{}" yaml:"registries" json:"registries,omitempty" property:"registries"` } // UnmarshalYAML unmarshals the ProviderConfig by @unmarshal function From f15150fc3a5f056372d172d9aa102027541cc2cd Mon Sep 17 00:00:00 2001 From: jialiang Date: Tue, 14 Jul 2020 15:27:14 +0800 Subject: [PATCH 187/209] Fix: panic when checkRegistries --- config/provider_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/provider_config.go b/config/provider_config.go index 6195080160..7cd3c1e98b 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -48,7 +48,7 @@ type ProviderConfig struct { ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` - Registries map[string]*RegistryConfig `default:"{}" yaml:"registries" json:"registries,omitempty" property:"registries"` + Registries map[string]*RegistryConfig `default:"{}" yaml:"registries" json:"registries" property:"registries"` } // UnmarshalYAML unmarshals the ProviderConfig by @unmarshal function From 667540a5a68b0f45da34b57bd232bbc4b3c605ad Mon Sep 17 00:00:00 2001 From: lihaowei <2421565398@qq.com> Date: Sun, 19 Jul 2020 18:37:29 +0800 Subject: [PATCH 188/209] Imp: add some comments --- NOTICE | 2 +- .../cluster_impl/broadcast_cluster_invoker.go | 1 + common/constant/env.go | 1 + config/base_config_test.go | 8 +++--- config/config_loader_test.go | 4 +-- config/method_config.go | 4 +-- config/reference_config.go | 2 +- config/reference_config_test.go | 8 +++--- config/service_config.go | 2 +- config/service_config_test.go | 8 +++--- config_center/apollo/factory.go | 1 + config_center/mock_dynamic_config.go | 8 +++--- config_center/parser/configuration_parser.go | 17 +++++++---- config_center/zookeeper/listener.go | 2 +- filter/filter.go | 2 +- filter/filter_impl/access_log_filter.go | 12 ++++---- filter/filter_impl/echo_filter.go | 2 +- filter/filter_impl/execute_limit_filter.go | 2 +- filter/filter_impl/generic_filter.go | 2 +- filter/filter_impl/generic_service_filter.go | 12 ++++---- .../generic_service_filter_test.go | 4 +-- filter/filter_impl/hystrix_filter.go | 16 +++++------ filter/filter_impl/token_filter.go | 4 +-- .../tps/tps_limit_fix_window_strategy.go | 2 +- .../tps/tps_limit_strategy_mock.go | 5 +++- filter/filter_impl/tracing_filter_test.go | 5 +--- go.mod | 2 -- .../exporter/configurable/exporter_test.go | 4 +-- protocol/dubbo/codec.go | 6 ++-- protocol/grpc/grpc_exporter.go | 2 +- protocol/grpc/grpc_invoker.go | 12 ++++---- protocol/jsonrpc/http.go | 2 +- protocol/jsonrpc/json.go | 2 +- .../protocol_filter_wrapper.go | 12 ++++---- protocol/rest/config/rest_config.go | 28 +++++++++---------- protocol/rest/rest_exporter.go | 3 ++ protocol/rest/rest_invoker.go | 5 ++++ protocol/rest/rest_protocol.go | 9 ++++++ .../subscribed_urls_synthesizer.go | 1 + remoting/listener.go | 2 ++ 40 files changed, 126 insertions(+), 100 deletions(-) diff --git a/NOTICE b/NOTICE index d7aa899d1c..1120c200c9 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,4 @@ -Apache Dubbo Go +Apache Dubbo-go Copyright 2018-2020 The Apache Software Foundation This product includes software developed at diff --git a/cluster/cluster_impl/broadcast_cluster_invoker.go b/cluster/cluster_impl/broadcast_cluster_invoker.go index 3a97d3d9b4..b117dbb246 100644 --- a/cluster/cluster_impl/broadcast_cluster_invoker.go +++ b/cluster/cluster_impl/broadcast_cluster_invoker.go @@ -36,6 +36,7 @@ func newBroadcastClusterInvoker(directory cluster.Directory) protocol.Invoker { } } +// nolint func (invoker *broadcastClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { invokers := invoker.directory.List(invocation) err := invoker.checkInvokers(invokers, invocation) diff --git a/common/constant/env.go b/common/constant/env.go index 5376323328..f8402b9cb8 100644 --- a/common/constant/env.go +++ b/common/constant/env.go @@ -17,6 +17,7 @@ package constant +// nolint const ( // CONF_CONSUMER_FILE_PATH ... CONF_CONSUMER_FILE_PATH = "CONF_CONSUMER_FILE_PATH" diff --git a/config/base_config_test.go b/config/base_config_test.go index 15b468753d..6db6a8dcb8 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -95,14 +95,14 @@ var baseMockRef = map[string]*ReferenceConfig{ InterfaceName: "com.MockService", Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, { InterfaceId: "MockService", InterfaceName: "com.MockService", Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, }, }, @@ -258,14 +258,14 @@ func TestRefreshProvider(t *testing.T) { InterfaceName: "com.MockService", Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, { InterfaceId: "MockService", InterfaceName: "com.MockService", Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, }, }, diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 2cbf526a70..01d2ca812a 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -278,13 +278,13 @@ func mockInitProviderWithSingleRegistry() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, }, diff --git a/config/method_config.go b/config/method_config.go index e64773eb13..b64306fd6a 100644 --- a/config/method_config.go +++ b/config/method_config.go @@ -25,13 +25,13 @@ import ( "github.com/apache/dubbo-go/common/constant" ) -// MethodConfig ... +// MethodConfig defines method config type MethodConfig struct { InterfaceId string InterfaceName string Name string `yaml:"name" json:"name,omitempty" property:"name"` Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + LoadBalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` Weight int64 `yaml:"weight" json:"weight,omitempty" property:"weight"` TpsLimitInterval string `yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"` TpsLimitRate string `yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"` diff --git a/config/reference_config.go b/config/reference_config.go index 748b2d403f..e9a895d57a 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -220,7 +220,7 @@ func (c *ReferenceConfig) getUrlMap() url.Values { urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, c.Filter, defaultReferenceFilter)) for _, v := range c.Methods { - urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.Loadbalance) + urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.LoadBalance) urlMap.Set("methods."+v.Name+"."+constant.RETRIES_KEY, v.Retries) urlMap.Set("methods."+v.Name+"."+constant.STICKY_KEY, strconv.FormatBool(v.Sticky)) if len(v.RequestTimeout) != 0 { diff --git a/config/reference_config_test.go b/config/reference_config_test.go index 3fbf8da44c..45cdb2dfac 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -103,12 +103,12 @@ func doInitConsumer() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Sticky: true, }, }, @@ -174,12 +174,12 @@ func doInitConsumerWithSingleRegistry() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", }, }, }, diff --git a/config/service_config.go b/config/service_config.go index 57fce028fa..4351eea7c9 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -303,7 +303,7 @@ func (c *ServiceConfig) getUrlMap() url.Values { for _, v := range c.Methods { prefix := "methods." + v.Name + "." - urlMap.Set(prefix+constant.LOADBALANCE_KEY, v.Loadbalance) + urlMap.Set(prefix+constant.LOADBALANCE_KEY, v.LoadBalance) urlMap.Set(prefix+constant.RETRIES_KEY, v.Retries) urlMap.Set(prefix+constant.WEIGHT_KEY, strconv.FormatInt(v.Weight, 10)) diff --git a/config/service_config_test.go b/config/service_config_test.go index e7d55077be..0f7e404f6e 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -56,13 +56,13 @@ func doInitProvider() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, }, @@ -81,13 +81,13 @@ func doInitProvider() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, }, diff --git a/config_center/apollo/factory.go b/config_center/apollo/factory.go index f975ce13d8..8d873eaabc 100644 --- a/config_center/apollo/factory.go +++ b/config_center/apollo/factory.go @@ -34,6 +34,7 @@ func createDynamicConfigurationFactory() config_center.DynamicConfigurationFacto type apolloConfigurationFactory struct{} +// GetDynamicConfiguration returns the dynamic configuration func (f *apolloConfigurationFactory) GetDynamicConfiguration(url *common.URL) (config_center.DynamicConfiguration, error) { dynamicConfiguration, err := newApolloConfiguration(url) if err != nil { diff --git a/config_center/mock_dynamic_config.go b/config_center/mock_dynamic_config.go index de208946f1..8fe0a25123 100644 --- a/config_center/mock_dynamic_config.go +++ b/config_center/mock_dynamic_config.go @@ -33,7 +33,7 @@ import ( "github.com/apache/dubbo-go/remoting" ) -// MockDynamicConfigurationFactory ... +// MockDynamicConfigurationFactory defines content type MockDynamicConfigurationFactory struct { Content string } @@ -96,7 +96,7 @@ func (c *MockDynamicConfiguration) GetConfigKeysByGroup(group string) (*gxset.Ha return gxset.NewSet(c.content), nil } -// MockDynamicConfiguration ... +// MockDynamicConfiguration uses to parse content and defines listener type MockDynamicConfiguration struct { parser parser.ConfigurationParser content string @@ -149,7 +149,7 @@ func (c *MockDynamicConfiguration) GetRule(key string, opts ...Option) (string, return c.GetProperties(key, opts...) } -// MockServiceConfigEvent ... +// MockServiceConfigEvent returns ConfiguratorConfig func (c *MockDynamicConfiguration) MockServiceConfigEvent() { config := &parser.ConfiguratorConfig{ ConfigVersion: "2.7.1", @@ -171,7 +171,7 @@ func (c *MockDynamicConfiguration) MockServiceConfigEvent() { c.listener[key].Process(&ConfigChangeEvent{Key: key, Value: string(value), ConfigType: remoting.EventTypeAdd}) } -// MockApplicationConfigEvent ... +// MockApplicationConfigEvent returns ConfiguratorConfig func (c *MockDynamicConfiguration) MockApplicationConfigEvent() { config := &parser.ConfiguratorConfig{ ConfigVersion: "2.7.1", diff --git a/config_center/parser/configuration_parser.go b/config_center/parser/configuration_parser.go index 6fbdc27d43..f794221f9c 100644 --- a/config_center/parser/configuration_parser.go +++ b/config_center/parser/configuration_parser.go @@ -35,13 +35,13 @@ import ( ) const ( - // ScopeApplication ... + // ScopeApplication : scope application ScopeApplication = "application" - // GeneralType ... + // GeneralType defines the general type GeneralType = "general" ) -// ConfigurationParser ... +// ConfigurationParser interface type ConfigurationParser interface { Parse(string) (map[string]string, error) ParseToUrls(content string) ([]*common.URL, error) @@ -50,7 +50,7 @@ type ConfigurationParser interface { // DefaultConfigurationParser for supporting properties file in config center type DefaultConfigurationParser struct{} -// ConfiguratorConfig ... +// ConfiguratorConfig defines configurator config type ConfiguratorConfig struct { ConfigVersion string `yaml:"configVersion"` Scope string `yaml:"scope"` @@ -59,7 +59,7 @@ type ConfiguratorConfig struct { Configs []ConfigItem `yaml:"configs"` } -// ConfigItem ... +// ConfigItem defines config item type ConfigItem struct { Type string `yaml:"type"` Enabled bool `yaml:"enabled"` @@ -81,7 +81,7 @@ func (parser *DefaultConfigurationParser) Parse(content string) (map[string]stri return pps.Map(), nil } -// ParseToUrls ... +// ParseToUrls is used to parse content to urls func (parser *DefaultConfigurationParser) ParseToUrls(content string) ([]*common.URL, error) { config := ConfiguratorConfig{} if err := yaml.Unmarshal([]byte(content), &config); err != nil { @@ -110,6 +110,7 @@ func (parser *DefaultConfigurationParser) ParseToUrls(content string) ([]*common return allUrls, nil } +// serviceItemToUrls is used to transfer item and config to urls func serviceItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.URL, error) { var addresses = item.Addresses if len(addresses) == 0 { @@ -156,6 +157,7 @@ func serviceItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.UR return urls, nil } +// nolint func appItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.URL, error) { var addresses = item.Addresses if len(addresses) == 0 { @@ -196,6 +198,7 @@ func appItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.URL, e return urls, nil } +// getServiceString returns service string func getServiceString(service string) (string, error) { if len(service) == 0 { return "", perrors.New("service field in configuration is null.") @@ -219,6 +222,7 @@ func getServiceString(service string) (string, error) { return serviceStr, nil } +// nolint func getParamString(item ConfigItem) (string, error) { var retStr string retStr = retStr + "category=" @@ -241,6 +245,7 @@ func getParamString(item ConfigItem) (string, error) { return retStr, nil } +// getEnabledString returns enabled string func getEnabledString(item ConfigItem, config ConfiguratorConfig) string { retStr := "&enabled=" if len(item.Type) == 0 || item.Type == GeneralType { diff --git a/config_center/zookeeper/listener.go b/config_center/zookeeper/listener.go index 747c4be352..bc6eb6d6ee 100644 --- a/config_center/zookeeper/listener.go +++ b/config_center/zookeeper/listener.go @@ -27,7 +27,7 @@ import ( "github.com/apache/dubbo-go/remoting" ) -// CacheListener ... +// CacheListener defines keyListeners and rootPath type CacheListener struct { keyListeners sync.Map rootPath string diff --git a/filter/filter.go b/filter/filter.go index d20ca72c34..804bf3b9df 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -27,7 +27,7 @@ import ( // Filter interface defines the functions of a filter // Extension - Filter type Filter interface { - // Invoke is the core function of a filter, it determins the process of the filter + // Invoke is the core function of a filter, it determines the process of the filter Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result // OnResponse updates the results from Invoke and then returns the modified results. OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result diff --git a/filter/filter_impl/access_log_filter.go b/filter/filter_impl/access_log_filter.go index 49cdc2287c..621012c24c 100644 --- a/filter/filter_impl/access_log_filter.go +++ b/filter/filter_impl/access_log_filter.go @@ -36,20 +36,20 @@ import ( const ( //used in URL. - // FileDateFormat ... + // nolint FileDateFormat = "2006-01-02" - // MessageDateLayout ... + // nolint MessageDateLayout = "2006-01-02 15:04:05" - // LogMaxBuffer ... + // nolint LogMaxBuffer = 5000 - // LogFileMode ... + // nolint LogFileMode = 0600 // those fields are the data collected by this filter - // Types ... + // nolint Types = "types" - // Arguments ... + // nolint Arguments = "arguments" ) diff --git a/filter/filter_impl/echo_filter.go b/filter/filter_impl/echo_filter.go index 7da5ec7029..06e443e807 100644 --- a/filter/filter_impl/echo_filter.go +++ b/filter/filter_impl/echo_filter.go @@ -65,7 +65,7 @@ func (ef *EchoFilter) OnResponse(_ context.Context, result protocol.Result, _ pr return result } -// GetFilter ... +// GetFilter returns the Filter func GetFilter() filter.Filter { return &EchoFilter{} } diff --git a/filter/filter_impl/execute_limit_filter.go b/filter/filter_impl/execute_limit_filter.go index bfc5096ca0..5fc309cfb4 100644 --- a/filter/filter_impl/execute_limit_filter.go +++ b/filter/filter_impl/execute_limit_filter.go @@ -74,7 +74,7 @@ type ExecuteLimitFilter struct { executeState *concurrent.Map } -// ExecuteState ... +// ExecuteState defines the concurrent count type ExecuteState struct { concurrentCount int64 } diff --git a/filter/filter_impl/generic_filter.go b/filter/filter_impl/generic_filter.go index 3f4d714e6b..d385054ed9 100644 --- a/filter/filter_impl/generic_filter.go +++ b/filter/filter_impl/generic_filter.go @@ -47,7 +47,7 @@ func init() { // when do a generic invoke, struct need to be map -// GenericFilter ... +// nolint type GenericFilter struct{} // Invoke turns the parameters to map for generic method diff --git a/filter/filter_impl/generic_service_filter.go b/filter/filter_impl/generic_service_filter.go index 6272df6b39..3711e68cce 100644 --- a/filter/filter_impl/generic_service_filter.go +++ b/filter/filter_impl/generic_service_filter.go @@ -40,9 +40,9 @@ import ( ) const ( - // GENERIC_SERVICE ... + // GENERIC_SERVICE defines the filter name GENERIC_SERVICE = "generic_service" - // GENERIC_SERIALIZATION_DEFAULT ... + // nolint GENERIC_SERIALIZATION_DEFAULT = "true" ) @@ -50,10 +50,10 @@ func init() { extension.SetFilter(GENERIC_SERVICE, GetGenericServiceFilter) } -// GenericServiceFilter ... +// nolint type GenericServiceFilter struct{} -// Invoke ... +// Invoke is used to call service method by invocation func (ef *GenericServiceFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking generic service filter.") logger.Debugf("generic service filter methodName:%v,args:%v", invocation.MethodName(), len(invocation.Arguments())) @@ -115,7 +115,7 @@ func (ef *GenericServiceFilter) Invoke(ctx context.Context, invoker protocol.Inv return invoker.Invoke(ctx, newInvocation) } -// OnResponse ... +// nolint func (ef *GenericServiceFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { if invocation.MethodName() == constant.GENERIC && len(invocation.Arguments()) == 3 && result.Result() != nil { v := reflect.ValueOf(result.Result()) @@ -127,7 +127,7 @@ func (ef *GenericServiceFilter) OnResponse(ctx context.Context, result protocol. return result } -// GetGenericServiceFilter ... +// nolint func GetGenericServiceFilter() filter.Filter { return &GenericServiceFilter{} } diff --git a/filter/filter_impl/generic_service_filter_test.go b/filter/filter_impl/generic_service_filter_test.go index f0bdb7fb33..67819717cf 100644 --- a/filter/filter_impl/generic_service_filter_test.go +++ b/filter/filter_impl/generic_service_filter_test.go @@ -51,7 +51,7 @@ func (c *TestStruct) JavaClassName() string { type TestService struct{} -// MethodOne ... +// nolint func (ts *TestService) MethodOne(_ context.Context, test1 *TestStruct, test2 []TestStruct, test3 interface{}, test4 []interface{}, test5 *string) (*TestStruct, error) { if test1 == nil { @@ -72,7 +72,7 @@ func (ts *TestService) MethodOne(_ context.Context, test1 *TestStruct, test2 []T return &TestStruct{}, nil } -// Reference ... +// nolint func (*TestService) Reference() string { return "com.test.Path" } diff --git a/filter/filter_impl/hystrix_filter.go b/filter/filter_impl/hystrix_filter.go index 711ef71c44..e2275149f1 100644 --- a/filter/filter_impl/hystrix_filter.go +++ b/filter/filter_impl/hystrix_filter.go @@ -37,11 +37,11 @@ import ( ) const ( - // HYSTRIX_CONSUMER ... + // nolint HYSTRIX_CONSUMER = "hystrix_consumer" - // HYSTRIX_PROVIDER ... + // nolint HYSTRIX_PROVIDER = "hystrix_provider" - // HYSTRIX ... + // nolint HYSTRIX = "hystrix" ) @@ -85,14 +85,14 @@ func NewHystrixFilterError(err error, failByHystrix bool) error { } } -// HystrixFilter ... +// nolint type HystrixFilter struct { COrP bool //true for consumer res map[string][]*regexp.Regexp ifNewMap sync.Map } -// Invoke is an implentation of filter, provides Hystrix pattern latency and fault tolerance +// Invoke is an implementation of filter, provides Hystrix pattern latency and fault tolerance func (hf *HystrixFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { cmdName := fmt.Sprintf("%s&method=%s", invoker.GetUrl().Key(), invocation.MethodName()) @@ -256,7 +256,7 @@ func initHystrixConfigProvider() error { // return initHystrixConfig() //} -// CommandConfigWithError ... +// nolint type CommandConfigWithError struct { Timeout int `yaml:"timeout"` MaxConcurrentRequests int `yaml:"max_concurrent_requests"` @@ -274,14 +274,14 @@ type CommandConfigWithError struct { //- ErrorPercentThreshold: it causes circuits to open once the rolling measure of errors exceeds this percent of requests //See hystrix doc -// HystrixFilterConfig ... +// nolint type HystrixFilterConfig struct { Configs map[string]*CommandConfigWithError Default string Services map[string]ServiceHystrixConfig } -// ServiceHystrixConfig ... +// nolint type ServiceHystrixConfig struct { ServiceConfig string `yaml:"service_config"` Methods map[string]string diff --git a/filter/filter_impl/token_filter.go b/filter/filter_impl/token_filter.go index 23742c66e9..fe4e38747e 100644 --- a/filter/filter_impl/token_filter.go +++ b/filter/filter_impl/token_filter.go @@ -34,7 +34,7 @@ import ( ) const ( - // TOKEN ... + // nolint TOKEN = "token" ) @@ -66,7 +66,7 @@ func (tf *TokenFilter) OnResponse(ctx context.Context, result protocol.Result, i return result } -// GetTokenFilter ... +// nolint func GetTokenFilter() filter.Filter { return &TokenFilter{} } diff --git a/filter/filter_impl/tps/tps_limit_fix_window_strategy.go b/filter/filter_impl/tps/tps_limit_fix_window_strategy.go index 7419a45761..d495e035de 100644 --- a/filter/filter_impl/tps/tps_limit_fix_window_strategy.go +++ b/filter/filter_impl/tps/tps_limit_fix_window_strategy.go @@ -29,7 +29,7 @@ import ( ) const ( - // FixedWindowKey ... + // FixedWindowKey defines tps limit algorithm FixedWindowKey = "fixedWindow" ) diff --git a/filter/filter_impl/tps/tps_limit_strategy_mock.go b/filter/filter_impl/tps/tps_limit_strategy_mock.go index c228c7349c..3a1688e4d8 100644 --- a/filter/filter_impl/tps/tps_limit_strategy_mock.go +++ b/filter/filter_impl/tps/tps_limit_strategy_mock.go @@ -23,7 +23,10 @@ package tps import ( gomock "github.com/golang/mock/gomock" - reflect "reflect" +) + +import ( + "reflect" ) // MockTpsLimitStrategy is a mock of TpsLimitStrategy interface diff --git a/filter/filter_impl/tracing_filter_test.go b/filter/filter_impl/tracing_filter_test.go index 15dc32e7ec..57f4095d49 100644 --- a/filter/filter_impl/tracing_filter_test.go +++ b/filter/filter_impl/tracing_filter_test.go @@ -26,12 +26,9 @@ import ( "github.com/opentracing/opentracing-go" ) -import ( - "github.com/apache/dubbo-go/common/constant" -) - import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol/invocation" ) diff --git a/go.mod b/go.mod index e82a04b279..a16b906225 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/apache/dubbo-go require ( github.com/Workiva/go-datastructures v1.0.50 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 - github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 // indirect github.com/apache/dubbo-go-hessian2 v1.6.1 - github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible github.com/coreos/go-semver v0.3.0 // indirect diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go index 4689c6660b..9fdbd76757 100644 --- a/metadata/service/exporter/configurable/exporter_test.go +++ b/metadata/service/exporter/configurable/exporter_test.go @@ -97,13 +97,13 @@ func mockInitProviderWithSingleRegistry() { { Name: "GetUser", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, { Name: "GetUser1", Retries: "2", - Loadbalance: "random", + LoadBalance: "random", Weight: 200, }, }, diff --git a/protocol/dubbo/codec.go b/protocol/dubbo/codec.go index 1f7d107544..8ba725e3ce 100644 --- a/protocol/dubbo/codec.go +++ b/protocol/dubbo/codec.go @@ -54,10 +54,10 @@ const ( // dubbo package //////////////////////////////////////////// -// SequenceType ... +// SequenceType sequence type type SequenceType int64 -// DubboPackage ... +// nolint type DubboPackage struct { Header hessian.DubboHeader Service hessian.Service @@ -82,7 +82,7 @@ func (p *DubboPackage) Marshal() (*bytes.Buffer, error) { return bytes.NewBuffer(pkg), nil } -// Unmarshal dncode hessian package. +// Unmarshal decode hessian package. func (p *DubboPackage) Unmarshal(buf *bytes.Buffer, opts ...interface{}) error { // fix issue https://github.com/apache/dubbo-go/issues/380 bufLen := buf.Len() diff --git a/protocol/grpc/grpc_exporter.go b/protocol/grpc/grpc_exporter.go index 79962b59e2..0dc764854d 100644 --- a/protocol/grpc/grpc_exporter.go +++ b/protocol/grpc/grpc_exporter.go @@ -28,7 +28,7 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// GrpcExporter ... +// nolint type GrpcExporter struct { *protocol.BaseExporter } diff --git a/protocol/grpc/grpc_invoker.go b/protocol/grpc/grpc_invoker.go index e150d05e6f..737e8c40a0 100644 --- a/protocol/grpc/grpc_invoker.go +++ b/protocol/grpc/grpc_invoker.go @@ -37,14 +37,14 @@ import ( var errNoReply = errors.New("request need @response") -// GrpcInvoker ... +// nolint type GrpcInvoker struct { protocol.BaseInvoker quitOnce sync.Once client *Client } -// NewGrpcInvoker ... +// NewGrpcInvoker returns a Grpc invoker instance func NewGrpcInvoker(url common.URL, client *Client) *GrpcInvoker { return &GrpcInvoker{ BaseInvoker: *protocol.NewBaseInvoker(url), @@ -52,7 +52,7 @@ func NewGrpcInvoker(url common.URL, client *Client) *GrpcInvoker { } } -// Invoke ... +// Invoke is used to call service method by invocation func (gi *GrpcInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { var ( result protocol.RPCResult @@ -81,17 +81,17 @@ func (gi *GrpcInvoker) Invoke(ctx context.Context, invocation protocol.Invocatio return &result } -// IsAvailable ... +// IsAvailable get available status func (gi *GrpcInvoker) IsAvailable() bool { return gi.BaseInvoker.IsAvailable() && gi.client.GetState() != connectivity.Shutdown } -// IsDestroyed ... +// IsDestroyed get destroyed status func (gi *GrpcInvoker) IsDestroyed() bool { return gi.BaseInvoker.IsDestroyed() && gi.client.GetState() == connectivity.Shutdown } -// Destroy ... +// Destroy will destroy gRPC's invoker and client, so it is only called once func (gi *GrpcInvoker) Destroy() { gi.quitOnce.Do(func() { gi.BaseInvoker.Destroy() diff --git a/protocol/jsonrpc/http.go b/protocol/jsonrpc/http.go index 5fca66d993..2a2ddfeeeb 100644 --- a/protocol/jsonrpc/http.go +++ b/protocol/jsonrpc/http.go @@ -47,7 +47,7 @@ import ( // Request // //////////////////////////////////////////// -// Request ... +// Request is HTTP protocol request type Request struct { ID int64 group string diff --git a/protocol/jsonrpc/json.go b/protocol/jsonrpc/json.go index 7b05a22943..506c4c953b 100644 --- a/protocol/jsonrpc/json.go +++ b/protocol/jsonrpc/json.go @@ -288,7 +288,7 @@ type ServerCodec struct { var ( null = json.RawMessage([]byte("null")) - // Version ... + // Version is json RPC's version Version = "2.0" ) diff --git a/protocol/protocolwrapper/protocol_filter_wrapper.go b/protocol/protocolwrapper/protocol_filter_wrapper.go index cba1d5d5bc..87f90d3b7c 100644 --- a/protocol/protocolwrapper/protocol_filter_wrapper.go +++ b/protocol/protocolwrapper/protocol_filter_wrapper.go @@ -86,7 +86,7 @@ func buildInvokerChain(invoker protocol.Invoker, key string) protocol.Invoker { return next } -// GetProtocol ... +// nolint func GetProtocol() protocol.Protocol { return &ProtocolFilterWrapper{} } @@ -95,30 +95,30 @@ func GetProtocol() protocol.Protocol { // filter invoker /////////////////////////// -// FilterInvoker ... +// FilterInvoker defines invoker and filter type FilterInvoker struct { next protocol.Invoker invoker protocol.Invoker filter filter.Filter } -// GetUrl ... +// GetUrl is used to get url from FilterInvoker func (fi *FilterInvoker) GetUrl() common.URL { return fi.invoker.GetUrl() } -// IsAvailable ... +// IsAvailable is used to get available status func (fi *FilterInvoker) IsAvailable() bool { return fi.invoker.IsAvailable() } -// Invoke ... +// Invoke is used to call service method by invocation func (fi *FilterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { result := fi.filter.Invoke(ctx, fi.next, invocation) return fi.filter.OnResponse(ctx, result, fi.invoker, invocation) } -// Destroy ... +// Destroy will destroy invoker func (fi *FilterInvoker) Destroy() { fi.invoker.Destroy() } diff --git a/protocol/rest/config/rest_config.go b/protocol/rest/config/rest_config.go index 168ec8ce52..4732dd8e4e 100644 --- a/protocol/rest/config/rest_config.go +++ b/protocol/rest/config/rest_config.go @@ -26,7 +26,7 @@ var ( restProviderServiceConfigMap map[string]*RestServiceConfig ) -// RestConsumerConfig ... +// nolint type RestConsumerConfig struct { Client string `default:"resty" yaml:"rest_client" json:"rest_client,omitempty" property:"rest_client"` Produces string `default:"application/json" yaml:"rest_produces" json:"rest_produces,omitempty" property:"rest_produces"` @@ -34,7 +34,7 @@ type RestConsumerConfig struct { RestServiceConfigsMap map[string]*RestServiceConfig `yaml:"references" json:"references,omitempty" property:"references"` } -// UnmarshalYAML ... +// UnmarshalYAML unmarshals the RestConsumerConfig by @unmarshal function func (c *RestConsumerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := defaults.Set(c); err != nil { return err @@ -46,7 +46,7 @@ func (c *RestConsumerConfig) UnmarshalYAML(unmarshal func(interface{}) error) er return nil } -// RestProviderConfig ... +// nolint type RestProviderConfig struct { Server string `default:"go-restful" yaml:"rest_server" json:"rest_server,omitempty" property:"rest_server"` Produces string `default:"*/*" yaml:"rest_produces" json:"rest_produces,omitempty" property:"rest_produces"` @@ -54,7 +54,7 @@ type RestProviderConfig struct { RestServiceConfigsMap map[string]*RestServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` } -// UnmarshalYAML ... +// UnmarshalYAML unmarshals the RestProviderConfig by @unmarshal function func (c *RestProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := defaults.Set(c); err != nil { return err @@ -66,7 +66,7 @@ func (c *RestProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) er return nil } -// RestServiceConfig ... +// nolint type RestServiceConfig struct { InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"` Url string `yaml:"url" json:"url,omitempty" property:"url"` @@ -80,7 +80,7 @@ type RestServiceConfig struct { RestMethodConfigsMap map[string]*RestMethodConfig } -// UnmarshalYAML ... +// UnmarshalYAML unmarshals the RestServiceConfig by @unmarshal function func (c *RestServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := defaults.Set(c); err != nil { return err @@ -92,7 +92,7 @@ func (c *RestServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) err return nil } -// RestMethodConfig ... +// nolint type RestMethodConfig struct { InterfaceName string MethodName string `required:"true" yaml:"name" json:"name,omitempty" property:"name"` @@ -110,7 +110,7 @@ type RestMethodConfig struct { HeadersMap map[int]string } -// UnmarshalYAML ... +// UnmarshalYAML unmarshals the RestMethodConfig by @unmarshal function func (c *RestMethodConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := defaults.Set(c); err != nil { return err @@ -122,32 +122,32 @@ func (c *RestMethodConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro return nil } -// GetRestConsumerServiceConfig ... +// nolint func GetRestConsumerServiceConfig(path string) *RestServiceConfig { return restConsumerServiceConfigMap[path] } -// GetRestProviderServiceConfig ... +// nolint func GetRestProviderServiceConfig(path string) *RestServiceConfig { return restProviderServiceConfigMap[path] } -// SetRestConsumerServiceConfigMap ... +// nolint func SetRestConsumerServiceConfigMap(configMap map[string]*RestServiceConfig) { restConsumerServiceConfigMap = configMap } -// SetRestProviderServiceConfigMap ... +// nolint func SetRestProviderServiceConfigMap(configMap map[string]*RestServiceConfig) { restProviderServiceConfigMap = configMap } -// GetRestConsumerServiceConfigMap ... +// nolint func GetRestConsumerServiceConfigMap() map[string]*RestServiceConfig { return restConsumerServiceConfigMap } -// GetRestProviderServiceConfigMap ... +// nolint func GetRestProviderServiceConfigMap() map[string]*RestServiceConfig { return restProviderServiceConfigMap } diff --git a/protocol/rest/rest_exporter.go b/protocol/rest/rest_exporter.go index 1ee208615e..e39558caea 100644 --- a/protocol/rest/rest_exporter.go +++ b/protocol/rest/rest_exporter.go @@ -28,16 +28,19 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// nolint type RestExporter struct { protocol.BaseExporter } +// NewRestExporter returns a RestExporter func NewRestExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *RestExporter { return &RestExporter{ BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap), } } +// Unexport unexport the RestExporter func (re *RestExporter) Unexport() { serviceId := re.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") interfaceName := re.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "") diff --git a/protocol/rest/rest_invoker.go b/protocol/rest/rest_invoker.go index 121d1217ef..691beeda40 100644 --- a/protocol/rest/rest_invoker.go +++ b/protocol/rest/rest_invoker.go @@ -35,12 +35,14 @@ import ( "github.com/apache/dubbo-go/protocol/rest/config" ) +// nolint type RestInvoker struct { protocol.BaseInvoker client client.RestClient restMethodConfigMap map[string]*config.RestMethodConfig } +// NewRestInvoker returns a RestInvoker func NewRestInvoker(url common.URL, client *client.RestClient, restMethodConfig map[string]*config.RestMethodConfig) *RestInvoker { return &RestInvoker{ BaseInvoker: *protocol.NewBaseInvoker(url), @@ -49,6 +51,7 @@ func NewRestInvoker(url common.URL, client *client.RestClient, restMethodConfig } } +// Invoke is used to call service method by invocation func (ri *RestInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { inv := invocation.(*invocation_impl.RPCInvocation) methodConfig := ri.restMethodConfigMap[inv.MethodName()] @@ -95,6 +98,7 @@ func (ri *RestInvoker) Invoke(ctx context.Context, invocation protocol.Invocatio return &result } +// restStringMapTransform is used to transform rest map func restStringMapTransform(paramsMap map[int]string, args []interface{}) (map[string]string, error) { resMap := make(map[string]string, len(paramsMap)) for k, v := range paramsMap { @@ -106,6 +110,7 @@ func restStringMapTransform(paramsMap map[int]string, args []interface{}) (map[s return resMap, nil } +// nolint func getRestHttpHeader(methodConfig *config.RestMethodConfig, args []interface{}) (http.Header, error) { header := http.Header{} headersMap := methodConfig.HeadersMap diff --git a/protocol/rest/rest_protocol.go b/protocol/rest/rest_protocol.go index e15eeb39d7..0cd26c240a 100644 --- a/protocol/rest/rest_protocol.go +++ b/protocol/rest/rest_protocol.go @@ -44,10 +44,12 @@ var ( const REST = "rest" +// nolint func init() { extension.SetProtocol(REST, GetRestProtocol) } +// nolint type RestProtocol struct { protocol.BaseProtocol serverLock sync.Mutex @@ -56,6 +58,7 @@ type RestProtocol struct { clientMap map[client.RestOptions]client.RestClient } +// NewRestProtocol returns a RestProtocol func NewRestProtocol() *RestProtocol { return &RestProtocol{ BaseProtocol: protocol.NewBaseProtocol(), @@ -64,6 +67,7 @@ func NewRestProtocol() *RestProtocol { } } +// Export export rest service func (rp *RestProtocol) Export(invoker protocol.Invoker) protocol.Exporter { url := invoker.GetUrl() serviceKey := url.ServiceKey() @@ -81,6 +85,7 @@ func (rp *RestProtocol) Export(invoker protocol.Invoker) protocol.Exporter { return exporter } +// Refer create rest service reference func (rp *RestProtocol) Refer(url common.URL) protocol.Invoker { // create rest_invoker var requestTimeout = config.GetConsumerConfig().RequestTimeout @@ -101,6 +106,7 @@ func (rp *RestProtocol) Refer(url common.URL) protocol.Invoker { return invoker } +// nolint func (rp *RestProtocol) getServer(url common.URL, serverType string) server.RestServer { restServer, ok := rp.serverMap[url.Location] if ok { @@ -122,6 +128,7 @@ func (rp *RestProtocol) getServer(url common.URL, serverType string) server.Rest return restServer } +// nolint func (rp *RestProtocol) getClient(restOptions client.RestOptions, clientType string) client.RestClient { restClient, ok := rp.clientMap[restOptions] if ok { @@ -138,6 +145,7 @@ func (rp *RestProtocol) getClient(restOptions client.RestOptions, clientType str return restClient } +// Destroy destroy rest service func (rp *RestProtocol) Destroy() { // destroy rest_server rp.BaseProtocol.Destroy() @@ -150,6 +158,7 @@ func (rp *RestProtocol) Destroy() { } } +// GetRestProtocol get a rest protocol func GetRestProtocol() protocol.Protocol { if restProtocol == nil { restProtocol = NewRestProtocol() diff --git a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go index 949a5822c2..415ca35fba 100644 --- a/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go +++ b/registry/servicediscovery/synthesizer/subscribed_urls_synthesizer.go @@ -22,6 +22,7 @@ import ( "github.com/apache/dubbo-go/registry" ) +// SubscribedURLsSynthesizer is used to synthesize the subscribed url type SubscribedURLsSynthesizer interface { // Supports the synthesis of the subscribed url or not Support(subscribedURL *common.URL) bool diff --git a/remoting/listener.go b/remoting/listener.go index 6cbb883181..eb27c71dfd 100644 --- a/remoting/listener.go +++ b/remoting/listener.go @@ -48,6 +48,7 @@ var serviceEventTypeStrings = [...]string{ "update", } +// nolint func (t EventType) String() string { return serviceEventTypeStrings[t] } @@ -63,6 +64,7 @@ type Event struct { Content string } +// nolint func (e Event) String() string { return fmt.Sprintf("Event{Action{%s}, Content{%s}}", e.Action, e.Content) } From d3db7dab6fccd991d0b8a66aaee9f8dbf15e07aa Mon Sep 17 00:00:00 2001 From: lihaowei <2421565398@qq.com> Date: Sun, 19 Jul 2020 20:23:14 +0800 Subject: [PATCH 189/209] Imp: some improvements including add comments --- cluster/cluster_impl/broadcast_cluster.go | 1 + cluster/cluster_impl/failback_cluster.go | 1 + cluster/cluster_impl/failback_cluster_invoker.go | 1 + cluster/cluster_impl/failfast_cluster.go | 1 + cluster/cluster_impl/failfast_cluster_invoker.go | 1 + cluster/cluster_impl/failover_cluster.go | 1 + cluster/cluster_impl/failover_cluster_invoker.go | 1 + cluster/cluster_impl/failover_cluster_test.go | 15 +++++++++++++++ cluster/cluster_impl/failsafe_cluster.go | 1 + cluster/cluster_impl/failsafe_cluster_invoker.go | 1 + cluster/cluster_impl/forking_cluster.go | 1 + cluster/cluster_impl/forking_cluster_invoker.go | 2 +- cluster/cluster_impl/mock_cluster.go | 1 + cluster/cluster_impl/registry_aware_cluster.go | 1 + .../registry_aware_cluster_invoker.go | 1 + cluster/loadbalance/consistent_hash.go | 1 + cluster/loadbalance/least_active.go | 1 + cluster/loadbalance/round_robin.go | 1 + cluster/router/healthcheck/factory_test.go | 9 +++++++++ cluster/router/tag/tag_router.go | 8 ++++++++ 20 files changed, 49 insertions(+), 1 deletion(-) diff --git a/cluster/cluster_impl/broadcast_cluster.go b/cluster/cluster_impl/broadcast_cluster.go index ba454af6a8..024cf4f533 100644 --- a/cluster/cluster_impl/broadcast_cluster.go +++ b/cluster/cluster_impl/broadcast_cluster.go @@ -39,6 +39,7 @@ func NewBroadcastCluster() cluster.Cluster { return &broadcastCluster{} } +// Join would return baseClusterInvoker instance func (cluster *broadcastCluster) Join(directory cluster.Directory) protocol.Invoker { return newBroadcastClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failback_cluster.go b/cluster/cluster_impl/failback_cluster.go index 432e33122c..589b6bfc46 100644 --- a/cluster/cluster_impl/failback_cluster.go +++ b/cluster/cluster_impl/failback_cluster.go @@ -39,6 +39,7 @@ func NewFailbackCluster() cluster.Cluster { return &failbackCluster{} } +// Join would return baseClusterInvoker instance func (cluster *failbackCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailbackClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failback_cluster_invoker.go b/cluster/cluster_impl/failback_cluster_invoker.go index af17a93756..62f48045ec 100644 --- a/cluster/cluster_impl/failback_cluster_invoker.go +++ b/cluster/cluster_impl/failback_cluster_invoker.go @@ -126,6 +126,7 @@ func (invoker *failbackClusterInvoker) checkRetry(retryTask *retryTimerTask, err } } +// nolint func (invoker *failbackClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { invokers := invoker.directory.List(invocation) if err := invoker.checkInvokers(invokers, invocation); err != nil { diff --git a/cluster/cluster_impl/failfast_cluster.go b/cluster/cluster_impl/failfast_cluster.go index ac9ec6b821..d8b7e9543b 100644 --- a/cluster/cluster_impl/failfast_cluster.go +++ b/cluster/cluster_impl/failfast_cluster.go @@ -39,6 +39,7 @@ func NewFailFastCluster() cluster.Cluster { return &failfastCluster{} } +// Join would return baseClusterInvoker instance func (cluster *failfastCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailFastClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failfast_cluster_invoker.go b/cluster/cluster_impl/failfast_cluster_invoker.go index 3b4dc9b721..d71ef5f5a1 100644 --- a/cluster/cluster_impl/failfast_cluster_invoker.go +++ b/cluster/cluster_impl/failfast_cluster_invoker.go @@ -35,6 +35,7 @@ func newFailFastClusterInvoker(directory cluster.Directory) protocol.Invoker { } } +// nolint func (invoker *failfastClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { invokers := invoker.directory.List(invocation) err := invoker.checkInvokers(invokers, invocation) diff --git a/cluster/cluster_impl/failover_cluster.go b/cluster/cluster_impl/failover_cluster.go index d30a743e03..ecc3596f8a 100644 --- a/cluster/cluster_impl/failover_cluster.go +++ b/cluster/cluster_impl/failover_cluster.go @@ -40,6 +40,7 @@ func NewFailoverCluster() cluster.Cluster { return &failoverCluster{} } +// Join would return baseClusterInvoker instance func (cluster *failoverCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailoverClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go index 66adabd104..2ce393cc3c 100644 --- a/cluster/cluster_impl/failover_cluster_invoker.go +++ b/cluster/cluster_impl/failover_cluster_invoker.go @@ -44,6 +44,7 @@ func newFailoverClusterInvoker(directory cluster.Directory) protocol.Invoker { } } +// nolint func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { var ( result protocol.Result diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go index e05b79202c..d3ac2c8a5f 100644 --- a/cluster/cluster_impl/failover_cluster_test.go +++ b/cluster/cluster_impl/failover_cluster_test.go @@ -43,6 +43,7 @@ import ( // mock invoker // /////////////////////////// +// nolint type MockInvoker struct { url common.URL available bool @@ -51,6 +52,7 @@ type MockInvoker struct { successCount int } +// nolint func NewMockInvoker(url common.URL, successCount int) *MockInvoker { return &MockInvoker{ url: url, @@ -60,23 +62,28 @@ func NewMockInvoker(url common.URL, successCount int) *MockInvoker { } } +// nolint func (bi *MockInvoker) GetUrl() common.URL { return bi.url } +// nolint func (bi *MockInvoker) IsAvailable() bool { return bi.available } +// nolint func (bi *MockInvoker) IsDestroyed() bool { return bi.destroyed } +// nolint type rest struct { tried int success bool } +// nolint func (bi *MockInvoker) Invoke(c context.Context, invocation protocol.Invocation) protocol.Result { count++ var ( @@ -93,14 +100,17 @@ func (bi *MockInvoker) Invoke(c context.Context, invocation protocol.Invocation) return result } +// nolint func (bi *MockInvoker) Destroy() { logger.Infof("Destroy invoker: %v", bi.GetUrl().String()) bi.destroyed = true bi.available = false } +// nolint var count int +// nolint func normalInvoke(successCount int, urlParam url.Values, invocations ...*invocation.RPCInvocation) protocol.Result { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failoverCluster := NewFailoverCluster() @@ -119,6 +129,7 @@ func normalInvoke(successCount int, urlParam url.Values, invocations ...*invocat return clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) } +// nolint func TestFailoverInvokeSuccess(t *testing.T) { urlParams := url.Values{} result := normalInvoke(3, urlParams) @@ -126,6 +137,7 @@ func TestFailoverInvokeSuccess(t *testing.T) { count = 0 } +// nolint func TestFailoverInvokeFail(t *testing.T) { urlParams := url.Values{} result := normalInvoke(4, urlParams) @@ -133,6 +145,7 @@ func TestFailoverInvokeFail(t *testing.T) { count = 0 } +// nolint func TestFailoverInvoke1(t *testing.T) { urlParams := url.Values{} urlParams.Set(constant.RETRIES_KEY, "3") @@ -141,6 +154,7 @@ func TestFailoverInvoke1(t *testing.T) { count = 0 } +// nolint func TestFailoverInvoke2(t *testing.T) { urlParams := url.Values{} urlParams.Set(constant.RETRIES_KEY, "2") @@ -152,6 +166,7 @@ func TestFailoverInvoke2(t *testing.T) { count = 0 } +// nolint func TestFailoverDestroy(t *testing.T) { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failoverCluster := NewFailoverCluster() diff --git a/cluster/cluster_impl/failsafe_cluster.go b/cluster/cluster_impl/failsafe_cluster.go index f708b7fb91..25f42dd0a9 100644 --- a/cluster/cluster_impl/failsafe_cluster.go +++ b/cluster/cluster_impl/failsafe_cluster.go @@ -39,6 +39,7 @@ func NewFailsafeCluster() cluster.Cluster { return &failsafeCluster{} } +// Join would return baseClusterInvoker instance func (cluster *failsafeCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailsafeClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failsafe_cluster_invoker.go b/cluster/cluster_impl/failsafe_cluster_invoker.go index 4d8fe27719..27c59fff18 100644 --- a/cluster/cluster_impl/failsafe_cluster_invoker.go +++ b/cluster/cluster_impl/failsafe_cluster_invoker.go @@ -45,6 +45,7 @@ func newFailsafeClusterInvoker(directory cluster.Directory) protocol.Invoker { } } +// nolint func (invoker *failsafeClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { invokers := invoker.directory.List(invocation) diff --git a/cluster/cluster_impl/forking_cluster.go b/cluster/cluster_impl/forking_cluster.go index 0e6cd26882..9dd366d0b5 100644 --- a/cluster/cluster_impl/forking_cluster.go +++ b/cluster/cluster_impl/forking_cluster.go @@ -39,6 +39,7 @@ func NewForkingCluster() cluster.Cluster { return &forkingCluster{} } +// Join would return baseClusterInvoker instance func (cluster *forkingCluster) Join(directory cluster.Directory) protocol.Invoker { return newForkingClusterInvoker(directory) } diff --git a/cluster/cluster_impl/forking_cluster_invoker.go b/cluster/cluster_impl/forking_cluster_invoker.go index a5a3f2ec66..1684448816 100644 --- a/cluster/cluster_impl/forking_cluster_invoker.go +++ b/cluster/cluster_impl/forking_cluster_invoker.go @@ -44,7 +44,7 @@ func newForkingClusterInvoker(directory cluster.Directory) protocol.Invoker { } } -// Invoke ... +// nolint func (invoker *forkingClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { if err := invoker.checkWhetherDestroyed(); err != nil { return &protocol.RPCResult{Err: err} diff --git a/cluster/cluster_impl/mock_cluster.go b/cluster/cluster_impl/mock_cluster.go index d887cfb45b..a7fa5d4f02 100644 --- a/cluster/cluster_impl/mock_cluster.go +++ b/cluster/cluster_impl/mock_cluster.go @@ -33,6 +33,7 @@ func NewMockCluster() cluster.Cluster { return &mockCluster{} } +// nolint func (cluster *mockCluster) Join(directory cluster.Directory) protocol.Invoker { return protocol.NewBaseInvoker(directory.GetUrl()) } diff --git a/cluster/cluster_impl/registry_aware_cluster.go b/cluster/cluster_impl/registry_aware_cluster.go index fcefa52862..f4c0897371 100644 --- a/cluster/cluster_impl/registry_aware_cluster.go +++ b/cluster/cluster_impl/registry_aware_cluster.go @@ -34,6 +34,7 @@ func NewRegistryAwareCluster() cluster.Cluster { return ®istryAwareCluster{} } +// nolint func (cluster *registryAwareCluster) Join(directory cluster.Directory) protocol.Invoker { return newRegistryAwareClusterInvoker(directory) } diff --git a/cluster/cluster_impl/registry_aware_cluster_invoker.go b/cluster/cluster_impl/registry_aware_cluster_invoker.go index cded5bf164..7840da5218 100644 --- a/cluster/cluster_impl/registry_aware_cluster_invoker.go +++ b/cluster/cluster_impl/registry_aware_cluster_invoker.go @@ -36,6 +36,7 @@ func newRegistryAwareClusterInvoker(directory cluster.Directory) protocol.Invoke } } +// nolint func (invoker *registryAwareClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { invokers := invoker.directory.List(invocation) //First, pick the invoker (XXXClusterInvoker) that comes from the local registry, distinguish by a 'default' key. diff --git a/cluster/loadbalance/consistent_hash.go b/cluster/loadbalance/consistent_hash.go index 84fbb268c7..3266b4f11c 100644 --- a/cluster/loadbalance/consistent_hash.go +++ b/cluster/loadbalance/consistent_hash.go @@ -157,6 +157,7 @@ func (c *ConsistentHashSelector) selectForKey(hash uint32) protocol.Invoker { return c.virtualInvokers[c.keys[idx]] } +// nolint func (c *ConsistentHashSelector) hash(digest [16]byte, i int) uint32 { return uint32((digest[3+i*4]&0xFF)<<24) | uint32((digest[2+i*4]&0xFF)<<16) | uint32((digest[1+i*4]&0xFF)<<8) | uint32(digest[i*4]&0xFF)&0xFFFFFFF diff --git a/cluster/loadbalance/least_active.go b/cluster/loadbalance/least_active.go index 37ad91c3ed..87767359a9 100644 --- a/cluster/loadbalance/least_active.go +++ b/cluster/loadbalance/least_active.go @@ -46,6 +46,7 @@ func NewLeastActiveLoadBalance() cluster.LoadBalance { return &leastActiveLoadBalance{} } +// Select gets invoker based on least active load balancing strategy func (lb *leastActiveLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker { count := len(invokers) if count == 0 { diff --git a/cluster/loadbalance/round_robin.go b/cluster/loadbalance/round_robin.go index c44b239dbc..8d1324e27a 100644 --- a/cluster/loadbalance/round_robin.go +++ b/cluster/loadbalance/round_robin.go @@ -59,6 +59,7 @@ func NewRoundRobinLoadBalance() cluster.LoadBalance { return &roundRobinLoadBalance{} } +// Select gets invoker based on round robin load balancing strategy func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker { count := len(invokers) if count == 0 { diff --git a/cluster/router/healthcheck/factory_test.go b/cluster/router/healthcheck/factory_test.go index c3a26a9389..e80fd4c4d3 100644 --- a/cluster/router/healthcheck/factory_test.go +++ b/cluster/router/healthcheck/factory_test.go @@ -31,34 +31,43 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// nolint type MockInvoker struct { url common.URL } +// nolint func NewMockInvoker(url common.URL) *MockInvoker { return &MockInvoker{ url: url, } } +// nolint func (bi *MockInvoker) GetUrl() common.URL { return bi.url } + +// nolint func (bi *MockInvoker) IsAvailable() bool { return true } +// nolint func (bi *MockInvoker) IsDestroyed() bool { return true } +// nolint func (bi *MockInvoker) Invoke(_ context.Context, _ protocol.Invocation) protocol.Result { return nil } +// nolint func (bi *MockInvoker) Destroy() { } +// nolint func TestHealthCheckRouteFactory(t *testing.T) { factory := newHealthCheckRouteFactory() assert.NotNil(t, factory) diff --git a/cluster/router/tag/tag_router.go b/cluster/router/tag/tag_router.go index 87da418943..74f51075c7 100644 --- a/cluster/router/tag/tag_router.go +++ b/cluster/router/tag/tag_router.go @@ -31,12 +31,14 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// tagRouter defines url, enable and the priority type tagRouter struct { url *common.URL enabled bool priority int64 } +// NewTagRouter would return tagRouter instance if url is not nil func NewTagRouter(url *common.URL) (*tagRouter, error) { if url == nil { return nil, perrors.Errorf("Illegal route URL!") @@ -48,10 +50,12 @@ func NewTagRouter(url *common.URL) (*tagRouter, error) { }, nil } +// nolint func (c *tagRouter) isEnabled() bool { return c.enabled } +// Route gets a list of invoker func (c *tagRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker { if !c.isEnabled() { return invokers @@ -62,14 +66,17 @@ func (c *tagRouter) Route(invokers []protocol.Invoker, url *common.URL, invocati return filterUsingStaticTag(invokers, url, invocation) } +// URL gets the url of tagRouter func (c *tagRouter) URL() common.URL { return *c.url } +// Priority gets the priority of tagRouter func (c *tagRouter) Priority() int64 { return c.priority } +// filterUsingStaticTag gets a list of invoker using static tag func filterUsingStaticTag(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker { if tag, ok := invocation.Attachments()[constant.Tagkey]; ok { result := make([]protocol.Invoker, 0, 8) @@ -86,6 +93,7 @@ func filterUsingStaticTag(invokers []protocol.Invoker, url *common.URL, invocati return invokers } +// isForceUseTag returns whether force use tag func isForceUseTag(url *common.URL, invocation protocol.Invocation) bool { if b, e := strconv.ParseBool(invocation.AttachmentsByKey(constant.ForceUseTag, url.GetParam(constant.ForceUseTag, "false"))); e == nil { return b From 892d8593d45881b8e732547c2e9cfdc4392cac5e Mon Sep 17 00:00:00 2001 From: lihaowei <2421565398@qq.com> Date: Sun, 19 Jul 2020 20:32:24 +0800 Subject: [PATCH 190/209] Imp: three improvements --- config_center/apollo/factory.go | 2 +- filter/filter_impl/echo_filter.go | 2 +- filter/filter_impl/tps/tps_limit_strategy_mock.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config_center/apollo/factory.go b/config_center/apollo/factory.go index 8d873eaabc..c52d942c4f 100644 --- a/config_center/apollo/factory.go +++ b/config_center/apollo/factory.go @@ -34,7 +34,7 @@ func createDynamicConfigurationFactory() config_center.DynamicConfigurationFacto type apolloConfigurationFactory struct{} -// GetDynamicConfiguration returns the dynamic configuration +// GetDynamicConfiguration gets the dynamic configuration func (f *apolloConfigurationFactory) GetDynamicConfiguration(url *common.URL) (config_center.DynamicConfiguration, error) { dynamicConfiguration, err := newApolloConfiguration(url) if err != nil { diff --git a/filter/filter_impl/echo_filter.go b/filter/filter_impl/echo_filter.go index 06e443e807..24ba6e47ac 100644 --- a/filter/filter_impl/echo_filter.go +++ b/filter/filter_impl/echo_filter.go @@ -65,7 +65,7 @@ func (ef *EchoFilter) OnResponse(_ context.Context, result protocol.Result, _ pr return result } -// GetFilter returns the Filter +// GetFilter gets the Filter func GetFilter() filter.Filter { return &EchoFilter{} } diff --git a/filter/filter_impl/tps/tps_limit_strategy_mock.go b/filter/filter_impl/tps/tps_limit_strategy_mock.go index 3a1688e4d8..be76466092 100644 --- a/filter/filter_impl/tps/tps_limit_strategy_mock.go +++ b/filter/filter_impl/tps/tps_limit_strategy_mock.go @@ -26,7 +26,7 @@ import ( ) import ( - "reflect" + reflect "reflect" ) // MockTpsLimitStrategy is a mock of TpsLimitStrategy interface From 5868ed12d8cbb831a5c6324783dda9a8f7236e39 Mon Sep 17 00:00:00 2001 From: lihaowei <2421565398@qq.com> Date: Sun, 19 Jul 2020 20:48:35 +0800 Subject: [PATCH 191/209] Imp: three improvements --- cluster/loadbalance/consistent_hash.go | 4 ++-- cluster/loadbalance/round_robin.go | 6 +++--- config_center/apollo/listener.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cluster/loadbalance/consistent_hash.go b/cluster/loadbalance/consistent_hash.go index 3266b4f11c..85eb96417c 100644 --- a/cluster/loadbalance/consistent_hash.go +++ b/cluster/loadbalance/consistent_hash.go @@ -38,9 +38,9 @@ import ( ) const ( - // ConsistentHash ... + // ConsistentHash consistent hash ConsistentHash = "consistenthash" - // HashNodes ... + // HashNodes hash nodes HashNodes = "hash.nodes" // HashArguments key of hash arguments in url HashArguments = "hash.arguments" diff --git a/cluster/loadbalance/round_robin.go b/cluster/loadbalance/round_robin.go index 8d1324e27a..51a76da998 100644 --- a/cluster/loadbalance/round_robin.go +++ b/cluster/loadbalance/round_robin.go @@ -31,12 +31,12 @@ import ( ) const ( - // RoundRobin ... + // RoundRobin load balancing way RoundRobin = "roundrobin" - // COMPLETE ... + // nolint COMPLETE = 0 - // UPDATING ... + // nolint UPDATING = 1 ) diff --git a/config_center/apollo/listener.go b/config_center/apollo/listener.go index 1cf65ed22b..48a35093d2 100644 --- a/config_center/apollo/listener.go +++ b/config_center/apollo/listener.go @@ -36,7 +36,7 @@ func NewApolloListener() *apolloListener { } } -// OnChange ... +// OnChange process each listener func (a *apolloListener) OnChange(changeEvent *agollo.ChangeEvent) { for key, change := range changeEvent.Changes { for listener := range a.listeners { From 53f2b372c5e6778b851a546f5f76e49a13b3d730 Mon Sep 17 00:00:00 2001 From: lihaowei <2421565398@qq.com> Date: Sun, 19 Jul 2020 21:42:14 +0800 Subject: [PATCH 192/209] Imp: replace 'would return' to returns xxx --- cluster/cluster_impl/available_cluster.go | 1 + cluster/cluster_impl/broadcast_cluster.go | 2 +- cluster/cluster_impl/failback_cluster.go | 2 +- cluster/cluster_impl/failfast_cluster.go | 2 +- cluster/cluster_impl/failover_cluster.go | 2 +- cluster/cluster_impl/failsafe_cluster.go | 2 +- cluster/cluster_impl/forking_cluster.go | 2 +- cluster/router/tag/tag_router.go | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cluster/cluster_impl/available_cluster.go b/cluster/cluster_impl/available_cluster.go index b70a97fad2..ebd5767e4c 100644 --- a/cluster/cluster_impl/available_cluster.go +++ b/cluster/cluster_impl/available_cluster.go @@ -38,6 +38,7 @@ func NewAvailableCluster() cluster.Cluster { return &availableCluster{} } +// Join returns a baseClusterInvoker instance func (cluser *availableCluster) Join(directory cluster.Directory) protocol.Invoker { return NewAvailableClusterInvoker(directory) } diff --git a/cluster/cluster_impl/broadcast_cluster.go b/cluster/cluster_impl/broadcast_cluster.go index 024cf4f533..ea3dee9218 100644 --- a/cluster/cluster_impl/broadcast_cluster.go +++ b/cluster/cluster_impl/broadcast_cluster.go @@ -39,7 +39,7 @@ func NewBroadcastCluster() cluster.Cluster { return &broadcastCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *broadcastCluster) Join(directory cluster.Directory) protocol.Invoker { return newBroadcastClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failback_cluster.go b/cluster/cluster_impl/failback_cluster.go index 589b6bfc46..278ac5432e 100644 --- a/cluster/cluster_impl/failback_cluster.go +++ b/cluster/cluster_impl/failback_cluster.go @@ -39,7 +39,7 @@ func NewFailbackCluster() cluster.Cluster { return &failbackCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *failbackCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailbackClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failfast_cluster.go b/cluster/cluster_impl/failfast_cluster.go index d8b7e9543b..a5ea7a0585 100644 --- a/cluster/cluster_impl/failfast_cluster.go +++ b/cluster/cluster_impl/failfast_cluster.go @@ -39,7 +39,7 @@ func NewFailFastCluster() cluster.Cluster { return &failfastCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *failfastCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailFastClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failover_cluster.go b/cluster/cluster_impl/failover_cluster.go index ecc3596f8a..254cc097e3 100644 --- a/cluster/cluster_impl/failover_cluster.go +++ b/cluster/cluster_impl/failover_cluster.go @@ -40,7 +40,7 @@ func NewFailoverCluster() cluster.Cluster { return &failoverCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *failoverCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailoverClusterInvoker(directory) } diff --git a/cluster/cluster_impl/failsafe_cluster.go b/cluster/cluster_impl/failsafe_cluster.go index 25f42dd0a9..d9465c034c 100644 --- a/cluster/cluster_impl/failsafe_cluster.go +++ b/cluster/cluster_impl/failsafe_cluster.go @@ -39,7 +39,7 @@ func NewFailsafeCluster() cluster.Cluster { return &failsafeCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *failsafeCluster) Join(directory cluster.Directory) protocol.Invoker { return newFailsafeClusterInvoker(directory) } diff --git a/cluster/cluster_impl/forking_cluster.go b/cluster/cluster_impl/forking_cluster.go index 9dd366d0b5..8c99113275 100644 --- a/cluster/cluster_impl/forking_cluster.go +++ b/cluster/cluster_impl/forking_cluster.go @@ -39,7 +39,7 @@ func NewForkingCluster() cluster.Cluster { return &forkingCluster{} } -// Join would return baseClusterInvoker instance +// Join returns a baseClusterInvoker instance func (cluster *forkingCluster) Join(directory cluster.Directory) protocol.Invoker { return newForkingClusterInvoker(directory) } diff --git a/cluster/router/tag/tag_router.go b/cluster/router/tag/tag_router.go index 74f51075c7..e1376fd96a 100644 --- a/cluster/router/tag/tag_router.go +++ b/cluster/router/tag/tag_router.go @@ -38,7 +38,7 @@ type tagRouter struct { priority int64 } -// NewTagRouter would return tagRouter instance if url is not nil +// NewTagRouter returns a tagRouter instance if url is not nil func NewTagRouter(url *common.URL) (*tagRouter, error) { if url == nil { return nil, perrors.Errorf("Illegal route URL!") From e59c00b1af96544230243dfb2f88b8f14d2968a1 Mon Sep 17 00:00:00 2001 From: lzp0412 <641785844@qq.com> Date: Tue, 21 Jul 2020 19:32:08 +0800 Subject: [PATCH 193/209] solve nacos unit test failed --- registry/nacos/service_discovery_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 720c44a6f9..4b069c2e82 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -18,7 +18,10 @@ package nacos import ( + "math/rand" + "strconv" "testing" + "time" ) import ( @@ -84,8 +87,8 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { }) extension.SetAndInitGlobalDispatcher("mock") - - serviceName := "service-name" + rand.Seed(time.Now().Unix()) + serviceName := "service-name" + strconv.Itoa(rand.Intn(10000)) id := "id" host := "host" port := 123 @@ -113,7 +116,9 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { err := serviceDiscovry.Register(instance) assert.Nil(t, err) - + //sometimes nacos may be failed to push update of instance, + //so it need 10s to pull, we sleep 10 second to make sure instance has been update + time.Sleep(11 * time.Second) page := serviceDiscovry.GetHealthyInstancesByPage(serviceName, 0, 10, true) assert.NotNil(t, page) From ea57c44e7dca4d4da2f29f25d46826a057980463 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Thu, 23 Jul 2020 12:07:26 +0800 Subject: [PATCH 194/209] code format --- remoting/etcdv3/client.go | 128 ++++++++++---------------------------- 1 file changed, 32 insertions(+), 96 deletions(-) diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index 7632a7cd04..a2a5764538 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -35,7 +35,7 @@ import ( ) const ( - // ConnDelay connection dalay + // ConnDelay connection delay ConnDelay = 3 // MaxFailTimes max failure times MaxFailTimes = 15 @@ -93,7 +93,6 @@ func WithHeartbeat(heartbeat int) Option { // ValidateClient validates client and sets options func ValidateClient(container clientFacade, opts ...Option) error { - options := &Options{ heartbeat: 1, // default heartbeat } @@ -118,7 +117,6 @@ func ValidateClient(container clientFacade, opts ...Option) error { // Client lose connection with etcd server if container.Client().rawClient == nil { - newClient, err := NewClient(options.name, options.endpoints, options.timeout, options.heartbeat) if err != nil { logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", @@ -136,7 +134,6 @@ func NewServiceDiscoveryClient(opts ...Option) *Client { options := &Options{ heartbeat: 1, // default heartbeat } - for _, opt := range opts { opt(options) } @@ -171,7 +168,6 @@ type Client struct { // nolint func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat int) (*Client, error) { - ctx, cancel := context.WithCancel(context.Background()) rawClient, err := clientv3.New(clientv3.Config{ Context: ctx, @@ -184,7 +180,6 @@ func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat } c := &Client{ - name: name, timeout: timeout, endpoints: endpoints, @@ -205,7 +200,6 @@ func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat // NOTICE: need to get the lock before calling this method func (c *Client) clean() { - // close raw client c.rawClient.Close() @@ -217,7 +211,6 @@ func (c *Client) clean() { } func (c *Client) stop() bool { - select { case <-c.exit: return true @@ -229,7 +222,6 @@ func (c *Client) stop() bool { // nolint func (c *Client) Close() { - if c == nil { return } @@ -241,15 +233,14 @@ func (c *Client) Close() { c.Wait.Wait() c.lock.Lock() + defer c.lock.Unlock() if c.rawClient != nil { c.clean() } - c.lock.Unlock() logger.Warnf("etcd client{name:%s, endpoints:%s} exit now.", c.name, c.endpoints) } func (c *Client) maintenanceStatus() error { - s, err := concurrency.NewSession(c.rawClient, concurrency.WithTTL(c.heartbeat)) if err != nil { return perrors.WithMessage(err, "new session with server") @@ -262,7 +253,6 @@ func (c *Client) maintenanceStatus() error { } func (c *Client) maintenanceStatusLoop(s *concurrency.Session) { - defer func() { c.Wait.Done() logger.Infof("etcd client {endpoints:%v, name:%s} maintenance goroutine game over.", c.endpoints, c.name) @@ -288,7 +278,6 @@ func (c *Client) maintenanceStatusLoop(s *concurrency.Session) { // if k not exist will put k/v in etcd, otherwise return nil func (c *Client) put(k string, v string, opts ...clientv3.OpOption) error { - c.lock.RLock() defer c.lock.RUnlock() @@ -300,17 +289,12 @@ func (c *Client) put(k string, v string, opts ...clientv3.OpOption) error { If(clientv3.Compare(clientv3.Version(k), "<", 1)). Then(clientv3.OpPut(k, v, opts...)). Commit() - if err != nil { - return err - - } - return nil + return err } // if k not exist will put k/v in etcd // if k is already exist in etcd, replace it func (c *Client) update(k string, v string, opts ...clientv3.OpOption) error { - c.lock.RLock() defer c.lock.RUnlock() @@ -322,15 +306,10 @@ func (c *Client) update(k string, v string, opts ...clientv3.OpOption) error { If(clientv3.Compare(clientv3.Version(k), "!=", -1)). Then(clientv3.OpPut(k, v, opts...)). Commit() - if err != nil { - return err - - } - return nil + return err } func (c *Client) delete(k string) error { - c.lock.RLock() defer c.lock.RUnlock() @@ -339,15 +318,10 @@ func (c *Client) delete(k string) error { } _, err := c.rawClient.Delete(c.ctx, k) - if err != nil { - return err - - } - return nil + return err } func (c *Client) get(k string) (string, error) { - c.lock.RLock() defer c.lock.RUnlock() @@ -369,7 +343,6 @@ func (c *Client) get(k string) (string, error) { // nolint func (c *Client) CleanKV() error { - c.lock.RLock() defer c.lock.RUnlock() @@ -378,15 +351,10 @@ func (c *Client) CleanKV() error { } _, err := c.rawClient.Delete(c.ctx, "", clientv3.WithPrefix()) - if err != nil { - return err - } - - return nil + return err } func (c *Client) getChildren(k string) ([]string, []string, error) { - c.lock.RLock() defer c.lock.RUnlock() @@ -403,21 +371,16 @@ func (c *Client) getChildren(k string) ([]string, []string, error) { return nil, nil, ErrKVPairNotFound } - var ( - kList []string - vList []string - ) - + kList := make([]string, 0, len(resp.Kvs)) + vList := make([]string, 0, len(resp.Kvs)) for _, kv := range resp.Kvs { kList = append(kList, string(kv.Key)) vList = append(vList, string(kv.Value)) } - return kList, vList, nil } func (c *Client) watchWithPrefix(prefix string) (clientv3.WatchChan, error) { - c.lock.RLock() defer c.lock.RUnlock() @@ -429,7 +392,6 @@ func (c *Client) watchWithPrefix(prefix string) (clientv3.WatchChan, error) { } func (c *Client) watch(k string) (clientv3.WatchChan, error) { - c.lock.RLock() defer c.lock.RUnlock() @@ -441,7 +403,6 @@ func (c *Client) watch(k string) (clientv3.WatchChan, error) { } func (c *Client) keepAliveKV(k string, v string) error { - c.lock.RLock() defer c.lock.RUnlock() @@ -457,14 +418,16 @@ func (c *Client) keepAliveKV(k string, v string) error { keepAlive, err := c.rawClient.KeepAlive(c.ctx, lease.ID) if err != nil || keepAlive == nil { c.rawClient.Revoke(c.ctx, lease.ID) - return perrors.WithMessage(err, "keep alive lease") + if err != nil { + return perrors.WithMessage(err, "keep alive lease") + } else { + return perrors.New("keep alive lease") + } } _, err = c.rawClient.Put(c.ctx, k, v, clientv3.WithLease(lease.ID)) - if err != nil { - return perrors.WithMessage(err, "put k/v with lease") - } - return nil + err = perrors.WithMessage(err, "put k/v with lease") + return err } // nolint @@ -481,92 +444,65 @@ func (c *Client) Valid() bool { } c.lock.RLock() + defer c.lock.RUnlock() if c.rawClient == nil { - c.lock.RUnlock() return false } - c.lock.RUnlock() return true } // nolint func (c *Client) Create(k string, v string) error { - err := c.put(k, v) - if err != nil { - return perrors.WithMessagef(err, "put k/v (key: %s value %s)", k, v) - } - return nil + err = perrors.WithMessagef(err, "put k/v (key: %s value %s)", k, v) + return err } // Update key value ... func (c *Client) Update(k, v string) error { err := c.update(k, v) - if err != nil { - return perrors.WithMessagef(err, "Update k/v (key: %s value %s)", k, v) - } - return nil + err = perrors.WithMessagef(err, "Update k/v (key: %s value %s)", k, v) + return err } // nolint func (c *Client) Delete(k string) error { - err := c.delete(k) - if err != nil { - return perrors.WithMessagef(err, "delete k/v (key %s)", k) - } - - return nil + err = perrors.WithMessagef(err, "delete k/v (key %s)", k) + return err } // RegisterTemp registers a temporary node func (c *Client) RegisterTemp(k, v string) error { - err := c.keepAliveKV(k, v) - if err != nil { - return perrors.WithMessagef(err, "keepalive kv (key %s)", k) - } - - return nil + err = perrors.WithMessagef(err, "keepalive kv (key %s)", k) + return err } // GetChildrenKVList gets children kv list by @k func (c *Client) GetChildrenKVList(k string) ([]string, []string, error) { - kList, vList, err := c.getChildren(k) - if err != nil { - return nil, nil, perrors.WithMessagef(err, "get key children (key %s)", k) - } - return kList, vList, nil + err = perrors.WithMessagef(err, "get key children (key %s)", k) + return kList, vList, err } // Get gets value by @k func (c *Client) Get(k string) (string, error) { - v, err := c.get(k) - if err != nil { - return "", perrors.WithMessagef(err, "get key value (key %s)", k) - } - - return v, nil + err = perrors.WithMessagef(err, "get key value (key %s)", k) + return v, err } // Watch watches on spec key func (c *Client) Watch(k string) (clientv3.WatchChan, error) { - wc, err := c.watch(k) - if err != nil { - return nil, perrors.WithMessagef(err, "watch prefix (key %s)", k) - } - return wc, nil + err = perrors.WithMessagef(err, "watch prefix (key %s)", k) + return wc, err } // WatchWithPrefix watches on spec prefix func (c *Client) WatchWithPrefix(prefix string) (clientv3.WatchChan, error) { - wc, err := c.watchWithPrefix(prefix) - if err != nil { - return nil, perrors.WithMessagef(err, "watch prefix (key %s)", prefix) - } - return wc, nil + err = perrors.WithMessagef(err, "watch prefix (key %s)", prefix) + return wc, err } From 1a16b04ddab27aa69b9c496e0c7d2b8400723727 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Thu, 23 Jul 2020 12:11:34 +0800 Subject: [PATCH 195/209] code_format --- registry/consul/listener.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/consul/listener.go b/registry/consul/listener.go index cf3888dd16..b159834503 100644 --- a/registry/consul/listener.go +++ b/registry/consul/listener.go @@ -197,7 +197,7 @@ func (l *consulListener) Next() (*registry.ServiceEvent, error) { } } -// Close closes this listener +// Close the listener. func (l *consulListener) Close() { close(l.done) l.plan.Stop() From f5e07cdfc7e7a6cc6710046412e4ee8517b2acbb Mon Sep 17 00:00:00 2001 From: fangyincheng Date: Fri, 24 Jul 2020 02:08:11 +0800 Subject: [PATCH 196/209] update readme --- README.md | 2 ++ README_CN.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 2f40eaa3a6..7373f196e7 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Apache License, Version 2.0 ## Release note ## +[v1.5.0 - July 24, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.5.0) + [v1.4.0 - Mar 17, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.4.0) [v1.3.0 - Mar 1, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.3.0) diff --git a/README_CN.md b/README_CN.md index 94630da6c3..35078e24b5 100644 --- a/README_CN.md +++ b/README_CN.md @@ -15,6 +15,8 @@ Apache License, Version 2.0 ## 发布日志 ## +[v1.5.0 - 2020年7月24日](https://github.com/apache/dubbo-go/releases/tag/v1.5.0) + [v1.4.0 - 2020年3月17日](https://github.com/apache/dubbo-go/releases/tag/v1.4.0) [v1.3.0 - 2020年3月1日](https://github.com/apache/dubbo-go/releases/tag/v1.3.0) From f85a42a6a1fac5db409d5c05c22bdac5092ecfdb Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 25 Jul 2020 11:40:01 +0800 Subject: [PATCH 197/209] go mod tidy --- go.mod | 2 -- go.sum | 26 +++++--------------------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index e82a04b279..a16b906225 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/apache/dubbo-go require ( github.com/Workiva/go-datastructures v1.0.50 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 - github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 // indirect github.com/apache/dubbo-go-hessian2 v1.6.1 - github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible github.com/coreos/go-semver v0.3.0 // indirect diff --git a/go.sum b/go.sum index 8c8c4ef132..0fe2dfa050 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/Azure/go-autorest v10.7.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v10.15.3+incompatible h1:nhKI/bvazIs3C3TFGoSqKY6hZ8f5od5mb5/UcS6HVIY= github.com/Azure/go-autorest v10.15.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v2.2.0+incompatible h1:V5BKkxACZLjzHjSgBbr2gvLA2Ae49yhc6CSY7MLy5k4= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -35,16 +36,10 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= -github.com/apache/dubbo-go-hessian2 v1.5.0 h1:fzulDG5G7nX0ccgKdiN9XipJ7tZ4WXKgmk4stdlDS6s= -github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= -github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279 h1:1g3IJdaUjXWs++NA9Ail8+r6WgrkfhjS6hD/YXvRzjk= -github.com/apache/dubbo-go-hessian2 v1.6.1-0.20200623062814-707fde850279/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/apache/dubbo-go-hessian2 v1.6.1 h1:mFKeCZzaCkk4mMOyP+LQ85GHbRyqKT7858KS21JQYA4= github.com/apache/dubbo-go-hessian2 v1.6.1/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= @@ -58,7 +53,6 @@ github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL6 github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -113,13 +107,10 @@ github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dubbogo/getty v1.3.5 h1:xJxdDj9jm7wlrRSsVZSk2TDNxJbbac5GpxV0QpjO+Tw= -github.com/dubbogo/getty v1.3.5/go.mod h1:T55vN8Q6tZjf2AQZiGmkujneD3LfqYbv2b3QjacwYOY= github.com/dubbogo/getty v1.3.7 h1:xlkYD2/AH34iGteuLMsGjLl2PwBVrbIhHjf3tlUsv1M= github.com/dubbogo/getty v1.3.7/go.mod h1:XWO4+wAaMqgnBN9Ykv2YxxOAkGxymg6LGO9RK+EiCDY= github.com/dubbogo/go-zookeeper v1.0.1 h1:irLzvOsDOTNsN8Sv9tvYYxVu6DCQfLtziZQtUHmZgz8= github.com/dubbogo/go-zookeeper v1.0.1/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= -github.com/dubbogo/gost v1.5.1/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/dubbogo/gost v1.9.0 h1:UT+dWwvLyJiDotxJERO75jB3Yxgsdy10KztR5ycxRAk= github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= @@ -217,8 +208,6 @@ github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca/go.mod h1: github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= @@ -402,8 +391,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nacos-group/nacos-sdk-go v0.3.2 h1:q+ukmIImL6u0zBtbceMZl2frgeAc45QT6cIrTZZz50c= -github.com/nacos-group/nacos-sdk-go v0.3.2/go.mod h1:4TdsN7eZnnVCDlOlBa61b0gsRnvNJI74m9+2+OKZkcw= github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f h1:gid5/0AkHvINWK69Fgbidb3BVIXqlf1YEm7wO0NVPsw= github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f/go.mod h1:fti1GlX/EB6RDKvzK/P7Vuibqj0JMPJHQwrcTU1tLXk= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= @@ -474,7 +461,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -531,17 +517,12 @@ github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 h1:k8TV7Gz7cpWpOw/dz7 github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8/go.mod h1:S1cAa98KMFv4Sa8SbJ6ZtvOmf0VlgH0QJ1gXI0lBfBY= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -553,6 +534,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -614,6 +596,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180829000535-087779f1d2c9 h1:z1TeLUmxf9ws9KLICfmX+KGXTs+rjm+aGWzfsv7MZ9w= @@ -658,6 +641,7 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= From ba32f151e04ef902336c4dc003e1d6ff3873babc Mon Sep 17 00:00:00 2001 From: fangyincheng Date: Sat, 25 Jul 2020 13:30:07 +0800 Subject: [PATCH 198/209] Mod: update feature list --- README.md | 2 ++ README_CN.md | 1 + 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 7373f196e7..e51cb7df3a 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Finished List: - Codec * JsonRPC V2 * Hessian V2 + * [json for grpc](https://github.com/apache/dubbo-go/pull/582) - Protocol * Dubbo @@ -111,6 +112,7 @@ Finished List: * [For jsonrpc](https://github.com/apache/dubbo-go/pull/335) * [For dubbo](https://github.com/apache/dubbo-go/pull/344) * [For grpc](https://github.com/apache/dubbo-go/pull/397) +- - Others: * start check diff --git a/README_CN.md b/README_CN.md index 35078e24b5..4bf94226eb 100644 --- a/README_CN.md +++ b/README_CN.md @@ -50,6 +50,7 @@ Apache License, Version 2.0 - 序列化协议 * JsonRPC V2 * Hessian V2 + * [json for grpc](https://github.com/apache/dubbo-go/pull/582) - 协议 * Dubbo From 68ed8c9ae72eddc301709d5add698cdb6197fc66 Mon Sep 17 00:00:00 2001 From: fangyincheng Date: Sat, 25 Jul 2020 13:37:19 +0800 Subject: [PATCH 199/209] Mod: update feature list --- README.md | 16 ++++++++++------ README_CN.md | 14 +++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e51cb7df3a..d0080b33b6 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,16 @@ Finished List: * [For jsonrpc](https://github.com/apache/dubbo-go/pull/335) * [For dubbo](https://github.com/apache/dubbo-go/pull/344) * [For grpc](https://github.com/apache/dubbo-go/pull/397) -- + +- Metadata Center + * [Nacos](https://github.com/apache/dubbo-go/pull/522) + * [Zookeeper](https://github.com/apache/dubbo-go/pull/633) + * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) + +- Service discovery + * [Nacos](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/nacos/service_discovery.go) + * [Zookeeper](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/zookeeper/service_discovery.go) + * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/etcdv3/service_discovery.go) - Others: * start check @@ -122,11 +131,6 @@ Finished List: * multi-versions * service group -Working List: - -- Metadata Center (dubbo v2.7.x) -- Service Discovery (dubbo v2.7.x) - You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap). ![feature](./doc/pic/arch/dubbo-go-arch.png) diff --git a/README_CN.md b/README_CN.md index 4bf94226eb..9dd10d6272 100644 --- a/README_CN.md +++ b/README_CN.md @@ -111,6 +111,15 @@ Apache License, Version 2.0 * [For dubbo](https://github.com/apache/dubbo-go/pull/344) * [For grpc](https://github.com/apache/dubbo-go/pull/397) +- 元数据中心 + * [Nacos](https://github.com/apache/dubbo-go/pull/522) + * [Zookeeper](https://github.com/apache/dubbo-go/pull/633) + * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) + +- 服务发现 + * [Nacos](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/nacos/service_discovery.go) + * [Zookeeper](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/zookeeper/service_discovery.go) + * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/etcdv3/service_discovery.go) - 其他功能支持: * 启动时检查 @@ -120,11 +129,6 @@ Apache License, Version 2.0 * 多服务版本 * 服务分组 -开发中列表: - -- 元数据中心 (dubbo v2.7.x) -- 服务发现 (dubbo v2.7.x) - 你可以通过访问 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 知道更多关于 dubbo-go 的信息。 ![feature](./doc/pic/arch/dubbo-go-arch.png) From b587f644f7b3052d0ba1160188956e1111974a02 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 25 Jul 2020 17:11:11 +0800 Subject: [PATCH 200/209] update consul version --- go.mod | 46 ++- go.sum | 523 ++++++++++++++++++++------- registry/etcdv3/service_discovery.go | 2 +- 3 files changed, 415 insertions(+), 156 deletions(-) diff --git a/go.mod b/go.mod index a16b906225..052aa15bbb 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,9 @@ module github.com/apache/dubbo-go require ( + cloud.google.com/go v0.39.0 // indirect + github.com/Microsoft/go-winio v0.4.13 // indirect + github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/Workiva/go-datastructures v1.0.50 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 github.com/apache/dubbo-go-hessian2 v1.6.1 @@ -8,52 +11,61 @@ require ( github.com/coreos/etcd v3.3.13+incompatible github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect - github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/creasty/defaults v1.3.0 + github.com/docker/go-connections v0.4.0 // indirect github.com/dubbogo/getty v1.3.7 github.com/dubbogo/go-zookeeper v1.0.1 github.com/dubbogo/gost v1.9.0 + github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.0.0 + github.com/frankban/quicktest v1.4.1 // indirect + github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect github.com/go-co-op/gocron v0.1.1 github.com/go-resty/resty/v2 v2.1.0 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 - github.com/google/btree v1.0.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/google/go-cmp v0.3.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 // indirect github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 - github.com/hashicorp/consul v1.5.3 - github.com/hashicorp/consul/api v1.1.0 - github.com/hashicorp/vault v0.10.3 + github.com/hashicorp/consul v1.8.0 + github.com/hashicorp/consul/api v1.5.0 + github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/hashicorp/vault/api v1.0.5-0.20191108163347-bdd38fca2cff // indirect + github.com/hashicorp/vault/sdk v0.1.14-0.20191112033314-390e96e22eb2 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b // indirect github.com/magiconair/properties v1.8.1 - github.com/mitchellh/mapstructure v1.1.2 + github.com/mitchellh/hashstructure v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.2.3 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f github.com/opentracing/opentracing-go v1.1.0 + github.com/pierrec/lz4 v2.2.6+incompatible // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.1.0 github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b + github.com/shirou/gopsutil v2.19.9+incompatible // indirect github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect - github.com/soheilhy/cmux v0.1.4 // indirect + github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 - github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect - github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 go.etcd.io/bbolt v1.3.4 // indirect go.uber.org/atomic v1.6.0 go.uber.org/zap v1.15.0 - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - google.golang.org/grpc v1.22.1 - gopkg.in/yaml.v2 v2.2.2 - k8s.io/api v0.0.0-20190325185214-7544f9db76f6 - k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 - k8s.io/client-go v8.0.0+incompatible + google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 // indirect + google.golang.org/grpc v1.23.0 + gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect + gopkg.in/yaml.v2 v2.2.8 + k8s.io/api v0.16.9 + k8s.io/apimachinery v0.16.9 + k8s.io/client-go v0.16.9 k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a // indirect ) go 1.13 + +replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go v1.1.7 diff --git a/go.sum b/go.sum index 0fe2dfa050..ee42317071 100644 --- a/go.sum +++ b/go.sum @@ -1,31 +1,58 @@ cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/Azure/azure-sdk-for-go v16.0.0+incompatible h1:gr1qKY/Ll72VjFTZmaBwRK1yQHAxCnV25ekOKroc9ws= -github.com/Azure/azure-sdk-for-go v16.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v10.7.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v10.15.3+incompatible h1:nhKI/bvazIs3C3TFGoSqKY6hZ8f5od5mb5/UcS6HVIY= -github.com/Azure/go-autorest v10.15.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= +github.com/Azure/azure-sdk-for-go v40.3.0+incompatible h1:NthZg3psrLxvQLN6rVm07pZ9mv2wvGNaBNGQ3fnPvLE= +github.com/Azure/azure-sdk-for-go v40.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY= +github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v2.2.0+incompatible h1:V5BKkxACZLjzHjSgBbr2gvLA2Ae49yhc6CSY7MLy5k4= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/Jeffail/gabs v1.1.0 h1:kw5zCcl9tlJNHTDme7qbi21fDHZmXrnjMoXos3Jw/NI= -github.com/Jeffail/gabs v1.1.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Microsoft/go-winio v0.4.3 h1:M3NHMuPgMSUPdE5epwNUHlRPSVzHs8HpRTrVXhR0myo= github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.13 h1:Hmi80lzZuI/CaYmlJp/b+FjZdRZhKu9c2mDVqKlLWVs= +github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/SAP/go-hdb v0.12.0 h1:5hBQZ2jjyZ268qjDmoDZJuCyLzR6oRLI60eYzmTW9m4= -github.com/SAP/go-hdb v0.12.0/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0= -github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc h1:LkkwnbY+S8WmwkWq1SVyRWMH9nYWO1P5XN3OD1tts/w= -github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= @@ -44,79 +71,90 @@ github.com/apache/dubbo-go-hessian2 v1.6.1 h1:mFKeCZzaCkk4mMOyP+LQ85GHbRyqKT7858 github.com/apache/dubbo-go-hessian2 v1.6.1/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU= +github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL60YFll4ehCwibKotx0BR9v2ND40fomga8qDs= -github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro= -github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go v1.25.41 h1:/hj7nZ0586wFqpwjNpzWiUTwtaMgxAZNZKHay80MdXw= +github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M= -github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coredns/coredns v1.1.2 h1:bAFHrSsBeTeRG5W3Nf2su3lUGw7Npw2UKeCJm/3A638= github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/creasty/defaults v1.3.0 h1:uG+RAxYbJgOPCOdKEcec9ZJXeva7Y6mj/8egdzwmLtw= github.com/creasty/defaults v1.3.0/go.mod h1:CIEEvs7oIVZm30R8VxtFJs+4k201gReYyuYHJxZc68I= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20180620032804-94c9c97e8c9f h1:JtRnQbMXb3TcSIm1j452zI45lPMiAQ0puF8iK5EnY9M= -github.com/denisenkom/go-mssqldb v0.0.0-20180620032804-94c9c97e8c9f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.1.1/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/digitalocean/godo v1.10.0 h1:uW1/FcvZE/hoixnJcnlmIUvTVNdZCLjRLzmDtRi1xXY= github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o= github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/dubbogo/getty v1.3.7 h1:xlkYD2/AH34iGteuLMsGjLl2PwBVrbIhHjf3tlUsv1M= github.com/dubbogo/getty v1.3.7/go.mod h1:XWO4+wAaMqgnBN9Ykv2YxxOAkGxymg6LGO9RK+EiCDY= github.com/dubbogo/go-zookeeper v1.0.1 h1:irLzvOsDOTNsN8Sv9tvYYxVu6DCQfLtziZQtUHmZgz8= github.com/dubbogo/go-zookeeper v1.0.1/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= github.com/dubbogo/gost v1.9.0 h1:UT+dWwvLyJiDotxJERO75jB3Yxgsdy10KztR5ycxRAk= github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= -github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= -github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0 h1:ZoRgc53qJCfSLimXqJDrmBhnt5GChDsExMCK7t48o0Y= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.0.0 h1:Duxxa4x0WIHW3bYEDmoAPNjmy8Rbqn+utcF74dlF/G8= @@ -125,28 +163,39 @@ github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1d github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk= github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM= github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/structs v0.0.0-20180123065059-ebf56d35bba7 h1:bGT+Ub6bpzHl7AAYQhBrZ5nYTAH2SF/848WducU0Ao4= -github.com/fatih/structs v0.0.0-20180123065059-ebf56d35bba7/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= +github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= +github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= +github.com/go-asn1-ber/asn1-ber v1.3.1 h1:gvPdv/Hr++TRFCl0UbPFHC54P9N9jgsRPnmnr419Uck= +github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-co-op/gocron v0.1.1 h1:OfDmkqkCguFtFMsm6Eaayci3DADLa8pXvdmOlPU/JcU= github.com/go-co-op/gocron v0.1.1/go.mod h1:Y9PWlYqDChf2Nbgg7kfS+ZsXHDTZbMZYPEQ0MILqH+M= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-ldap/ldap v3.0.2+incompatible h1:kD5HQcAzlQ7yrhfn+h+MSABeAy/jAJhvIJ/QDllP44g= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-ldap/ldap/v3 v3.1.3 h1:RIgdpHXJpsUqUK5WXwKyVsESrGFqo5BRWPk3RR4/ogQ= +github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= @@ -156,24 +205,26 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-resty/resty/v2 v2.1.0 h1:Z6IefCpUMfnvItVJaJXWv/pMiiD11So35QgwEELsldE= github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= -github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4 h1:1LlmVz15APoKz9dnm5j2ePptburJlwEH+/v/pUuoxck= -github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78 h1:G7iRamCffNivybfZvsJjtk3k2qHa73xW+OysVkukcGk= -github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -181,8 +232,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -191,139 +240,187 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= +github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2/go.mod h1:DavVbd41y+b7ukKDmlnPR4nGYmkWXR6vHUkjQNiHPBs= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca h1:wobTb8SE189AuxzEKClyYxiI4nUGWlpVtl13eLiFlOE= -github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= -github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul v1.5.3 h1:EmTWRf/cuqZk6Ug9tgFUVE9xNgJPpmBvJwJMvm+agSk= -github.com/hashicorp/consul v1.5.3/go.mod h1:61E2GJCPEP3oq8La7sfDdWGQ66+Zbxzw5ecOdFD7xIE= -github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul v1.8.0 h1:yRKMKZyPLqUxl37t4nFt5OuGmTXoFhTJrakhfnYKCYA= +github.com/hashicorp/consul v1.8.0/go.mod h1:Gg9/UgAQ9rdY3CTvzQZ6g2jcIb7NlIfjI+0pvLk5D1A= +github.com/hashicorp/consul/api v1.5.0 h1:Yo2bneoGy68A7aNwmuETFnPhjyBEm7n3vzRacEVMjvI= +github.com/hashicorp/consul/api v1.5.0/go.mod h1:LqwrLNW876eYSuUOo4ZLHBcdKc038txr/IMfbLPATa4= +github.com/hashicorp/consul/sdk v0.5.0 h1:WC4594Wp/LkEeML/OdQKEC1yqBmEYkRp6i7X5u0zDAs= +github.com/hashicorp/consul/sdk v0.5.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.0 h1:hA/9CWGPsQ6YZXvPvizD+VEEjBG4V6Un0Qcyav5ghK4= -github.com/hashicorp/go-bexpr v0.1.0/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= +github.com/hashicorp/go-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= +github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= +github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de h1:XDCSythtg8aWSRSO29uwhgh7b127fWr+m5SemqjSUL8= github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-discover v0.0.0-20190403160810-22221edb15cd h1:SynRxs8h2h7lLSA5py5a3WWkYpImhREtju0CuRd97wc= -github.com/hashicorp/go-discover v0.0.0-20190403160810-22221edb15cd/go.mod h1:ueUgD9BeIocT7QNuvxSyJyPAM9dfifBcaWmeybb67OY= +github.com/hashicorp/go-connlimit v0.2.0 h1:OZjcfNxH/hPh/bT2Iw5yOJcLzz+zuIWpsp3I1S4Pjw4= +github.com/hashicorp/go-connlimit v0.2.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= +github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088 h1:jBvElOilnIl6mm8S6gva/dfeTJCcMs9TGO6/2C6k52E= +github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088/go.mod h1:vZu6Opqf49xX5lsFAu7iFNewkcVF1sn/wyapZh5ytlg= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.1 h1:9PZfAcVEvez4yhLH2TBU64/h/z4xlFI80cWXRrxuKuM= github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71 h1:yxxFgVz31vFoKKTtRUNbXLNe4GFnbLKqg+0N7yG42L8= -github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71/go.mod h1:kbfItVoBJwCfKXDXN4YoAXjxcFVZ7MRrJzyTX6H4giE= +github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= +github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.0.3 h1:iiqzNk8jKB6/sLRj623Ui/Vi1zf21LOUpgzGjTge6a8= +github.com/hashicorp/go-memdb v1.0.3/go.mod h1:LWQ8R70vPrS4OEY9k28D2z8/Zzyu34NVzeRibGAzHO0= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v0.0.0-20180331002553-e8d22c780116 h1:Y4V/yReWjQo/Ngyc0w6C3EKXKincp4YgvXeo8lI4LrI= -github.com/hashicorp/go-plugin v0.0.0-20180331002553-e8d22c780116/go.mod h1:JSqWYsict+jzcj0+xElxyrBQRPNoiWQuddnxArJ7XHQ= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-raftchunking v0.6.1 h1:moEnaG3gcwsWNyIBJoD5PCByE+Ewkqxh6N05CT+MbwA= github.com/hashicorp/go-raftchunking v0.6.1/go.mod h1:cGlg3JtDy7qy6c/3Bu660Mic1JF+7lWqIwCFSb08fX0= +github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4= +github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU= github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= +github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031 h1:c3Xdf5fTpk+hqhxqCO+ymqjfUXV9+GZqNgTtlnVzDos= -github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v0.0.0-20180906183839-65a6292f0157 h1:PJ+K03hio6ADVjEc6lFu5r866o67xEEMQ73CFdI6R2U= -github.com/hashicorp/hcl v0.0.0-20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5 h1:uk280DXEbQiCOZgCOI3elFSeNxf8YIZiNsbr2pQLYD0= github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs= -github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.1.2 h1:oxEL5DDeurYxLd3UbcY/hccgSPhLLpiBZ1YxtWEq59c= +github.com/hashicorp/raft v1.1.2/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= -github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/vault v0.10.3 h1:3Hf6mwC4rggOq6ViWSoJ2yfk1oBS5ed58LLcP33gmEg= -github.com/hashicorp/vault v0.10.3/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= -github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20190318174639-195e0e9d07f1 h1:7IvvWArBoSjStPohKqHj3ksXNjcyPsyXYDIhCQw6Vtg= -github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20190318174639-195e0e9d07f1/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0= +github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU= +github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0= +github.com/hashicorp/serf v0.9.2/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/vault/api v1.0.4 h1:j08Or/wryXT4AcHj1oCbMd7IijXcKzYUGw59LGu9onU= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/api v1.0.5-0.20191108163347-bdd38fca2cff h1:cl94LQIrs/mNbh3ny1R8lM1gtYcUBa7HnGtOCi35SlQ= +github.com/hashicorp/vault/api v1.0.5-0.20191108163347-bdd38fca2cff/go.mod h1:Uf8LaHyrYsgVgHzO2tMZKhqRGlL3UJ6XaSwW2EA1Iqo= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/vault/sdk v0.1.14-0.20191108161836-82f2b5571044/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU= +github.com/hashicorp/vault/sdk v0.1.14-0.20191112033314-390e96e22eb2 h1:mKYi4Fm2uSfe94Ji89CoAaP7SPEEkfdtaUlgRGGb2go= +github.com/hashicorp/vault/sdk v0.1.14-0.20191112033314-390e96e22eb2/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU= github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw= github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90= +github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= -github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee h1:AQ/QmCk6x8ECPpf2pkPtA4lyncEEBbs8VFnVXPYKhIs= -github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 h1:JHCT6xuyPUrbbgAPE/3dqlvUKzRHMNuTBKKUb6OeR/k= github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= +github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20190930114154-d42613fe1ab9 h1:hJix6idebFclqlfZCHE7EUX7uqLCyb70nHNHH1XKGBg= @@ -333,15 +430,18 @@ github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVE github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b h1:Rrp0ByJXEjhREMPGTt3aWYjoIsUGCbt21ekbeJcTWv0= github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b h1:VE6r2OwP5gj+Z9aCkSKl3MlmnZbfMAjhvR5T7abKHEo= -github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -351,34 +451,58 @@ github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgU github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8= github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc= github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= -github.com/lib/pq v0.0.0-20180523175426-90697d60dd84 h1:it29sI2IM490luSc3RAhp5WuCYnc6RtbfLVAB7nmC5M= -github.com/lib/pq v0.0.0-20180523175426-90697d60dd84/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= +github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= +github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= +github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.3 h1:f/MjBEBDLttYCGfRaKBbKSRVF5aV2O6fnBpzknuE3jU= +github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.0.0 h1:ATSdz4NWrmWPOF1CeCBU4sMCno2hgqdbSrRPFWQSVZI= +github.com/mitchellh/pointerstructure v1.0.0/go.mod h1:k4XwG94++jLVsSiTxo7qdIfXA9pj9EAeo0QsNNJOLZ8= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -391,42 +515,41 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f h1:gid5/0AkHvINWK69Fgbidb3BVIXqlf1YEm7wO0NVPsw= github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f/go.mod h1:fti1GlX/EB6RDKvzK/P7Vuibqj0JMPJHQwrcTU1tLXk= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= -github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0= -github.com/oklog/run v0.0.0-20180308005104-6934b124db28/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/ory/dockertest v3.3.4+incompatible h1:VrpM6Gqg7CrPm3bL4Wm1skO+zFWLbh7/Xb5kGEbJRh8= -github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8 h1:BR6MM54q4W9pn0SySwg6yctZtBKlTdUq6a+b0kArBnE= -github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.2.6+incompatible h1:6aCX4/YZ9v8q69hTyiR7dNLnTA3fgtKHVVW5BCd5Znw= +github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -437,47 +560,69 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rboyer/safeio v0.2.1 h1:05xhhdRNAdS3apYm7JRjOqngf4xruaW959jmRxGDuSU= +github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= -github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= +github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880 h1:1Ge4j/3uB2rxzPWD3TC+daeCw+w91z8UCUL/7WH5gn8= github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v2.19.9+incompatible h1:IrPVlK4nfwW10DF7pW+7YJKws9NkgNzWozwwWv9FsgY= +github.com/shirou/gopsutil v2.19.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI= github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -485,13 +630,25 @@ github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQv github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -500,6 +657,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto= github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible h1:8uRvJleFpqLsO77WaAh2UrasMOzd8MxXrNj20e7El+Q= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0= github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= @@ -509,56 +668,88 @@ github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 h1:k8TV7Gz7cpWpOw/dz71fx8cCZdWoPuckHJ/wkJl+meg= github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8/go.mod h1:S1cAa98KMFv4Sa8SbJ6ZtvOmf0VlgH0QJ1gXI0lBfBY= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20170807180024-9a379c6b3e95/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= @@ -571,44 +762,89 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180829000535-087779f1d2c9 h1:z1TeLUmxf9ws9KLICfmX+KGXTs+rjm+aGWzfsv7MZ9w= -google.golang.org/api v0.0.0-20180829000535-087779f1d2c9/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw= +google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101 h1:wuGevabY6r+ivPNagjUXGGxF+GqgMd+dBhjsxW4q9u4= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= @@ -616,6 +852,8 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -624,37 +862,46 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 h1:/saqWwm73dLmuzbNhe92F0QsZ/KiFND+esHco2v1hiY= -gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/ory-am/dockertest.v3 v3.3.4 h1:oen8RiwxVNxtQ1pRoV4e4jqh6UjNsOuIZ1NXns6jdcw= -gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= +gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= -k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/api v0.0.0-20190325185214-7544f9db76f6 h1:9MWtbqhwTyDvF4cS1qAhxDb9Mi8taXiAu+5nEacl7gY= -k8s.io/api v0.0.0-20190325185214-7544f9db76f6/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apimachinery v0.0.0-20180821005732-488889b0007f/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 h1:Q4RZrHNtlC/mSdC1sTrcZ5RchC/9vxLVj57pWiCBKv4= -k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7HfitmxC4= -k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/api v0.16.9 h1:3vCx0WX9qcg1Hv4aQ/G1tiIKectGVuimvPVTJU4VOCA= +k8s.io/api v0.16.9/go.mod h1:Y7dZNHs1Xy0mSwSlzL9QShi6qkljnN41yR8oWCRTDe8= +k8s.io/apimachinery v0.16.9 h1:ESUZ4hMBUKF2kn2HBFL5zM/wQv4j/0uRbR7AjgqGJ4o= +k8s.io/apimachinery v0.16.9/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= +k8s.io/client-go v0.16.9 h1:6Eh4lMDxFtDzBkqid1AOL3bQ/pPYrulx8l23DXw4mRU= +k8s.io/client-go v0.16.9/go.mod h1:ThjPlh7Kx+XoBFOCt775vx5J7atwY7F/zaFzTco5gL0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index 10396049fb..f381ba70d6 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -26,7 +26,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" gxpage "github.com/dubbogo/gost/page" - "github.com/hashicorp/vault/helper/jsonutil" + "github.com/hashicorp/vault/sdk/helper/jsonutil" perrors "github.com/pkg/errors" ) From 7970243e81f092ea2a51bdbec1ab02f1086ae763 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 25 Jul 2020 17:29:11 +0800 Subject: [PATCH 201/209] remove replace --- go.mod | 2 -- go.sum | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 052aa15bbb..7a472daef7 100644 --- a/go.mod +++ b/go.mod @@ -67,5 +67,3 @@ require ( ) go 1.13 - -replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go v1.1.7 diff --git a/go.sum b/go.sum index ee42317071..424a11087b 100644 --- a/go.sum +++ b/go.sum @@ -668,11 +668,8 @@ github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= From 9632fd7fa363061b180fcb9afc40dda6c5f1c101 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 25 Jul 2020 21:13:33 +0800 Subject: [PATCH 202/209] update consul test --- metadata/report/consul/report_test.go | 2 +- registry/consul/utils_test.go | 8 ++++--- remoting/consul/test_agent.go | 30 ++------------------------- remoting/consul/test_agent_test.go | 2 +- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/metadata/report/consul/report_test.go b/metadata/report/consul/report_test.go index 34ee29de94..e07a7429f1 100644 --- a/metadata/report/consul/report_test.go +++ b/metadata/report/consul/report_test.go @@ -143,7 +143,7 @@ func (suite *consulMetadataReportTestSuite) testGetServiceDefinition() { func test1(t *testing.T) { consulAgent := consul.NewConsulAgent(t, 8500) - defer consulAgent.Close() + defer consulAgent.Shutdown() url := newProviderRegistryUrl("localhost", 8500) mf := extension.GetMetadataReportFactory("consul") diff --git a/registry/consul/utils_test.go b/registry/consul/utils_test.go index 327dd95f71..939352dc08 100644 --- a/registry/consul/utils_test.go +++ b/registry/consul/utils_test.go @@ -148,7 +148,7 @@ func (suite *consulRegistryTestSuite) close() { // register -> subscribe -> unregister func test1(t *testing.T) { consulAgent := consul.NewConsulAgent(t, registryPort) - defer consulAgent.Close() + defer consulAgent.Shutdown() server := newServer(providerHost, providerPort) defer server.close() @@ -165,10 +165,10 @@ func test1(t *testing.T) { suite.testListener(remoting.EventTypeDel) } -// subscribe -> register +// subscribe -> register -> unregister func test2(t *testing.T) { consulAgent := consul.NewConsulAgent(t, registryPort) - defer consulAgent.Close() + defer consulAgent.Shutdown() server := newServer(providerHost, providerPort) defer server.close() @@ -181,6 +181,8 @@ func test2(t *testing.T) { suite.testNewProviderRegistry() suite.testRegister() suite.testListener(remoting.EventTypeAdd) + suite.testUnregister() + suite.testListener(remoting.EventTypeDel) } func TestConsulRegistry(t *testing.T) { diff --git a/remoting/consul/test_agent.go b/remoting/consul/test_agent.go index 1744da7bd9..f6ba336a95 100644 --- a/remoting/consul/test_agent.go +++ b/remoting/consul/test_agent.go @@ -18,8 +18,6 @@ package consul import ( - "io/ioutil" - "os" "strconv" "testing" ) @@ -30,35 +28,11 @@ import ( // Consul agent, used for test, simulates // an embedded consul server. -type ConsulAgent struct { - dataDir string - testAgent *agent.TestAgent -} - -func NewConsulAgent(t *testing.T, port int) *ConsulAgent { - dataDir, _ := ioutil.TempDir("./", "agent") +func NewConsulAgent(t *testing.T, port int) *agent.TestAgent { hcl := ` ports { http = ` + strconv.Itoa(port) + ` } - data_dir = "` + dataDir + `" ` - testAgent := &agent.TestAgent{Name: t.Name(), DataDir: dataDir, HCL: hcl} - testAgent.Start(t) - - consulAgent := &ConsulAgent{ - dataDir: dataDir, - testAgent: testAgent, - } - return consulAgent -} - -func (consulAgent *ConsulAgent) Close() error { - var err error - - err = consulAgent.testAgent.Shutdown() - if err != nil { - return err - } - return os.RemoveAll(consulAgent.dataDir) + return agent.NewTestAgent(t, hcl) } diff --git a/remoting/consul/test_agent_test.go b/remoting/consul/test_agent_test.go index 8cf0ac6cd8..066e5e3c2d 100644 --- a/remoting/consul/test_agent_test.go +++ b/remoting/consul/test_agent_test.go @@ -27,6 +27,6 @@ import ( func TestNewConsulAgent(t *testing.T) { consulAgent := NewConsulAgent(t, 8500) - err := consulAgent.Close() + err := consulAgent.Shutdown() assert.NoError(t, err) } From 655d1df27d8d3c645f4949968cd19992bbec7ced Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sat, 25 Jul 2020 23:00:12 +0800 Subject: [PATCH 203/209] code format --- remoting/etcdv3/client.go | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index a2a5764538..4e7436e445 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -142,9 +142,7 @@ func NewServiceDiscoveryClient(opts ...Option) *Client { if err != nil { logger.Errorf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}", options.name, options.endpoints, options.timeout, err) - return nil } - return newClient } @@ -426,8 +424,7 @@ func (c *Client) keepAliveKV(k string, v string) error { } _, err = c.rawClient.Put(c.ctx, k, v, clientv3.WithLease(lease.ID)) - err = perrors.WithMessage(err, "put k/v with lease") - return err + return perrors.WithMessage(err, "put k/v with lease") } // nolint @@ -445,64 +442,53 @@ func (c *Client) Valid() bool { c.lock.RLock() defer c.lock.RUnlock() - if c.rawClient == nil { - return false - } - return true + return c.rawClient != nil } // nolint func (c *Client) Create(k string, v string) error { err := c.put(k, v) - err = perrors.WithMessagef(err, "put k/v (key: %s value %s)", k, v) - return err + return perrors.WithMessagef(err, "put k/v (key: %s value %s)", k, v) } // Update key value ... func (c *Client) Update(k, v string) error { err := c.update(k, v) - err = perrors.WithMessagef(err, "Update k/v (key: %s value %s)", k, v) - return err + return perrors.WithMessagef(err, "Update k/v (key: %s value %s)", k, v) } // nolint func (c *Client) Delete(k string) error { err := c.delete(k) - err = perrors.WithMessagef(err, "delete k/v (key %s)", k) - return err + return perrors.WithMessagef(err, "delete k/v (key %s)", k) } // RegisterTemp registers a temporary node func (c *Client) RegisterTemp(k, v string) error { err := c.keepAliveKV(k, v) - err = perrors.WithMessagef(err, "keepalive kv (key %s)", k) - return err + return perrors.WithMessagef(err, "keepalive kv (key %s)", k) } // GetChildrenKVList gets children kv list by @k func (c *Client) GetChildrenKVList(k string) ([]string, []string, error) { kList, vList, err := c.getChildren(k) - err = perrors.WithMessagef(err, "get key children (key %s)", k) - return kList, vList, err + return kList, vList, perrors.WithMessagef(err, "get key children (key %s)", k) } // Get gets value by @k func (c *Client) Get(k string) (string, error) { v, err := c.get(k) - err = perrors.WithMessagef(err, "get key value (key %s)", k) - return v, err + return v, perrors.WithMessagef(err, "get key value (key %s)", k) } // Watch watches on spec key func (c *Client) Watch(k string) (clientv3.WatchChan, error) { wc, err := c.watch(k) - err = perrors.WithMessagef(err, "watch prefix (key %s)", k) - return wc, err + return wc, perrors.WithMessagef(err, "watch prefix (key %s)", k) } // WatchWithPrefix watches on spec prefix func (c *Client) WatchWithPrefix(prefix string) (clientv3.WatchChan, error) { wc, err := c.watchWithPrefix(prefix) - err = perrors.WithMessagef(err, "watch prefix (key %s)", prefix) - return wc, err + return wc, perrors.WithMessagef(err, "watch prefix (key %s)", prefix) } From d795e2a350e7fca7793ac40b154950e04dd83fce Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 10:05:47 +0800 Subject: [PATCH 204/209] decrease stack level in log --- common/logger/logger.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/common/logger/logger.go b/common/logger/logger.go index 9bc6a46100..88ed0c29f8 100644 --- a/common/logger/logger.go +++ b/common/logger/logger.go @@ -100,7 +100,6 @@ func InitLog(logConfFile string) error { func InitLogger(conf *zap.Config) { var zapLoggerConfig zap.Config if conf == nil { - zapLoggerConfig = zap.NewDevelopmentConfig() zapLoggerEncoderConfig := zapcore.EncoderConfig{ TimeKey: "time", LevelKey: "level", @@ -113,12 +112,18 @@ func InitLogger(conf *zap.Config) { EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } - zapLoggerConfig.EncoderConfig = zapLoggerEncoderConfig + zapLoggerConfig = zap.Config{ + Level: zap.NewAtomicLevelAt(zap.DebugLevel), + Development: false, + Encoding: "console", + EncoderConfig: zapLoggerEncoderConfig, + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + } } else { zapLoggerConfig = *conf } zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1)) - //logger = zapLogger.Sugar() logger = &DubboLogger{Logger: zapLogger.Sugar(), dynamicLevel: zapLoggerConfig.Level} // set getty log From 7d9abd2010ccec94f3742328c7da139df0dd1161 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 10:12:52 +0800 Subject: [PATCH 205/209] add consul metadata in readme --- README.md | 1 + README_CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index d0080b33b6..a1c09fc3ca 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ Finished List: * [Nacos](https://github.com/apache/dubbo-go/pull/522) * [Zookeeper](https://github.com/apache/dubbo-go/pull/633) * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) + * [Consul](https://github.com/apache/dubbo-go/pull/633) - Service discovery * [Nacos](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/nacos/service_discovery.go) diff --git a/README_CN.md b/README_CN.md index 9dd10d6272..552685c7bb 100644 --- a/README_CN.md +++ b/README_CN.md @@ -115,6 +115,7 @@ Apache License, Version 2.0 * [Nacos](https://github.com/apache/dubbo-go/pull/522) * [Zookeeper](https://github.com/apache/dubbo-go/pull/633) * [Etcd](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/metadata/report/etcd/report.go) + * [Consul](https://github.com/apache/dubbo-go/pull/633) - 服务发现 * [Nacos](https://github.com/apache/dubbo-go/blob/9a5990d9a9c3d5e6633c0d7d926c156416bcb931/registry/nacos/service_discovery.go) From cb15ad055ea25beb6fd14dd046731c995423646d Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 10:24:17 +0800 Subject: [PATCH 206/209] code format --- remoting/zookeeper/client.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 4ca34a6aec..3db743ed58 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -363,14 +363,9 @@ func (z *ZookeeperClient) ZkConnValid() bool { default: } - valid := true z.RLock() - if z.Conn == nil { - valid = false - } - z.RUnlock() - - return valid + defer z.RUnlock() + return z.Conn != nil } // nolint From 66e0f4de81f338224f0c45743715aaa556a25ab9 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 14:07:43 +0800 Subject: [PATCH 207/209] wait nacos client cache flush --- registry/nacos/service_discovery_test.go | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 4b069c2e82..24412999c5 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -103,25 +103,26 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { } // clean data - - serviceDiscovry, _ := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) + serviceDiscovery, err := extension.GetServiceDiscovery(constant.NACOS_KEY, testName) + assert.Nil(t, err) // clean data for local test - serviceDiscovry.Unregister(®istry.DefaultServiceInstance{ + err = serviceDiscovery.Unregister(®istry.DefaultServiceInstance{ Id: id, ServiceName: serviceName, Host: host, Port: port, }) + assert.Nil(t, err) - err := serviceDiscovry.Register(instance) + err = serviceDiscovery.Register(instance) assert.Nil(t, err) + //sometimes nacos may be failed to push update of instance, //so it need 10s to pull, we sleep 10 second to make sure instance has been update time.Sleep(11 * time.Second) - page := serviceDiscovry.GetHealthyInstancesByPage(serviceName, 0, 10, true) + page := serviceDiscovery.GetHealthyInstancesByPage(serviceName, 0, 10, true) assert.NotNil(t, page) - assert.Equal(t, 0, page.GetOffset()) assert.Equal(t, 10, page.GetPageSize()) assert.Equal(t, 1, page.GetDataSize()) @@ -135,12 +136,15 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { assert.Equal(t, 0, len(instance.GetMetadata())) instance.Metadata["a"] = "b" - - err = serviceDiscovry.Update(instance) + err = serviceDiscovery.Update(instance) assert.Nil(t, err) - pageMap := serviceDiscovry.GetRequestInstances([]string{serviceName}, 0, 1) + //sometimes nacos may be failed to push update of instance, + //so it need 10s to pull, we sleep 10 second to make sure instance has been update + time.Sleep(11 * time.Second) + pageMap := serviceDiscovery.GetRequestInstances([]string{serviceName}, 0, 1) assert.Equal(t, 1, len(pageMap)) + page = pageMap[serviceName] assert.NotNil(t, page) assert.Equal(t, 1, len(page.GetData())) @@ -150,11 +154,11 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { assert.Equal(t, "b", v) // test dispatcher event - err = serviceDiscovry.DispatchEventByServiceName(serviceName) + err = serviceDiscovery.DispatchEventByServiceName(serviceName) assert.Nil(t, err) // test AddListener - err = serviceDiscovry.AddListener(®istry.ServiceInstancesChangedListener{}) + err = serviceDiscovery.AddListener(®istry.ServiceInstancesChangedListener{}) assert.Nil(t, err) } From e60bb0850d57006f7a6f1281061582b35cf0ef53 Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 14:42:59 +0800 Subject: [PATCH 208/209] fix --- registry/nacos/service_discovery_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 24412999c5..44f9b2fb1c 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -118,9 +118,6 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { err = serviceDiscovery.Register(instance) assert.Nil(t, err) - //sometimes nacos may be failed to push update of instance, - //so it need 10s to pull, we sleep 10 second to make sure instance has been update - time.Sleep(11 * time.Second) page := serviceDiscovery.GetHealthyInstancesByPage(serviceName, 0, 10, true) assert.NotNil(t, page) assert.Equal(t, 0, page.GetOffset()) From 2083dba1918d6a6c3cfac0567c10ea61ce52073a Mon Sep 17 00:00:00 2001 From: "xg.gao" Date: Sun, 26 Jul 2020 15:28:13 +0800 Subject: [PATCH 209/209] revert --- registry/nacos/service_discovery_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/registry/nacos/service_discovery_test.go b/registry/nacos/service_discovery_test.go index 44f9b2fb1c..24412999c5 100644 --- a/registry/nacos/service_discovery_test.go +++ b/registry/nacos/service_discovery_test.go @@ -118,6 +118,9 @@ func TestNacosServiceDiscovery_CRUD(t *testing.T) { err = serviceDiscovery.Register(instance) assert.Nil(t, err) + //sometimes nacos may be failed to push update of instance, + //so it need 10s to pull, we sleep 10 second to make sure instance has been update + time.Sleep(11 * time.Second) page := serviceDiscovery.GetHealthyInstancesByPage(serviceName, 0, 10, true) assert.NotNil(t, page) assert.Equal(t, 0, page.GetOffset())