1818
1919import java .util .Collections ;
2020import java .util .HashSet ;
21+ import java .util .LinkedList ;
22+ import java .util .List ;
2123import java .util .Map ;
2224import java .util .Set ;
2325import java .util .concurrent .ConcurrentHashMap ;
26+ import java .util .concurrent .ExecutorService ;
2427import java .util .concurrent .atomic .AtomicBoolean ;
2528import java .util .function .Consumer ;
29+ import java .util .stream .Collectors ;
2630
2731import org .apache .dubbo .common .URL ;
32+ import org .apache .dubbo .common .threadpool .manager .FrameworkExecutorRepository ;
2833import org .apache .dubbo .common .utils .CollectionUtils ;
2934import org .apache .dubbo .common .utils .ConcurrentHashSet ;
3035import org .apache .dubbo .registry .xds .util .protocol .AbstractProtocol ;
3843import org .apache .dubbo .rpc .cluster .router .xds .RdsVirtualHostListener ;
3944import org .apache .dubbo .rpc .model .ApplicationModel ;
4045
41- import io .envoyproxy .envoy .config .route .v3 .VirtualHost ;
42-
4346public class PilotExchanger {
4447
4548 protected final XdsChannel xdsChannel ;
@@ -61,15 +64,18 @@ public class PilotExchanger {
6164
6265 private final Map <String , Consumer <RdsVirtualHostListener >> rdsObserveConsumer = new ConcurrentHashMap <>();
6366
64- private static PilotExchanger GLOBAL_PILOT_EXCHANGER = null ;
67+ private static PilotExchanger GLOBAL_PILOT_EXCHANGER = null ;
68+
69+ private final ApplicationModel applicationModel ;
6570
6671 protected PilotExchanger (URL url ) {
6772 xdsChannel = new XdsChannel (url );
6873 int pollingTimeout = url .getParameter ("pollingTimeout" , 10 );
69- ApplicationModel applicationModel = url .getOrDefaultApplicationModel ();
70- this .ldsProtocol = new LdsProtocol (xdsChannel , NodeBuilder .build (), pollingTimeout , applicationModel );
71- this .rdsProtocol = new RdsProtocol (xdsChannel , NodeBuilder .build (), pollingTimeout , applicationModel );
72- this .edsProtocol = new EdsProtocol (xdsChannel , NodeBuilder .build (), pollingTimeout , applicationModel );
74+ this .applicationModel = url .getOrDefaultApplicationModel ();
75+ AdsObserver adsObserver = new AdsObserver (url , NodeBuilder .build ());
76+ this .ldsProtocol = new LdsProtocol (adsObserver , NodeBuilder .build (), pollingTimeout );
77+ this .rdsProtocol = new RdsProtocol (adsObserver , NodeBuilder .build (), pollingTimeout );
78+ this .edsProtocol = new EdsProtocol (adsObserver , NodeBuilder .build (), pollingTimeout );
7379
7480 this .listenerResult = ldsProtocol .getListeners ();
7581 this .routeResult = rdsProtocol .getResource (listenerResult .values ().iterator ().next ().getRouteConfigNames ());
@@ -96,26 +102,31 @@ protected PilotExchanger(URL url) {
96102 private void createRouteObserve () {
97103 rdsProtocol .observeResource (listenerResult .values ().iterator ().next ().getRouteConfigNames (), (newResult ) -> {
98104 // check if observed domain update ( will update endpoint observation )
105+ List <String > domainsToUpdate = new LinkedList <>();
99106 domainObserveConsumer .forEach ((domain , consumer ) -> {
100107 newResult .values ().forEach (o -> {
101108 Set <String > newRoute = o .searchDomain (domain );
102- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
109+ for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
103110 if (!entry .getValue ().searchDomain (domain ).equals (newRoute )) {
104111 // routers in observed domain has been updated
105112// Long domainRequest = domainObserveRequest.get(domain);
106113 // router list is empty when observeEndpoints() called and domainRequest has not been created yet
107114 // create new observation
108- doObserveEndpoints (domain );
115+ domainsToUpdate .add (domain );
116+ // doObserveEndpoints(domain);
109117 }
110118 }
111119 });
112120 });
113121 routeResult = newResult ;
122+ ExecutorService executorService = applicationModel .getFrameworkModel ().getBeanFactory ()
123+ .getBean (FrameworkExecutorRepository .class ).getSharedExecutor ();
124+ executorService .submit (() -> domainsToUpdate .forEach (this ::doObserveEndpoints ));
114125 }, false );
115126 }
116127
117128 public static PilotExchanger initialize (URL url ) {
118- synchronized (PilotExchanger .class ){
129+ synchronized (PilotExchanger .class ) {
119130 if (GLOBAL_PILOT_EXCHANGER != null ) {
120131 return GLOBAL_PILOT_EXCHANGER ;
121132 }
@@ -140,15 +151,15 @@ public void destroy() {
140151
141152 public Set <String > getServices () {
142153 Set <String > domains = new HashSet <>();
143- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
154+ for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
144155 domains .addAll (entry .getValue ().getDomains ());
145156 }
146157 return domains ;
147158 }
148159
149160 public Set <Endpoint > getEndpoints (String domain ) {
150161 Set <Endpoint > endpoints = new HashSet <>();
151- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
162+ for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
152163 Set <String > cluster = entry .getValue ().searchDomain (domain );
153164 if (CollectionUtils .isNotEmpty (cluster )) {
154165 Map <String , EndpointResult > endpointResultList = edsProtocol .getResource (cluster );
@@ -176,19 +187,21 @@ public void observeEndpoints(String domain, Consumer<Set<Endpoint>> consumer) {
176187 }
177188
178189 private void doObserveEndpoints (String domain ) {
179- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
190+ for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
180191 Set <String > router = entry .getValue ().searchDomain (domain );
181192 // if router is empty, do nothing
182193 // observation will be created when RDS updates
183194 if (CollectionUtils .isNotEmpty (router )) {
184195 edsProtocol .observeResource (
185196 router ,
186197 (endpointResultMap ) -> {
187- endpointResultMap .forEach ((k , v ) -> {
188- // notify consumers
189- domainObserveConsumer .get (domain ).forEach (
190- consumer1 -> consumer1 .accept (v .getEndpoints ()));
191- });
198+ Set <Endpoint > endpoints = endpointResultMap .values ().stream ()
199+ .map (EndpointResult ::getEndpoints )
200+ .flatMap (Set ::stream )
201+ .collect (Collectors .toSet ());
202+ for (Consumer <Set <Endpoint >> consumer : domainObserveConsumer .get (domain )) {
203+ consumer .accept (endpoints );
204+ }
192205 }, false );
193206 domainObserveRequest .add (domain );
194207 }
@@ -201,18 +214,28 @@ public void unObserveEndpoints(String domain, Consumer<Set<Endpoint>> consumer)
201214 domainObserveRequest .remove (domain );
202215 }
203216
204- public VirtualHost getVirtualHost (String domain ) {
205- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
206- if (entry .getValue ().searchVirtualHost (domain ) != null ) {
207- return entry .getValue ().searchVirtualHost (domain );
208- }
209- }
210- return null ;
217+ public void observeEds (Set <String > clusterNames , Consumer <Map <String , EndpointResult >> consumer ) {
218+ edsProtocol .observeResource (clusterNames , consumer , false );
211219 }
212220
213- public void unObserveRds (String domain ) {
214- for (Map .Entry <String , RouteResult > entry : routeResult .entrySet ()) {
215- entry .getValue ().removeVirtualHost (domain );
216- }
221+ public void unObserveEds (Set <String > clusterNames , Consumer <Map <String , EndpointResult >> consumer ) {
222+ edsProtocol .unobserveResource (clusterNames , consumer );
223+ }
224+
225+ public void observeRds (Set <String > clusterNames , Consumer <Map <String , RouteResult >> consumer ) {
226+ rdsProtocol .observeResource (clusterNames , consumer , false );
227+ }
228+
229+ public void unObserveRds (Set <String > clusterNames , Consumer <Map <String , RouteResult >> consumer ) {
230+ rdsProtocol .unobserveResource (clusterNames , consumer );
217231 }
232+
233+ public void observeLds (Consumer <Map <String , ListenerResult >> consumer ) {
234+ ldsProtocol .observeResource (Collections .singleton (AbstractProtocol .emptyResourceName ), consumer , false );
235+ }
236+
237+ public void unObserveLds (Consumer <Map <String , ListenerResult >> consumer ) {
238+ ldsProtocol .unobserveResource (Collections .singleton (AbstractProtocol .emptyResourceName ), consumer );
239+ }
240+
218241}
0 commit comments