From 1577a31046a6271591bccce2f419331f8596ca56 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Tue, 12 Dec 2023 10:24:43 +0800 Subject: [PATCH] Remove Kubernetes and xDS implementations (#13469) * Remove Kubernetes and xDS implementations * Fix transform --- dubbo-distribution/dubbo-all/pom.xml | 23 - dubbo-distribution/dubbo-bom/pom.xml | 13 - dubbo-distribution/dubbo-core-spi/pom.xml | 6 - dubbo-kubernetes/pom.xml | 73 --- .../kubernetes/KubernetesMeshEnvListener.java | 207 -------- .../KubernetesMeshEnvListenerFactory.java | 42 -- .../kubernetes/KubernetesRegistry.java | 50 -- .../kubernetes/KubernetesRegistryFactory.java | 34 -- .../KubernetesServiceDiscovery.java | 451 ------------------ .../KubernetesServiceDiscoveryFactory.java | 28 -- .../registry/kubernetes/MeshConstant.java | 45 -- .../NopKubernetesMeshEnvListener.java | 34 -- .../util/KubernetesClientConst.java | 78 --- .../util/KubernetesConfigUtils.java | 104 ---- .../org.apache.dubbo.registry.RegistryFactory | 1 - ...bo.registry.client.ServiceDiscoveryFactory | 1 - ...r.router.mesh.route.MeshEnvListenerFactory | 1 - .../KubernetesServiceDiscoveryTest.java | 289 ----------- .../org.mockito.plugins.MockMaker | 1 - dubbo-test/dubbo-dependencies-all/pom.xml | 13 - dubbo-xds/pom.xml | 123 ----- .../registry/xds/XdsCertificateSigner.java | 58 --- .../org/apache/dubbo/registry/xds/XdsEnv.java | 22 - .../xds/XdsInitializationException.java | 28 -- .../dubbo/registry/xds/XdsRegistry.java | 50 -- .../registry/xds/XdsRegistryFactory.java | 34 -- .../registry/xds/XdsServiceDiscovery.java | 117 ----- .../xds/XdsServiceDiscoveryFactory.java | 48 -- .../istio/IstioCitadelCertificateSigner.java | 294 ------------ .../registry/xds/istio/IstioConstant.java | 109 ----- .../dubbo/registry/xds/istio/IstioEnv.java | 195 -------- .../dubbo/registry/xds/util/AdsObserver.java | 140 ------ .../dubbo/registry/xds/util/NodeBuilder.java | 43 -- .../registry/xds/util/PilotExchanger.java | 250 ---------- .../dubbo/registry/xds/util/XdsChannel.java | 142 ------ .../dubbo/registry/xds/util/XdsListener.java | 23 - .../xds/util/bootstrap/BootstrapInfoImpl.java | 131 ----- .../xds/util/bootstrap/Bootstrapper.java | 75 --- .../xds/util/bootstrap/BootstrapperImpl.java | 179 ------- .../CertificateProviderInfoImpl.java | 45 -- .../xds/util/bootstrap/ServerInfoImpl.java | 71 --- .../xds/util/protocol/AbstractProtocol.java | 269 ----------- .../xds/util/protocol/DeltaResource.java | 32 -- .../xds/util/protocol/XdsProtocol.java | 41 -- .../util/protocol/delta/DeltaEndpoint.java | 48 -- .../util/protocol/delta/DeltaListener.java | 47 -- .../xds/util/protocol/delta/DeltaRoute.java | 47 -- .../xds/util/protocol/impl/EdsProtocol.java | 97 ---- .../xds/util/protocol/impl/LdsProtocol.java | 106 ---- .../xds/util/protocol/impl/RdsProtocol.java | 92 ---- .../xds/util/protocol/message/Endpoint.java | 96 ---- .../util/protocol/message/EndpointResult.java | 60 --- .../util/protocol/message/ListenerResult.java | 68 --- .../util/protocol/message/RouteResult.java | 94 ---- .../router/xds/EdsEndpointListener.java | 26 - .../router/xds/EdsEndpointManager.java | 127 ----- .../router/xds/RdsRouteRuleManager.java | 162 ------- .../router/xds/RdsVirtualHostListener.java | 184 ------- .../router/xds/XdsRouteRuleListener.java | 28 -- .../rpc/cluster/router/xds/XdsRouter.java | 391 --------------- .../cluster/router/xds/XdsRouterFactory.java | 31 -- .../router/xds/XdsScopeModelInitializer.java | 39 -- .../router/xds/rule/ClusterWeight.java | 37 -- .../router/xds/rule/DestinationSubset.java | 57 --- .../router/xds/rule/HTTPRouteDestination.java | 42 -- .../router/xds/rule/HeaderMatcher.java | 121 ----- .../router/xds/rule/HttpRequestMatch.java | 39 -- .../router/xds/rule/LongRangeMatch.java | 47 -- .../cluster/router/xds/rule/PathMatcher.java | 71 --- .../cluster/router/xds/rule/XdsRouteRule.java | 37 -- dubbo-xds/src/main/proto/ca.proto | 62 --- .../org.apache.dubbo.registry.RegistryFactory | 1 - ...bo.registry.client.ServiceDiscoveryFactory | 1 - ...he.dubbo.registry.xds.XdsCertificateSigner | 1 - ...pc.cluster.router.state.StateRouterFactory | 1 - ...ache.dubbo.rpc.model.ScopeModelInitializer | 1 - .../xds/util/bootstrap/BootstrapperTest.java | 148 ------ .../util/protocol/impl/EdsProtocolMock.java | 51 -- .../util/protocol/impl/LdsProtocolMock.java | 68 --- .../util/protocol/impl/RdsProtocolMock.java | 54 --- .../router/xds/EdsEndpointManagerTest.java | 108 ----- .../router/xds/RdsRouteRuleManagerTest.java | 126 ----- .../xds/RdsVirtualHostListenerTest.java | 258 ---------- .../rpc/cluster/router/xds/XdsRouteTest.java | 376 --------------- .../router/xds/rule/HeaderMatcherTest.java | 89 ---- .../router/xds/rule/PathMatcherTest.java | 57 --- pom.xml | 2 - 87 files changed, 7611 deletions(-) delete mode 100644 dubbo-kubernetes/pom.xml delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryFactory.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/MeshConstant.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/NopKubernetesMeshEnvListener.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesClientConst.java delete mode 100644 dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java delete mode 100644 dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory delete mode 100644 dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory delete mode 100644 dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory delete mode 100644 dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java delete mode 100644 dubbo-kubernetes/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 dubbo-xds/pom.xml delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsCertificateSigner.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsEnv.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsInitializationException.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistry.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistryFactory.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscovery.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscoveryFactory.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioCitadelCertificateSigner.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioConstant.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioEnv.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/AdsObserver.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/NodeBuilder.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/PilotExchanger.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsChannel.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsListener.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapInfoImpl.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/Bootstrapper.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperImpl.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/CertificateProviderInfoImpl.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/ServerInfoImpl.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/AbstractProtocol.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/DeltaResource.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/XdsProtocol.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaEndpoint.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaListener.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaRoute.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocol.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocol.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocol.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/Endpoint.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/EndpointResult.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/ListenerResult.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/RouteResult.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointListener.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManager.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManager.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListener.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteRuleListener.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouter.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouterFactory.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsScopeModelInitializer.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/ClusterWeight.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/DestinationSubset.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HTTPRouteDestination.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcher.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HttpRequestMatch.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/LongRangeMatch.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcher.java delete mode 100644 dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/XdsRouteRule.java delete mode 100644 dubbo-xds/src/main/proto/ca.proto delete mode 100644 dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory delete mode 100644 dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory delete mode 100644 dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner delete mode 100644 dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory delete mode 100644 dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocolMock.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocolMock.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocolMock.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManagerTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManagerTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListenerTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcherTest.java delete mode 100644 dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcherTest.java diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index 95778476965..99187e7f11e 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -129,15 +129,6 @@ true - - - org.apache.dubbo - dubbo-kubernetes - ${project.version} - compile - true - - org.apache.dubbo @@ -429,15 +420,6 @@ true - - - org.apache.dubbo - dubbo-xds - ${project.version} - compile - true - - org.springframework @@ -557,8 +539,6 @@ org.apache.dubbo:dubbo-serialization-hessian2 org.apache.dubbo:dubbo-serialization-fastjson2 org.apache.dubbo:dubbo-serialization-jdk - org.apache.dubbo:dubbo-kubernetes - org.apache.dubbo:dubbo-xds @@ -753,9 +733,6 @@ META-INF/dubbo/internal/org.apache.dubbo.registry.integration.RegistryProtocolListener - - META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner - META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.filter.RestResponseInterceptor diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 28d4302cecd..dacced4646f 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -175,13 +175,6 @@ ${project.version} - - - org.apache.dubbo - dubbo-kubernetes - ${project.version} - - org.apache.dubbo @@ -595,12 +588,6 @@ ${project.version} - - - org.apache.dubbo - dubbo-xds - ${project.version} - diff --git a/dubbo-distribution/dubbo-core-spi/pom.xml b/dubbo-distribution/dubbo-core-spi/pom.xml index 88939753e9a..212ea97fca8 100644 --- a/dubbo-distribution/dubbo-core-spi/pom.xml +++ b/dubbo-distribution/dubbo-core-spi/pom.xml @@ -515,12 +515,6 @@ META-INF/dubbo/internal/org.apache.dubbo.registry.integration.RegistryProtocolListener - - - META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner - - diff --git a/dubbo-kubernetes/pom.xml b/dubbo-kubernetes/pom.xml deleted file mode 100644 index 8f5a0e1acb1..00000000000 --- a/dubbo-kubernetes/pom.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - 4.0.0 - - org.apache.dubbo - dubbo-parent - ${revision} - ../pom.xml - - - dubbo-kubernetes - ${project.artifactId} - The Kubernetes Integration - - false - - - - - org.apache.dubbo - dubbo-registry-api - ${project.parent.version} - - - org.apache.dubbo - dubbo-common - ${project.parent.version} - - - org.apache.dubbo - dubbo-metadata-api - ${project.parent.version} - - - io.fabric8 - kubernetes-client - - - io.fabric8 - kubernetes-server-mock - test - - - org.mockito - mockito-junit-jupiter - 3.12.4 - test - - - org.junit.jupiter - junit-jupiter-api - - - - - - diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java deleted file mode 100644 index 43e79862fe6..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java +++ /dev/null @@ -1,207 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener; -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListener; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.fabric8.kubernetes.api.model.GenericKubernetesResource; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; -import io.fabric8.kubernetes.client.WatcherException; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_LISTEN_KUBERNETES; - -public class KubernetesMeshEnvListener implements MeshEnvListener { - public static final ErrorTypeAwareLogger logger = - LoggerFactory.getErrorTypeAwareLogger(KubernetesMeshEnvListener.class); - private static volatile boolean usingApiServer = false; - private static volatile KubernetesClient kubernetesClient; - private static volatile String namespace; - - private final Map appRuleListenerMap = new ConcurrentHashMap<>(); - - private final Map vsAppWatch = new ConcurrentHashMap<>(); - private final Map drAppWatch = new ConcurrentHashMap<>(); - - private final Map vsAppCache = new ConcurrentHashMap<>(); - private final Map drAppCache = new ConcurrentHashMap<>(); - - public static void injectKubernetesEnv(KubernetesClient client, String configuredNamespace) { - usingApiServer = true; - kubernetesClient = client; - namespace = configuredNamespace; - } - - @Override - public boolean isEnable() { - return usingApiServer; - } - - @Override - public void onSubscribe(String appName, MeshAppRuleListener listener) { - appRuleListenerMap.put(appName, listener); - logger.info("Subscribe Mesh Rule in Kubernetes. AppName: " + appName); - - // subscribe VisualService - subscribeVs(appName); - - // subscribe DestinationRule - subscribeDr(appName); - - // notify for start - notifyOnce(appName); - } - - private void subscribeVs(String appName) { - if (vsAppWatch.containsKey(appName)) { - return; - } - - try { - Watch watch = kubernetesClient - .genericKubernetesResources(MeshConstant.getVsDefinition()) - .inNamespace(namespace) - .withName(appName) - .watch(new Watcher() { - @Override - public void eventReceived(Action action, GenericKubernetesResource resource) { - if (logger.isInfoEnabled()) { - logger.info("Received VS Rule notification. AppName: " + appName + " Action:" + action - + " Resource:" + resource); - } - - if (action == Action.ADDED || action == Action.MODIFIED) { - String vsRule = new Yaml(new SafeConstructor(new LoaderOptions())).dump(resource); - vsAppCache.put(appName, vsRule); - if (drAppCache.containsKey(appName)) { - notifyListener(vsRule, appName, drAppCache.get(appName)); - } - } else { - appRuleListenerMap.get(appName).receiveConfigInfo(""); - } - } - - @Override - public void onClose(WatcherException cause) { - // ignore - } - }); - vsAppWatch.put(appName, watch); - try { - GenericKubernetesResource vsRule = kubernetesClient - .genericKubernetesResources(MeshConstant.getVsDefinition()) - .inNamespace(namespace) - .withName(appName) - .get(); - vsAppCache.put(appName, new Yaml(new SafeConstructor(new LoaderOptions())).dump(vsRule)); - } catch (Throwable ignore) { - - } - } catch (Exception e) { - logger.error(REGISTRY_ERROR_LISTEN_KUBERNETES, "", "", "Error occurred when listen kubernetes crd.", e); - } - } - - private void notifyListener(String vsRule, String appName, String drRule) { - String rule = vsRule + "\n---\n" + drRule; - logger.info("Notify App Rule Listener. AppName: " + appName + " Rule:" + rule); - - appRuleListenerMap.get(appName).receiveConfigInfo(rule); - } - - private void subscribeDr(String appName) { - if (drAppWatch.containsKey(appName)) { - return; - } - - try { - Watch watch = kubernetesClient - .genericKubernetesResources(MeshConstant.getDrDefinition()) - .inNamespace(namespace) - .withName(appName) - .watch(new Watcher() { - @Override - public void eventReceived(Action action, GenericKubernetesResource resource) { - if (logger.isInfoEnabled()) { - logger.info("Received VS Rule notification. AppName: " + appName + " Action:" + action - + " Resource:" + resource); - } - - if (action == Action.ADDED || action == Action.MODIFIED) { - String drRule = new Yaml(new SafeConstructor(new LoaderOptions())).dump(resource); - - drAppCache.put(appName, drRule); - if (vsAppCache.containsKey(appName)) { - notifyListener(vsAppCache.get(appName), appName, drRule); - } - } else { - appRuleListenerMap.get(appName).receiveConfigInfo(""); - } - } - - @Override - public void onClose(WatcherException cause) { - // ignore - } - }); - drAppWatch.put(appName, watch); - try { - GenericKubernetesResource drRule = kubernetesClient - .genericKubernetesResources(MeshConstant.getDrDefinition()) - .inNamespace(namespace) - .withName(appName) - .get(); - drAppCache.put(appName, new Yaml(new SafeConstructor(new LoaderOptions())).dump(drRule)); - } catch (Throwable ignore) { - - } - } catch (Exception e) { - logger.error(REGISTRY_ERROR_LISTEN_KUBERNETES, "", "", "Error occurred when listen kubernetes crd.", e); - } - } - - private void notifyOnce(String appName) { - if (vsAppCache.containsKey(appName) && drAppCache.containsKey(appName)) { - notifyListener(vsAppCache.get(appName), appName, drAppCache.get(appName)); - } - } - - @Override - public void onUnSubscribe(String appName) { - appRuleListenerMap.remove(appName); - - if (vsAppWatch.containsKey(appName)) { - vsAppWatch.remove(appName).close(); - } - vsAppCache.remove(appName); - - if (drAppWatch.containsKey(appName)) { - drAppWatch.remove(appName).close(); - } - drAppCache.remove(appName); - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java deleted file mode 100644 index 9d1c6d06cfa..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java +++ /dev/null @@ -1,42 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.logger.Logger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListener; -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory; - -import java.util.concurrent.atomic.AtomicBoolean; - -public class KubernetesMeshEnvListenerFactory implements MeshEnvListenerFactory { - public static final Logger logger = LoggerFactory.getLogger(KubernetesMeshEnvListenerFactory.class); - private final AtomicBoolean initialized = new AtomicBoolean(false); - private MeshEnvListener listener = null; - - @Override - public MeshEnvListener getListener() { - try { - if (initialized.compareAndSet(false, true)) { - listener = new NopKubernetesMeshEnvListener(); - } - } catch (Throwable t) { - logger.info("Current Env not support Kubernetes."); - } - return listener; - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java deleted file mode 100644 index 2d51c1bfa2a..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java +++ /dev/null @@ -1,50 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.registry.NotifyListener; -import org.apache.dubbo.registry.support.FailbackRegistry; - -/** - * Empty implements for Kubernetes
- * Kubernetes only support `Service Discovery` mode register
- * Used to compat past version like 2.6.x, 2.7.x with interface level register
- * {@link KubernetesServiceDiscovery} is the real implementation of Kubernetes - */ -public class KubernetesRegistry extends FailbackRegistry { - public KubernetesRegistry(URL url) { - super(url); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public void doRegister(URL url) {} - - @Override - public void doUnregister(URL url) {} - - @Override - public void doSubscribe(URL url, NotifyListener listener) {} - - @Override - public void doUnsubscribe(URL url, NotifyListener listener) {} -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java deleted file mode 100644 index fe0e0477d7b..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java +++ /dev/null @@ -1,34 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.registry.Registry; -import org.apache.dubbo.registry.support.AbstractRegistryFactory; - -public class KubernetesRegistryFactory extends AbstractRegistryFactory { - - @Override - protected String createRegistryCacheKey(URL url) { - return url.toFullString(); - } - - @Override - protected Registry createRegistry(URL url) { - return new KubernetesRegistry(url); - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java deleted file mode 100644 index 7792abdd2b1..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java +++ /dev/null @@ -1,451 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.JsonUtils; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.registry.client.AbstractServiceDiscovery; -import org.apache.dubbo.registry.client.DefaultServiceInstance; -import org.apache.dubbo.registry.client.ServiceInstance; -import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; -import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; -import org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst; -import org.apache.dubbo.registry.kubernetes.util.KubernetesConfigUtils; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; - -import io.fabric8.kubernetes.api.model.EndpointAddress; -import io.fabric8.kubernetes.api.model.EndpointPort; -import io.fabric8.kubernetes.api.model.EndpointSubset; -import io.fabric8.kubernetes.api.model.Endpoints; -import io.fabric8.kubernetes.api.model.Pod; -import io.fabric8.kubernetes.api.model.PodBuilder; -import io.fabric8.kubernetes.api.model.Service; -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientBuilder; -import io.fabric8.kubernetes.client.informers.ResourceEventHandler; -import io.fabric8.kubernetes.client.informers.SharedIndexInformer; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_UNABLE_ACCESS_KUBERNETES; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_UNABLE_FIND_SERVICE_KUBERNETES; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_UNABLE_MATCH_KUBERNETES; - -public class KubernetesServiceDiscovery extends AbstractServiceDiscovery { - private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass()); - - private KubernetesClient kubernetesClient; - - private String currentHostname; - - private final URL registryURL; - - private final String namespace; - - private final boolean enableRegister; - - public static final String KUBERNETES_PROPERTIES_KEY = "io.dubbo/metadata"; - - private static final ConcurrentHashMap SERVICE_UPDATE_TIME = new ConcurrentHashMap<>(64); - - private static final ConcurrentHashMap> SERVICE_INFORMER = - new ConcurrentHashMap<>(64); - - private static final ConcurrentHashMap> PODS_INFORMER = - new ConcurrentHashMap<>(64); - - private static final ConcurrentHashMap> ENDPOINTS_INFORMER = - new ConcurrentHashMap<>(64); - - public KubernetesServiceDiscovery(ApplicationModel applicationModel, URL registryURL) { - super(applicationModel, registryURL); - Config config = KubernetesConfigUtils.createKubernetesConfig(registryURL); - this.kubernetesClient = new KubernetesClientBuilder().withConfig(config).build(); - this.currentHostname = System.getenv("HOSTNAME"); - this.registryURL = registryURL; - this.namespace = config.getNamespace(); - this.enableRegister = registryURL.getParameter(KubernetesClientConst.ENABLE_REGISTER, true); - - boolean availableAccess; - try { - availableAccess = kubernetesClient.pods().withName(currentHostname).get() != null; - } catch (Throwable e) { - availableAccess = false; - } - if (!availableAccess) { - String message = "Unable to access api server. " + "Please check your url config." - + " Master URL: " - + config.getMasterUrl() + " Hostname: " - + currentHostname; - logger.error(REGISTRY_UNABLE_ACCESS_KUBERNETES, "", "", message); - } else { - KubernetesMeshEnvListener.injectKubernetesEnv(kubernetesClient, namespace); - } - } - - @Override - public void doDestroy() { - SERVICE_INFORMER.forEach((k, v) -> v.close()); - SERVICE_INFORMER.clear(); - - PODS_INFORMER.forEach((k, v) -> v.close()); - PODS_INFORMER.clear(); - - ENDPOINTS_INFORMER.forEach((k, v) -> v.close()); - ENDPOINTS_INFORMER.clear(); - - kubernetesClient.close(); - } - - @Override - public void doRegister(ServiceInstance serviceInstance) throws RuntimeException { - if (enableRegister) { - kubernetesClient - .pods() - .inNamespace(namespace) - .withName(currentHostname) - .edit(pod -> new PodBuilder(pod) - .editOrNewMetadata() - .addToAnnotations( - KUBERNETES_PROPERTIES_KEY, JsonUtils.toJson(serviceInstance.getMetadata())) - .endMetadata() - .build()); - if (logger.isInfoEnabled()) { - logger.info("Write Current Service Instance Metadata to Kubernetes pod. " + "Current pod name: " - + currentHostname); - } - } - } - - /** - * Comparing to {@link AbstractServiceDiscovery#doUpdate(ServiceInstance, ServiceInstance)}, unregister() is unnecessary here. - */ - @Override - public void doUpdate(ServiceInstance oldServiceInstance, ServiceInstance newServiceInstance) - throws RuntimeException { - reportMetadata(newServiceInstance.getServiceMetadata()); - this.doRegister(newServiceInstance); - } - - @Override - public void doUnregister(ServiceInstance serviceInstance) throws RuntimeException { - if (enableRegister) { - kubernetesClient - .pods() - .inNamespace(namespace) - .withName(currentHostname) - .edit(pod -> new PodBuilder(pod) - .editOrNewMetadata() - .removeFromAnnotations(KUBERNETES_PROPERTIES_KEY) - .endMetadata() - .build()); - if (logger.isInfoEnabled()) { - logger.info( - "Remove Current Service Instance from Kubernetes pod. Current pod name: " + currentHostname); - } - } - } - - @Override - public Set getServices() { - return kubernetesClient.services().inNamespace(namespace).list().getItems().stream() - .map(service -> service.getMetadata().getName()) - .collect(Collectors.toSet()); - } - - @Override - public List getInstances(String serviceName) throws NullPointerException { - Endpoints endpoints = null; - SharedIndexInformer endInformer = ENDPOINTS_INFORMER.get(serviceName); - if (endInformer != null) { - // get endpoints directly from informer local store - List endpointsList = endInformer.getStore().list(); - if (endpointsList.size() > 0) { - endpoints = endpointsList.get(0); - } - } - if (endpoints == null) { - endpoints = kubernetesClient - .endpoints() - .inNamespace(namespace) - .withName(serviceName) - .get(); - } - - return toServiceInstance(endpoints, serviceName); - } - - @Override - public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) - throws NullPointerException, IllegalArgumentException { - listener.getServiceNames().forEach(serviceName -> { - SERVICE_UPDATE_TIME.put(serviceName, new AtomicLong(0L)); - - // Watch Service Endpoint Modification - watchEndpoints(listener, serviceName); - - // Watch Pods Modification, happens when ServiceInstance updated - watchPods(listener, serviceName); - - // Watch Service Modification, happens when Service Selector updated, used to update pods watcher - watchService(listener, serviceName); - }); - } - - private void watchEndpoints(ServiceInstancesChangedListener listener, String serviceName) { - SharedIndexInformer endInformer = kubernetesClient - .endpoints() - .inNamespace(namespace) - .withName(serviceName) - .inform(new ResourceEventHandler() { - @Override - public void onAdd(Endpoints endpoints) { - if (logger.isDebugEnabled()) { - logger.debug("Received Endpoint Event. Event type: added. Current pod name: " - + currentHostname + ". Endpoints is: " + endpoints); - } - notifyServiceChanged(serviceName, listener, toServiceInstance(endpoints, serviceName)); - } - - @Override - public void onUpdate(Endpoints oldEndpoints, Endpoints newEndpoints) { - if (logger.isDebugEnabled()) { - logger.debug("Received Endpoint Event. Event type: updated. Current pod name: " - + currentHostname + ". The new Endpoints is: " + newEndpoints); - } - notifyServiceChanged(serviceName, listener, toServiceInstance(newEndpoints, serviceName)); - } - - @Override - public void onDelete(Endpoints endpoints, boolean deletedFinalStateUnknown) { - if (logger.isDebugEnabled()) { - logger.debug("Received Endpoint Event. Event type: deleted. Current pod name: " - + currentHostname + ". Endpoints is: " + endpoints); - } - notifyServiceChanged(serviceName, listener, toServiceInstance(endpoints, serviceName)); - } - }); - - ENDPOINTS_INFORMER.put(serviceName, endInformer); - } - - private void watchPods(ServiceInstancesChangedListener listener, String serviceName) { - Map serviceSelector = getServiceSelector(serviceName); - if (serviceSelector == null) { - return; - } - - SharedIndexInformer podInformer = kubernetesClient - .pods() - .inNamespace(namespace) - .withLabels(serviceSelector) - .inform(new ResourceEventHandler() { - @Override - public void onAdd(Pod pod) { - if (logger.isDebugEnabled()) { - logger.debug("Received Pods Event. Event type: added. Current pod name: " + currentHostname - + ". Pod is: " + pod); - } - } - - @Override - public void onUpdate(Pod oldPod, Pod newPod) { - if (logger.isDebugEnabled()) { - logger.debug("Received Pods Event. Event type: updated. Current pod name: " - + currentHostname + ". new Pod is: " + newPod); - } - - notifyServiceChanged(serviceName, listener, getInstances(serviceName)); - } - - @Override - public void onDelete(Pod pod, boolean deletedFinalStateUnknown) { - if (logger.isDebugEnabled()) { - logger.debug("Received Pods Event. Event type: deleted. Current pod name: " - + currentHostname + ". Pod is: " + pod); - } - } - }); - - PODS_INFORMER.put(serviceName, podInformer); - } - - private void watchService(ServiceInstancesChangedListener listener, String serviceName) { - SharedIndexInformer serviceInformer = kubernetesClient - .services() - .inNamespace(namespace) - .withName(serviceName) - .inform(new ResourceEventHandler() { - @Override - public void onAdd(Service service) { - if (logger.isDebugEnabled()) { - logger.debug("Received Service Added Event. " + "Current pod name: " + currentHostname); - } - } - - @Override - public void onUpdate(Service oldService, Service newService) { - if (logger.isDebugEnabled()) { - logger.debug("Received Service Update Event. Update Pods Watcher. Current pod name: " - + currentHostname + ". The new Service is: " + newService); - } - if (PODS_INFORMER.containsKey(serviceName)) { - PODS_INFORMER.get(serviceName).close(); - PODS_INFORMER.remove(serviceName); - } - watchPods(listener, serviceName); - } - - @Override - public void onDelete(Service service, boolean deletedFinalStateUnknown) { - if (logger.isDebugEnabled()) { - logger.debug("Received Service Delete Event. " + "Current pod name: " + currentHostname); - } - } - }); - - SERVICE_INFORMER.put(serviceName, serviceInformer); - } - - private void notifyServiceChanged( - String serviceName, ServiceInstancesChangedListener listener, List serviceInstanceList) { - long receivedTime = System.nanoTime(); - - ServiceInstancesChangedEvent event; - - event = new ServiceInstancesChangedEvent(serviceName, serviceInstanceList); - - AtomicLong updateTime = SERVICE_UPDATE_TIME.get(serviceName); - long lastUpdateTime = updateTime.get(); - - if (lastUpdateTime <= receivedTime) { - if (updateTime.compareAndSet(lastUpdateTime, receivedTime)) { - listener.onEvent(event); - return; - } - } - - if (logger.isInfoEnabled()) { - logger.info("Discard Service Instance Data. " - + "Possible Cause: Newer message has been processed or Failed to update time record by CAS. " - + "Current Data received time: " - + receivedTime + ". " + "Newer Data received time: " - + lastUpdateTime + "."); - } - } - - @Override - public URL getUrl() { - return registryURL; - } - - private Map getServiceSelector(String serviceName) { - Service service = kubernetesClient - .services() - .inNamespace(namespace) - .withName(serviceName) - .get(); - if (service == null) { - return null; - } - return service.getSpec().getSelector(); - } - - private List toServiceInstance(Endpoints endpoints, String serviceName) { - Map serviceSelector = getServiceSelector(serviceName); - if (serviceSelector == null) { - return new LinkedList<>(); - } - Map pods = - kubernetesClient.pods().inNamespace(namespace).withLabels(serviceSelector).list().getItems().stream() - .collect(Collectors.toMap(pod -> pod.getMetadata().getName(), pod -> pod)); - - List instances = new LinkedList<>(); - Set instancePorts = new HashSet<>(); - - for (EndpointSubset endpointSubset : endpoints.getSubsets()) { - instancePorts.addAll(endpointSubset.getPorts().stream() - .map(EndpointPort::getPort) - .collect(Collectors.toSet())); - } - - for (EndpointSubset endpointSubset : endpoints.getSubsets()) { - for (EndpointAddress address : endpointSubset.getAddresses()) { - Pod pod = pods.get(address.getTargetRef().getName()); - String ip = address.getIp(); - if (pod == null) { - logger.warn( - REGISTRY_UNABLE_MATCH_KUBERNETES, - "", - "", - "Unable to match Kubernetes Endpoint address with Pod. " + "EndpointAddress Hostname: " - + address.getTargetRef().getName()); - continue; - } - instancePorts.forEach(port -> { - ServiceInstance serviceInstance = new DefaultServiceInstance( - serviceName, ip, port, ScopeModelUtil.getApplicationModel(getUrl().getScopeModel())); - - String properties = pod.getMetadata().getAnnotations().get(KUBERNETES_PROPERTIES_KEY); - if (StringUtils.isNotEmpty(properties)) { - serviceInstance.getMetadata().putAll(JsonUtils.toJavaObject(properties, Map.class)); - instances.add(serviceInstance); - } else { - logger.warn( - REGISTRY_UNABLE_FIND_SERVICE_KUBERNETES, - "", - "", - "Unable to find Service Instance metadata in Pod Annotations. " - + "Possibly cause: provider has not been initialized successfully. " - + "EndpointAddress Hostname: " - + address.getTargetRef().getName()); - } - }); - } - } - - return instances; - } - - /** - * UT used only - */ - @Deprecated - public void setCurrentHostname(String currentHostname) { - this.currentHostname = currentHostname; - } - - /** - * UT used only - */ - @Deprecated - public void setKubernetesClient(KubernetesClient kubernetesClient) { - this.kubernetesClient = kubernetesClient; - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryFactory.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryFactory.java deleted file mode 100644 index 7d11dfaaa81..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryFactory.java +++ /dev/null @@ -1,28 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory; -import org.apache.dubbo.registry.client.ServiceDiscovery; - -public class KubernetesServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory { - @Override - protected ServiceDiscovery createDiscovery(URL registryURL) { - return new KubernetesServiceDiscovery(applicationModel, registryURL); - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/MeshConstant.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/MeshConstant.java deleted file mode 100644 index e8b8f8407fd..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/MeshConstant.java +++ /dev/null @@ -1,45 +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 org.apache.dubbo.registry.kubernetes; - -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; - -public class MeshConstant { - public static CustomResourceDefinitionContext getVsDefinition() { - // TODO cache - return new CustomResourceDefinitionContext.Builder() - .withGroup("service.dubbo.apache.org") - .withVersion("v1alpha1") - .withScope("Namespaced") - .withName("virtualservices.service.dubbo.apache.org") - .withPlural("virtualservices") - .withKind("VirtualService") - .build(); - } - - public static CustomResourceDefinitionContext getDrDefinition() { - // TODO cache - return new CustomResourceDefinitionContext.Builder() - .withGroup("service.dubbo.apache.org") - .withVersion("v1alpha1") - .withScope("Namespaced") - .withName("destinationrules.service.dubbo.apache.org") - .withPlural("destinationrules") - .withKind("DestinationRule") - .build(); - } -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/NopKubernetesMeshEnvListener.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/NopKubernetesMeshEnvListener.java deleted file mode 100644 index 818b8df64d4..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/NopKubernetesMeshEnvListener.java +++ /dev/null @@ -1,34 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener; -import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListener; - -public class NopKubernetesMeshEnvListener implements MeshEnvListener { - - @Override - public boolean isEnable() { - return false; - } - - @Override - public void onSubscribe(String appName, MeshAppRuleListener listener) {} - - @Override - public void onUnSubscribe(String appName) {} -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesClientConst.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesClientConst.java deleted file mode 100644 index b7ace538947..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesClientConst.java +++ /dev/null @@ -1,78 +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 org.apache.dubbo.registry.kubernetes.util; - -public class KubernetesClientConst { - public static final String DEFAULT_MASTER_PLACEHOLDER = "DEFAULT_MASTER_HOST"; - public static final String DEFAULT_MASTER_URL = "https://kubernetes.default.svc"; - - public static final String ENABLE_REGISTER = "enableRegister"; - - public static final String TRUST_CERTS = "trustCerts"; - - public static final String USE_HTTPS = "useHttps"; - - public static final String HTTP2_DISABLE = "http2Disable"; - - public static final String NAMESPACE = "namespace"; - - public static final String API_VERSION = "apiVersion"; - - public static final String CA_CERT_FILE = "caCertFile"; - - public static final String CA_CERT_DATA = "caCertData"; - - public static final String CLIENT_CERT_FILE = "clientCertFile"; - - public static final String CLIENT_CERT_DATA = "clientCertData"; - - public static final String CLIENT_KEY_FILE = "clientKeyFile"; - - public static final String CLIENT_KEY_DATA = "clientKeyData"; - - public static final String CLIENT_KEY_ALGO = "clientKeyAlgo"; - - public static final String CLIENT_KEY_PASSPHRASE = "clientKeyPassphrase"; - - public static final String OAUTH_TOKEN = "oauthToken"; - - public static final String USERNAME = "username"; - - public static final String PASSWORD = "password"; - - public static final String WATCH_RECONNECT_INTERVAL = "watchReconnectInterval"; - - public static final String WATCH_RECONNECT_LIMIT = "watchReconnectLimit"; - - public static final String CONNECTION_TIMEOUT = "connectionTimeout"; - - public static final String REQUEST_TIMEOUT = "requestTimeout"; - - public static final String ROLLING_TIMEOUT = "rollingTimeout"; - - public static final String LOGGING_INTERVAL = "loggingInterval"; - - public static final String HTTP_PROXY = "httpProxy"; - - public static final String HTTPS_PROXY = "httpsProxy"; - - public static final String PROXY_USERNAME = "proxyUsername"; - - public static final String PROXY_PASSWORD = "proxyPassword"; - - public static final String NO_PROXY = "noProxy"; -} diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java deleted file mode 100644 index 332bb6e7333..00000000000 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/util/KubernetesConfigUtils.java +++ /dev/null @@ -1,104 +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 org.apache.dubbo.registry.kubernetes.util; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.StringUtils; - -import java.util.Base64; - -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.ConfigBuilder; - -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.API_VERSION; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CA_CERT_DATA; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CA_CERT_FILE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_CERT_DATA; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_CERT_FILE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_KEY_ALGO; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_KEY_DATA; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_KEY_FILE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CLIENT_KEY_PASSPHRASE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.CONNECTION_TIMEOUT; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.DEFAULT_MASTER_PLACEHOLDER; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.DEFAULT_MASTER_URL; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.HTTP2_DISABLE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.HTTPS_PROXY; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.HTTP_PROXY; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.LOGGING_INTERVAL; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.NAMESPACE; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.NO_PROXY; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.OAUTH_TOKEN; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.PASSWORD; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.PROXY_PASSWORD; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.PROXY_USERNAME; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.REQUEST_TIMEOUT; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.TRUST_CERTS; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.USERNAME; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.USE_HTTPS; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.WATCH_RECONNECT_INTERVAL; -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.WATCH_RECONNECT_LIMIT; - -public class KubernetesConfigUtils { - - public static Config createKubernetesConfig(URL url) { - // Init default config - Config base = Config.autoConfigure(null); - - // replace config with parameters if presents - return new ConfigBuilder(base) // - .withMasterUrl(buildMasterUrl(url)) // - .withApiVersion(url.getParameter(API_VERSION, base.getApiVersion())) // - .withNamespace(url.getParameter(NAMESPACE, base.getNamespace())) // - .withUsername(url.getParameter(USERNAME, base.getUsername())) // - .withPassword(url.getParameter(PASSWORD, base.getPassword())) // - .withOauthToken(url.getParameter(OAUTH_TOKEN, base.getOauthToken())) // - .withCaCertFile(url.getParameter(CA_CERT_FILE, base.getCaCertFile())) // - .withCaCertData(url.getParameter(CA_CERT_DATA, decodeBase64(base.getCaCertData()))) // - .withClientKeyFile(url.getParameter(CLIENT_KEY_FILE, base.getClientKeyFile())) // - .withClientKeyData(url.getParameter(CLIENT_KEY_DATA, decodeBase64(base.getClientKeyData()))) // - .withClientCertFile(url.getParameter(CLIENT_CERT_FILE, base.getClientCertFile())) // - .withClientCertData(url.getParameter(CLIENT_CERT_DATA, decodeBase64(base.getClientCertData()))) // - .withClientKeyAlgo(url.getParameter(CLIENT_KEY_ALGO, base.getClientKeyAlgo())) // - .withClientKeyPassphrase(url.getParameter(CLIENT_KEY_PASSPHRASE, base.getClientKeyPassphrase())) // - .withConnectionTimeout(url.getParameter(CONNECTION_TIMEOUT, base.getConnectionTimeout())) // - .withRequestTimeout(url.getParameter(REQUEST_TIMEOUT, base.getRequestTimeout())) // - .withWatchReconnectInterval( - url.getParameter(WATCH_RECONNECT_INTERVAL, base.getWatchReconnectInterval())) // - .withWatchReconnectLimit(url.getParameter(WATCH_RECONNECT_LIMIT, base.getWatchReconnectLimit())) // - .withLoggingInterval(url.getParameter(LOGGING_INTERVAL, base.getLoggingInterval())) // - .withTrustCerts(url.getParameter(TRUST_CERTS, base.isTrustCerts())) // - .withHttp2Disable(url.getParameter(HTTP2_DISABLE, base.isHttp2Disable())) // - .withHttpProxy(url.getParameter(HTTP_PROXY, base.getHttpProxy())) // - .withHttpsProxy(url.getParameter(HTTPS_PROXY, base.getHttpsProxy())) // - .withProxyUsername(url.getParameter(PROXY_USERNAME, base.getProxyUsername())) // - .withProxyPassword(url.getParameter(PROXY_PASSWORD, base.getProxyPassword())) // - .withNoProxy(url.getParameter(NO_PROXY, base.getNoProxy())) // - .build(); - } - - private static String buildMasterUrl(URL url) { - if (DEFAULT_MASTER_PLACEHOLDER.equalsIgnoreCase(url.getHost())) { - return DEFAULT_MASTER_URL; - } - return (url.getParameter(USE_HTTPS, true) ? "https://" : "http://") + url.getHost() + ":" + url.getPort(); - } - - private static String decodeBase64(String str) { - return StringUtils.isNotEmpty(str) ? new String(Base64.getDecoder().decode(str)) : null; - } -} diff --git a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory deleted file mode 100644 index 94177d81ea9..00000000000 --- a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory +++ /dev/null @@ -1 +0,0 @@ -kubernetes=org.apache.dubbo.registry.kubernetes.KubernetesRegistryFactory \ No newline at end of file diff --git a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory b/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory deleted file mode 100644 index 4301ab8b4b7..00000000000 --- a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory +++ /dev/null @@ -1 +0,0 @@ -kubernetes=org.apache.dubbo.registry.kubernetes.KubernetesServiceDiscoveryFactory \ No newline at end of file diff --git a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory b/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory deleted file mode 100644 index 4dfae84b80d..00000000000 --- a/dubbo-kubernetes/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory +++ /dev/null @@ -1 +0,0 @@ -kubernetes=org.apache.dubbo.registry.kubernetes.KubernetesMeshEnvListenerFactory diff --git a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java deleted file mode 100644 index 6f47be60152..00000000000 --- a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java +++ /dev/null @@ -1,289 +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 org.apache.dubbo.registry.kubernetes; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.registry.client.DefaultServiceInstance; -import org.apache.dubbo.registry.client.ServiceInstance; -import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; -import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; -import org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import io.fabric8.kubernetes.api.model.Endpoints; -import io.fabric8.kubernetes.api.model.EndpointsBuilder; -import io.fabric8.kubernetes.api.model.Pod; -import io.fabric8.kubernetes.api.model.PodBuilder; -import io.fabric8.kubernetes.api.model.Service; -import io.fabric8.kubernetes.api.model.ServiceBuilder; -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.NamespacedKubernetesClient; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.NAMESPACE; -import static org.awaitility.Awaitility.await; - -@ExtendWith({MockitoExtension.class}) -class KubernetesServiceDiscoveryTest { - - private static final String SERVICE_NAME = "TestService"; - - private static final String POD_NAME = "TestServer"; - - public KubernetesServer mockServer = new KubernetesServer(false, true); - - private NamespacedKubernetesClient mockClient; - - private ServiceInstancesChangedListener mockListener = Mockito.mock(ServiceInstancesChangedListener.class); - - private URL serverUrl; - - private Map selector; - - private KubernetesServiceDiscovery serviceDiscovery; - - @BeforeEach - public void setUp() { - mockServer.before(); - mockClient = mockServer.getClient().inNamespace("dubbo-demo"); - - ApplicationModel applicationModel = ApplicationModel.defaultModel(); - applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig()); - - serverUrl = URL.valueOf(mockClient.getConfiguration().getMasterUrl()) - .setProtocol("kubernetes") - .addParameter(NAMESPACE, "dubbo-demo") - .addParameter(KubernetesClientConst.USE_HTTPS, "false") - .addParameter(KubernetesClientConst.HTTP2_DISABLE, "true"); - serverUrl.setScopeModel(applicationModel); - - this.serviceDiscovery = new KubernetesServiceDiscovery(applicationModel, serverUrl); - - System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); - - selector = new HashMap<>(4); - selector.put("l", "v"); - Pod pod = new PodBuilder() - .withNewMetadata() - .withName(POD_NAME) - .withLabels(selector) - .endMetadata() - .build(); - - Service service = new ServiceBuilder() - .withNewMetadata() - .withName(SERVICE_NAME) - .endMetadata() - .withNewSpec() - .withSelector(selector) - .endSpec() - .build(); - - Endpoints endPoints = new EndpointsBuilder() - .withNewMetadata() - .withName(SERVICE_NAME) - .endMetadata() - .addNewSubset() - .addNewAddress() - .withIp("ip1") - .withNewTargetRef() - .withUid("uid1") - .withName(POD_NAME) - .endTargetRef() - .endAddress() - .addNewPort("Test", "Test", 12345, "TCP") - .endSubset() - .build(); - - mockClient.pods().resource(pod).create(); - mockClient.services().resource(service).create(); - mockClient.endpoints().resource(endPoints).create(); - } - - @AfterEach - public void destroy() throws Exception { - serviceDiscovery.destroy(); - mockClient.close(); - mockServer.after(); - } - - @Test - void testEndpointsUpdate() { - serviceDiscovery.setCurrentHostname(POD_NAME); - serviceDiscovery.setKubernetesClient(mockClient); - - ServiceInstance serviceInstance = new DefaultServiceInstance( - SERVICE_NAME, - "Test", - 12345, - ScopeModelUtil.getApplicationModel(serviceDiscovery.getUrl().getScopeModel())); - - serviceDiscovery.doRegister(serviceInstance); - - HashSet serviceList = new HashSet<>(4); - serviceList.add(SERVICE_NAME); - Mockito.when(mockListener.getServiceNames()).thenReturn(serviceList); - Mockito.doNothing().when(mockListener).onEvent(Mockito.any()); - - serviceDiscovery.addServiceInstancesChangedListener(mockListener); - mockClient.endpoints().withName(SERVICE_NAME).edit(endpoints -> new EndpointsBuilder(endpoints) - .editFirstSubset() - .addNewAddress() - .withIp("ip2") - .withNewTargetRef() - .withUid("uid2") - .withName(POD_NAME) - .endTargetRef() - .endAddress() - .endSubset() - .build()); - - await().until(() -> { - ArgumentCaptor captor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.atLeast(0)).onEvent(captor.capture()); - return captor.getValue().getServiceInstances().size() == 2; - }); - ArgumentCaptor eventArgumentCaptor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.times(2)).onEvent(eventArgumentCaptor.capture()); - Assertions.assertEquals( - 2, eventArgumentCaptor.getValue().getServiceInstances().size()); - - serviceDiscovery.doUnregister(serviceInstance); - } - - @Test - void testPodsUpdate() throws Exception { - serviceDiscovery.setCurrentHostname(POD_NAME); - serviceDiscovery.setKubernetesClient(mockClient); - - ServiceInstance serviceInstance = new DefaultServiceInstance( - SERVICE_NAME, - "Test", - 12345, - ScopeModelUtil.getApplicationModel(serviceDiscovery.getUrl().getScopeModel())); - - serviceDiscovery.doRegister(serviceInstance); - - HashSet serviceList = new HashSet<>(4); - serviceList.add(SERVICE_NAME); - Mockito.when(mockListener.getServiceNames()).thenReturn(serviceList); - Mockito.doNothing().when(mockListener).onEvent(Mockito.any()); - - serviceDiscovery.addServiceInstancesChangedListener(mockListener); - - serviceInstance = new DefaultServiceInstance( - SERVICE_NAME, - "Test12345", - 12345, - ScopeModelUtil.getApplicationModel(serviceDiscovery.getUrl().getScopeModel())); - serviceDiscovery.doUpdate(serviceInstance, serviceInstance); - - await().until(() -> { - ArgumentCaptor captor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.atLeast(0)).onEvent(captor.capture()); - return captor.getValue().getServiceInstances().size() == 1; - }); - ArgumentCaptor eventArgumentCaptor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.times(1)).onEvent(eventArgumentCaptor.capture()); - Assertions.assertEquals( - 1, eventArgumentCaptor.getValue().getServiceInstances().size()); - - serviceDiscovery.doUnregister(serviceInstance); - } - - @Test - void testServiceUpdate() { - serviceDiscovery.setCurrentHostname(POD_NAME); - serviceDiscovery.setKubernetesClient(mockClient); - - ServiceInstance serviceInstance = new DefaultServiceInstance( - SERVICE_NAME, - "Test", - 12345, - ScopeModelUtil.getApplicationModel(serviceDiscovery.getUrl().getScopeModel())); - - serviceDiscovery.doRegister(serviceInstance); - - HashSet serviceList = new HashSet<>(4); - serviceList.add(SERVICE_NAME); - Mockito.when(mockListener.getServiceNames()).thenReturn(serviceList); - Mockito.doNothing().when(mockListener).onEvent(Mockito.any()); - - serviceDiscovery.addServiceInstancesChangedListener(mockListener); - - selector.put("app", "test"); - mockClient.services().withName(SERVICE_NAME).edit(service -> new ServiceBuilder(service) - .editSpec() - .addToSelector(selector) - .endSpec() - .build()); - - await().until(() -> { - ArgumentCaptor captor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.atLeast(0)).onEvent(captor.capture()); - return captor.getValue().getServiceInstances().size() == 1; - }); - ArgumentCaptor eventArgumentCaptor = - ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class); - Mockito.verify(mockListener, Mockito.times(1)).onEvent(eventArgumentCaptor.capture()); - Assertions.assertEquals( - 1, eventArgumentCaptor.getValue().getServiceInstances().size()); - - serviceDiscovery.doUnregister(serviceInstance); - } - - @Test - void testGetInstance() { - serviceDiscovery.setCurrentHostname(POD_NAME); - serviceDiscovery.setKubernetesClient(mockClient); - - ServiceInstance serviceInstance = new DefaultServiceInstance( - SERVICE_NAME, - "Test", - 12345, - ScopeModelUtil.getApplicationModel(serviceDiscovery.getUrl().getScopeModel())); - - serviceDiscovery.doRegister(serviceInstance); - - serviceDiscovery.doUpdate(serviceInstance, serviceInstance); - - Assertions.assertEquals(1, serviceDiscovery.getServices().size()); - Assertions.assertEquals(1, serviceDiscovery.getInstances(SERVICE_NAME).size()); - - serviceDiscovery.doUnregister(serviceInstance); - } -} diff --git a/dubbo-kubernetes/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/dubbo-kubernetes/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea8e..00000000000 --- a/dubbo-kubernetes/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index b39ac92a5cd..b0632440c54 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -120,13 +120,6 @@ ${project.version} - - - org.apache.dubbo - dubbo-kubernetes - ${project.version} - - org.apache.dubbo @@ -471,11 +464,5 @@ ${project.version} - - - org.apache.dubbo - dubbo-xds - ${project.version} - diff --git a/dubbo-xds/pom.xml b/dubbo-xds/pom.xml deleted file mode 100644 index 9e9ef216d20..00000000000 --- a/dubbo-xds/pom.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - 4.0.0 - - org.apache.dubbo - dubbo-parent - ${revision} - ../pom.xml - - - dubbo-xds - ${project.artifactId} - The xDS Integration - - false - - - - - - org.apache.dubbo - dubbo-registry-api - ${project.version} - - - - org.apache.dubbo - dubbo-common - ${project.version} - - - - io.grpc - grpc-protobuf - - - - io.grpc - grpc-stub - - - - io.grpc - grpc-netty-shaded - - - - io.envoyproxy.controlplane - api - - - - com.google.protobuf - protobuf-java - - - - com.google.protobuf - protobuf-java-util - - - - org.bouncycastle - bcprov-jdk15on - - - org.bouncycastle - bcpkix-jdk15on - - - org.bouncycastle - bcprov-ext-jdk15on - - - - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - ${maven_protobuf_plugin_version} - - com.google.protobuf:protoc:${protobuf-java_version}:exe:${os.detected.classifier} - grpc-java - io.grpc:protoc-gen-grpc-java:${grpc_version}:exe:${os.detected.classifier} - - - - - compile - compile-custom - - - - - - - - kr.motd.maven - os-maven-plugin - ${maven_os_plugin_version} - - - - - diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsCertificateSigner.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsCertificateSigner.java deleted file mode 100644 index 1ef1a8b31cf..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsCertificateSigner.java +++ /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 org.apache.dubbo.registry.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.extension.Adaptive; -import org.apache.dubbo.common.extension.SPI; - -@SPI -public interface XdsCertificateSigner { - - @Adaptive(value = "signer") - CertPair GenerateCert(URL url); - - class CertPair { - private final String privateKey; - private final String publicKey; - private final long createTime; - private final long expireTime; - - public CertPair(String privateKey, String publicKey, long createTime, long expireTime) { - this.privateKey = privateKey; - this.publicKey = publicKey; - this.createTime = createTime; - this.expireTime = expireTime; - } - - public String getPrivateKey() { - return privateKey; - } - - public String getPublicKey() { - return publicKey; - } - - public long getCreateTime() { - return createTime; - } - - public boolean isExpire() { - return System.currentTimeMillis() < expireTime; - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsEnv.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsEnv.java deleted file mode 100644 index c09ea808773..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsEnv.java +++ /dev/null @@ -1,22 +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 org.apache.dubbo.registry.xds; - -public interface XdsEnv { - - String getCluster(); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsInitializationException.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsInitializationException.java deleted file mode 100644 index 9a9b9a35cae..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsInitializationException.java +++ /dev/null @@ -1,28 +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 org.apache.dubbo.registry.xds; - -public final class XdsInitializationException extends Exception { - - public XdsInitializationException(String message) { - super(message); - } - - public XdsInitializationException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistry.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistry.java deleted file mode 100644 index 30e005ffe76..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistry.java +++ /dev/null @@ -1,50 +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 org.apache.dubbo.registry.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.registry.NotifyListener; -import org.apache.dubbo.registry.support.FailbackRegistry; - -/** - * Empty implements for xDS
- * xDS only support `Service Discovery` mode register
- * Used to compat past version like 2.6.x, 2.7.x with interface level register
- * {@link XdsServiceDiscovery} is the real implementation of xDS - */ -public class XdsRegistry extends FailbackRegistry { - public XdsRegistry(URL url) { - super(url); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public void doRegister(URL url) {} - - @Override - public void doUnregister(URL url) {} - - @Override - public void doSubscribe(URL url, NotifyListener listener) {} - - @Override - public void doUnsubscribe(URL url, NotifyListener listener) {} -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistryFactory.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistryFactory.java deleted file mode 100644 index 8fa130b1976..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsRegistryFactory.java +++ /dev/null @@ -1,34 +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 org.apache.dubbo.registry.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.registry.Registry; -import org.apache.dubbo.registry.support.AbstractRegistryFactory; - -public class XdsRegistryFactory extends AbstractRegistryFactory { - - @Override - protected String createRegistryCacheKey(URL url) { - return url.toFullString(); - } - - @Override - protected Registry createRegistry(URL url) { - return new XdsRegistry(url); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscovery.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscovery.java deleted file mode 100644 index 3385ff97a08..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscovery.java +++ /dev/null @@ -1,117 +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 org.apache.dubbo.registry.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.client.DefaultServiceInstance; -import org.apache.dubbo.registry.client.ReflectionBasedServiceDiscovery; -import org.apache.dubbo.registry.client.ServiceInstance; -import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; -import org.apache.dubbo.registry.xds.util.PilotExchanger; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; - -import java.util.Collection; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_INITIALIZE_XDS; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_PARSING_XDS; - -public class XdsServiceDiscovery extends ReflectionBasedServiceDiscovery { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(XdsServiceDiscovery.class); - - private PilotExchanger exchanger; - - public XdsServiceDiscovery(ApplicationModel applicationModel, URL registryURL) { - super(applicationModel, registryURL); - } - - @Override - public void doInitialize(URL registryURL) { - try { - exchanger = PilotExchanger.initialize(registryURL); - } catch (Throwable t) { - logger.error(REGISTRY_ERROR_INITIALIZE_XDS, "", "", t.getMessage(), t); - } - } - - @Override - public void doDestroy() { - try { - if (exchanger == null) { - return; - } - exchanger.destroy(); - } catch (Throwable t) { - logger.error(REGISTRY_ERROR_INITIALIZE_XDS, "", "", t.getMessage(), t); - } - } - - @Override - public Set getServices() { - return exchanger.getServices(); - } - - @Override - public List getInstances(String serviceName) throws NullPointerException { - Set endpoints = exchanger.getEndpoints(serviceName); - return changedToInstances(serviceName, endpoints); - } - - @Override - public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) - throws NullPointerException, IllegalArgumentException { - listener.getServiceNames() - .forEach(serviceName -> exchanger.observeEndpoints( - serviceName, - (endpoints -> - notifyListener(serviceName, listener, changedToInstances(serviceName, endpoints))))); - } - - private List changedToInstances(String serviceName, Collection endpoints) { - List instances = new LinkedList<>(); - endpoints.forEach(endpoint -> { - try { - DefaultServiceInstance serviceInstance = new DefaultServiceInstance( - serviceName, - endpoint.getAddress(), - endpoint.getPortValue(), - ScopeModelUtil.getApplicationModel(getUrl().getScopeModel())); - // fill metadata by SelfHostMetaServiceDiscovery, will be fetched by RPC request - serviceInstance.putExtendParam("clusterName", endpoint.getClusterName()); - fillServiceInstance(serviceInstance); - instances.add(serviceInstance); - } catch (Throwable t) { - logger.error( - REGISTRY_ERROR_PARSING_XDS, - "", - "", - "Error occurred when parsing endpoints. Endpoints List:" + endpoints, - t); - } - }); - instances.sort(Comparator.comparingInt(ServiceInstance::hashCode)); - return instances; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscoveryFactory.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscoveryFactory.java deleted file mode 100644 index 0f763c59c9a..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/XdsServiceDiscoveryFactory.java +++ /dev/null @@ -1,48 +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 org.apache.dubbo.registry.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory; -import org.apache.dubbo.registry.client.ServiceDiscovery; -import org.apache.dubbo.rpc.model.ApplicationModel; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_INITIALIZE_XDS; - -public class XdsServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory { - - private static final ErrorTypeAwareLogger logger = - LoggerFactory.getErrorTypeAwareLogger(XdsServiceDiscoveryFactory.class); - - @Override - protected ServiceDiscovery createDiscovery(URL registryURL) { - XdsServiceDiscovery xdsServiceDiscovery = new XdsServiceDiscovery(ApplicationModel.defaultModel(), registryURL); - try { - xdsServiceDiscovery.doInitialize(registryURL); - } catch (Exception e) { - logger.error( - REGISTRY_ERROR_INITIALIZE_XDS, - "", - "", - "Error occurred when initialize xDS service discovery impl.", - e); - } - return xdsServiceDiscovery; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioCitadelCertificateSigner.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioCitadelCertificateSigner.java deleted file mode 100644 index db54ea56287..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioCitadelCertificateSigner.java +++ /dev/null @@ -1,294 +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 org.apache.dubbo.registry.xds.istio; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.registry.xds.XdsCertificateSigner; -import org.apache.dubbo.rpc.RpcException; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.spec.ECGenParameterSpec; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.grpc.ManagedChannel; -import io.grpc.Metadata; -import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; -import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder; -import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import io.grpc.stub.MetadataUtils; -import io.grpc.stub.StreamObserver; -import istio.v1.auth.IstioCertificateRequest; -import istio.v1.auth.IstioCertificateResponse; -import istio.v1.auth.IstioCertificateServiceGrpc; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.ExtensionsGenerator; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; -import org.bouncycastle.util.io.pem.PemObject; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_GENERATE_CERT_ISTIO; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_GENERATE_KEY_ISTIO; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_RECEIVE_ERROR_MSG_ISTIO; - -public class IstioCitadelCertificateSigner implements XdsCertificateSigner { - - private static final ErrorTypeAwareLogger logger = - LoggerFactory.getErrorTypeAwareLogger(IstioCitadelCertificateSigner.class); - - private final org.apache.dubbo.registry.xds.istio.IstioEnv istioEnv; - - private CertPair certPair; - - public IstioCitadelCertificateSigner() { - // watch cert, Refresh every 30s - ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); - scheduledThreadPool.scheduleAtFixedRate(new GenerateCertTask(), 0, 30, TimeUnit.SECONDS); - istioEnv = IstioEnv.getInstance(); - } - - @Override - public CertPair GenerateCert(URL url) { - - if (certPair != null && !certPair.isExpire()) { - return certPair; - } - return doGenerateCert(); - } - - private class GenerateCertTask implements Runnable { - @Override - public void run() { - doGenerateCert(); - } - } - - private CertPair doGenerateCert() { - synchronized (this) { - if (certPair == null || certPair.isExpire()) { - try { - certPair = createCert(); - } catch (IOException e) { - logger.error(REGISTRY_FAILED_GENERATE_CERT_ISTIO, "", "", "Generate Cert from Istio failed.", e); - throw new RpcException("Generate Cert from Istio failed.", e); - } - } - } - return certPair; - } - - public CertPair createCert() throws IOException { - PublicKey publicKey = null; - PrivateKey privateKey = null; - ContentSigner signer = null; - - if (istioEnv.isECCFirst()) { - try { - ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); - KeyPairGenerator g = KeyPairGenerator.getInstance("EC"); - g.initialize(ecSpec, new SecureRandom()); - KeyPair keypair = g.generateKeyPair(); - publicKey = keypair.getPublic(); - privateKey = keypair.getPrivate(); - signer = new JcaContentSignerBuilder("SHA256withECDSA").build(keypair.getPrivate()); - } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | OperatorCreationException e) { - logger.error( - REGISTRY_FAILED_GENERATE_KEY_ISTIO, - "", - "", - "Generate Key with secp256r1 algorithm failed. Please check if your system support. " - + "Will attempt to generate with RSA2048.", - e); - } - } - - if (publicKey == null) { - try { - KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA"); - kpGenerator.initialize(istioEnv.getRasKeySize()); - KeyPair keypair = kpGenerator.generateKeyPair(); - publicKey = keypair.getPublic(); - privateKey = keypair.getPrivate(); - signer = new JcaContentSignerBuilder("SHA256WithRSA").build(keypair.getPrivate()); - } catch (NoSuchAlgorithmException | OperatorCreationException e) { - logger.error( - REGISTRY_FAILED_GENERATE_KEY_ISTIO, - "", - "", - "Generate Key with SHA256WithRSA algorithm failed. Please check if your system support.", - e); - throw new RpcException(e); - } - } - - String csr = generateCsr(publicKey, signer); - String caCert = istioEnv.getCaCert(); - ManagedChannel channel; - if (StringUtils.isNotEmpty(caCert)) { - channel = NettyChannelBuilder.forTarget(istioEnv.getCaAddr()) - .sslContext(GrpcSslContexts.forClient() - .trustManager(new ByteArrayInputStream(caCert.getBytes(StandardCharsets.UTF_8))) - .build()) - .build(); - } else { - channel = NettyChannelBuilder.forTarget(istioEnv.getCaAddr()) - .sslContext(GrpcSslContexts.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE) - .build()) - .build(); - } - - Metadata header = new Metadata(); - Metadata.Key key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER); - header.put(key, "Bearer " + istioEnv.getServiceAccount()); - - key = Metadata.Key.of("ClusterID", Metadata.ASCII_STRING_MARSHALLER); - header.put(key, istioEnv.getIstioMetaClusterId()); - - IstioCertificateServiceGrpc.IstioCertificateServiceStub stub = IstioCertificateServiceGrpc.newStub(channel); - - stub = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(header)); - - CountDownLatch countDownLatch = new CountDownLatch(1); - StringBuffer publicKeyBuilder = new StringBuffer(); - AtomicBoolean failed = new AtomicBoolean(false); - stub.createCertificate( - generateRequest(csr), generateResponseObserver(countDownLatch, publicKeyBuilder, failed)); - - long expireTime = - System.currentTimeMillis() + (long) (istioEnv.getSecretTTL() * istioEnv.getSecretGracePeriodRatio()); - - try { - countDownLatch.await(); - } catch (InterruptedException e) { - throw new RpcException("Generate Cert Failed. Wait for cert failed.", e); - } - - if (failed.get()) { - throw new RpcException("Generate Cert Failed. Send csr request failed. Please check log above."); - } - - String privateKeyPem = generatePrivatePemKey(privateKey); - CertPair certPair = - new CertPair(privateKeyPem, publicKeyBuilder.toString(), System.currentTimeMillis(), expireTime); - - channel.shutdown(); - return certPair; - } - - private IstioCertificateRequest generateRequest(String csr) { - return IstioCertificateRequest.newBuilder() - .setCsr(csr) - .setValidityDuration(istioEnv.getSecretTTL()) - .build(); - } - - private StreamObserver generateResponseObserver( - CountDownLatch countDownLatch, StringBuffer publicKeyBuilder, AtomicBoolean failed) { - return new StreamObserver() { - @Override - public void onNext(IstioCertificateResponse istioCertificateResponse) { - for (int i = 0; i < istioCertificateResponse.getCertChainCount(); i++) { - publicKeyBuilder.append( - istioCertificateResponse.getCertChainBytes(i).toStringUtf8()); - } - if (logger.isDebugEnabled()) { - logger.debug("Receive Cert chain from Istio Citadel. \n" + publicKeyBuilder); - } - countDownLatch.countDown(); - } - - @Override - public void onError(Throwable throwable) { - failed.set(true); - logger.error( - REGISTRY_RECEIVE_ERROR_MSG_ISTIO, - "", - "", - "Receive error message from Istio Citadel grpc stub.", - throwable); - countDownLatch.countDown(); - } - - @Override - public void onCompleted() { - countDownLatch.countDown(); - } - }; - } - - private String generatePrivatePemKey(PrivateKey privateKey) throws IOException { - String key = generatePemKey("RSA PRIVATE KEY", privateKey.getEncoded()); - if (logger.isDebugEnabled()) { - logger.debug("Generated Private Key. \n" + key); - } - return key; - } - - private String generatePemKey(String type, byte[] content) throws IOException { - PemObject pemObject = new PemObject(type, content); - StringWriter str = new StringWriter(); - JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(str); - jcaPEMWriter.writeObject(pemObject); - jcaPEMWriter.close(); - str.close(); - return str.toString(); - } - - private String generateCsr(PublicKey publicKey, ContentSigner signer) throws IOException { - GeneralNames subjectAltNames = new GeneralNames(new GeneralName[] {new GeneralName(6, istioEnv.getCsrHost())}); - - ExtensionsGenerator extGen = new ExtensionsGenerator(); - extGen.addExtension(Extension.subjectAlternativeName, true, subjectAltNames); - - PKCS10CertificationRequest request = new JcaPKCS10CertificationRequestBuilder( - new X500Name("O=" + istioEnv.getTrustDomain()), publicKey) - .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate()) - .build(signer); - - String csr = generatePemKey("CERTIFICATE REQUEST", request.getEncoded()); - - if (logger.isDebugEnabled()) { - logger.debug("CSR Request to Istio Citadel. \n" + csr); - } - return csr; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioConstant.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioConstant.java deleted file mode 100644 index 018fa3a0faa..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioConstant.java +++ /dev/null @@ -1,109 +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 org.apache.dubbo.registry.xds.istio; - -public class IstioConstant { - /** - * Address of the spiffe certificate provider. Defaults to discoveryAddress - */ - public static final String CA_ADDR_KEY = "CA_ADDR"; - - /** - * CA and xDS services - */ - public static final String DEFAULT_CA_ADDR = "istiod.istio-system.svc:15012"; - - /** - * The trust domain for spiffe certificates - */ - public static final String TRUST_DOMAIN_KEY = "TRUST_DOMAIN"; - - /** - * The trust domain for spiffe certificates default value - */ - public static final String DEFAULT_TRUST_DOMAIN = "cluster.local"; - - public static final String WORKLOAD_NAMESPACE_KEY = "WORKLOAD_NAMESPACE"; - - public static final String DEFAULT_WORKLOAD_NAMESPACE = "default"; - - /** - * k8s jwt token - */ - public static final String KUBERNETES_SA_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"; - - public static final String KUBERNETES_CA_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; - - public static final String ISTIO_SA_PATH = "/var/run/secrets/tokens/istio-token"; - - public static final String ISTIO_CA_PATH = "/var/run/secrets/istio/root-cert.pem"; - - public static final String KUBERNETES_NAMESPACE_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"; - - public static final String RSA_KEY_SIZE_KEY = "RSA_KEY_SIZE"; - - public static final String DEFAULT_RSA_KEY_SIZE = "2048"; - - /** - * The type of ECC signature algorithm to use when generating private keys - */ - public static final String ECC_SIG_ALG_KEY = "ECC_SIGNATURE_ALGORITHM"; - - public static final String DEFAULT_ECC_SIG_ALG = "ECDSA"; - - /** - * The cert lifetime requested by istio agent - */ - public static final String SECRET_TTL_KEY = "SECRET_TTL"; - - /** - * The cert lifetime default value 24h0m0s - */ - public static final String DEFAULT_SECRET_TTL = "86400"; // 24 * 60 * 60 - - /** - * The grace period ratio for the cert rotation - */ - public static final String SECRET_GRACE_PERIOD_RATIO_KEY = "SECRET_GRACE_PERIOD_RATIO"; - - /** - * The grace period ratio for the cert rotation, by default 0.5 - */ - public static final String DEFAULT_SECRET_GRACE_PERIOD_RATIO = "0.5"; - - public static final String ISTIO_META_CLUSTER_ID_KEY = "ISTIO_META_CLUSTER_ID"; - - public static final String PILOT_CERT_PROVIDER_KEY = "PILOT_CERT_PROVIDER"; - - public static final String ISTIO_PILOT_CERT_PROVIDER = "istiod"; - - public static final String DEFAULT_ISTIO_META_CLUSTER_ID = "Kubernetes"; - - public static final String SPIFFE = "spiffe://"; - - public static final String NS = "/ns/"; - - public static final String SA = "/sa/"; - - public static final String JWT_POLICY = "JWT_POLICY"; - - public static final String DEFAULT_JWT_POLICY = "first-party-jwt"; - - public static final String FIRST_PARTY_JWT = "first-party-jwt"; - - public static final String THIRD_PARTY_JWT = "third-party-jwt"; -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioEnv.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioEnv.java deleted file mode 100644 index e508e7cc294..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/istio/IstioEnv.java +++ /dev/null @@ -1,195 +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 org.apache.dubbo.registry.xds.istio; - -import org.apache.dubbo.common.constants.LoggerCodeConstants; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.xds.XdsEnv; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Optional; - -import org.apache.commons.io.FileUtils; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_READ_FILE_ISTIO; -import static org.apache.dubbo.registry.xds.istio.IstioConstant.NS; -import static org.apache.dubbo.registry.xds.istio.IstioConstant.SA; -import static org.apache.dubbo.registry.xds.istio.IstioConstant.SPIFFE; - -public class IstioEnv implements XdsEnv { - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(IstioEnv.class); - - private static final IstioEnv INSTANCE = new IstioEnv(); - - private String podName; - - private String caAddr; - - private String jwtPolicy; - - private String trustDomain; - - private String workloadNameSpace; - - private int rasKeySize; - - private String eccSigAlg; - - private int secretTTL; - - private float secretGracePeriodRatio; - - private String istioMetaClusterId; - - private String pilotCertProvider; - - private IstioEnv() { - jwtPolicy = - Optional.ofNullable(System.getenv(IstioConstant.JWT_POLICY)).orElse(IstioConstant.DEFAULT_JWT_POLICY); - podName = Optional.ofNullable(System.getenv("POD_NAME")).orElse(System.getenv("HOSTNAME")); - trustDomain = Optional.ofNullable(System.getenv(IstioConstant.TRUST_DOMAIN_KEY)) - .orElse(IstioConstant.DEFAULT_TRUST_DOMAIN); - workloadNameSpace = Optional.ofNullable(System.getenv(IstioConstant.WORKLOAD_NAMESPACE_KEY)) - .orElseGet(() -> { - File namespaceFile = new File(IstioConstant.KUBERNETES_NAMESPACE_PATH); - if (namespaceFile.canRead()) { - try { - return FileUtils.readFileToString(namespaceFile, StandardCharsets.UTF_8); - } catch (IOException e) { - logger.error(REGISTRY_ERROR_READ_FILE_ISTIO, "", "", "read namespace file error", e); - } - } - return IstioConstant.DEFAULT_WORKLOAD_NAMESPACE; - }); - caAddr = Optional.ofNullable(System.getenv(IstioConstant.CA_ADDR_KEY)).orElse(IstioConstant.DEFAULT_CA_ADDR); - rasKeySize = Integer.parseInt(Optional.ofNullable(System.getenv(IstioConstant.RSA_KEY_SIZE_KEY)) - .orElse(IstioConstant.DEFAULT_RSA_KEY_SIZE)); - eccSigAlg = Optional.ofNullable(System.getenv(IstioConstant.ECC_SIG_ALG_KEY)) - .orElse(IstioConstant.DEFAULT_ECC_SIG_ALG); - secretTTL = Integer.parseInt(Optional.ofNullable(System.getenv(IstioConstant.SECRET_TTL_KEY)) - .orElse(IstioConstant.DEFAULT_SECRET_TTL)); - secretGracePeriodRatio = - Float.parseFloat(Optional.ofNullable(System.getenv(IstioConstant.SECRET_GRACE_PERIOD_RATIO_KEY)) - .orElse(IstioConstant.DEFAULT_SECRET_GRACE_PERIOD_RATIO)); - istioMetaClusterId = Optional.ofNullable(System.getenv(IstioConstant.ISTIO_META_CLUSTER_ID_KEY)) - .orElse(IstioConstant.DEFAULT_ISTIO_META_CLUSTER_ID); - pilotCertProvider = Optional.ofNullable(System.getenv(IstioConstant.PILOT_CERT_PROVIDER_KEY)) - .orElse(""); - - if (getServiceAccount() == null) { - throw new UnsupportedOperationException("Unable to found kubernetes service account token file. " - + "Please check if work in Kubernetes and mount service account token file correctly."); - } - } - - public static IstioEnv getInstance() { - return INSTANCE; - } - - public String getPodName() { - return podName; - } - - public String getCaAddr() { - return caAddr; - } - - public String getServiceAccount() { - File saFile; - switch (jwtPolicy) { - case IstioConstant.FIRST_PARTY_JWT: - saFile = new File(IstioConstant.KUBERNETES_SA_PATH); - break; - case IstioConstant.THIRD_PARTY_JWT: - default: - saFile = new File(IstioConstant.ISTIO_SA_PATH); - } - if (saFile.canRead()) { - try { - return FileUtils.readFileToString(saFile, StandardCharsets.UTF_8); - } catch (IOException e) { - logger.error( - LoggerCodeConstants.REGISTRY_ISTIO_EXCEPTION, - "File Read Failed", - "", - "Unable to read token file.", - e); - } - } - - return null; - } - - public String getCsrHost() { - // spiffe:///ns//sa/ - return SPIFFE + trustDomain + NS + workloadNameSpace + SA + getServiceAccount(); - } - - public String getTrustDomain() { - return trustDomain; - } - - public String getWorkloadNameSpace() { - return workloadNameSpace; - } - - @Override - public String getCluster() { - return null; - } - - public int getRasKeySize() { - return rasKeySize; - } - - public boolean isECCFirst() { - return IstioConstant.DEFAULT_ECC_SIG_ALG.equals(eccSigAlg); - } - - public int getSecretTTL() { - return secretTTL; - } - - public float getSecretGracePeriodRatio() { - return secretGracePeriodRatio; - } - - public String getIstioMetaClusterId() { - return istioMetaClusterId; - } - - public String getCaCert() { - File caFile; - if (IstioConstant.ISTIO_PILOT_CERT_PROVIDER.equals(pilotCertProvider)) { - caFile = new File(IstioConstant.ISTIO_CA_PATH); - } else { - return null; - } - if (caFile.canRead()) { - try { - return FileUtils.readFileToString(caFile, StandardCharsets.UTF_8); - } catch (IOException e) { - logger.error( - LoggerCodeConstants.REGISTRY_ISTIO_EXCEPTION, "File Read Failed", "", "read ca file error", e); - } - } - return null; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/AdsObserver.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/AdsObserver.java deleted file mode 100644 index 5e1734806d9..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/AdsObserver.java +++ /dev/null @@ -1,140 +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 org.apache.dubbo.registry.xds.util; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; -import org.apache.dubbo.registry.xds.util.protocol.AbstractProtocol; -import org.apache.dubbo.registry.xds.util.protocol.DeltaResource; -import org.apache.dubbo.rpc.model.ApplicationModel; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.stub.StreamObserver; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_REQUEST_XDS; - -public class AdsObserver { - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AdsObserver.class); - private final ApplicationModel applicationModel; - private final URL url; - private final Node node; - private volatile XdsChannel xdsChannel; - - private final Map listeners = new ConcurrentHashMap<>(); - - protected StreamObserver requestObserver; - - private final Map observedResources = new ConcurrentHashMap<>(); - - public AdsObserver(URL url, Node node) { - this.url = url; - this.node = node; - this.xdsChannel = new XdsChannel(url); - this.applicationModel = url.getOrDefaultApplicationModel(); - } - - public > void addListener(AbstractProtocol protocol) { - listeners.put(protocol.getTypeUrl(), protocol); - } - - public void request(DiscoveryRequest discoveryRequest) { - if (requestObserver == null) { - requestObserver = xdsChannel.createDeltaDiscoveryRequest(new ResponseObserver(this)); - } - requestObserver.onNext(discoveryRequest); - observedResources.put(discoveryRequest.getTypeUrl(), discoveryRequest); - } - - private static class ResponseObserver implements StreamObserver { - private AdsObserver adsObserver; - - public ResponseObserver(AdsObserver adsObserver) { - this.adsObserver = adsObserver; - } - - @Override - public void onNext(DiscoveryResponse discoveryResponse) { - XdsListener xdsListener = adsObserver.listeners.get(discoveryResponse.getTypeUrl()); - xdsListener.process(discoveryResponse); - adsObserver.requestObserver.onNext(buildAck(discoveryResponse)); - } - - protected DiscoveryRequest buildAck(DiscoveryResponse response) { - // for ACK - return DiscoveryRequest.newBuilder() - .setNode(adsObserver.node) - .setTypeUrl(response.getTypeUrl()) - .setVersionInfo(response.getVersionInfo()) - .setResponseNonce(response.getNonce()) - .addAllResourceNames(adsObserver - .observedResources - .get(response.getTypeUrl()) - .getResourceNamesList()) - .build(); - } - - @Override - public void onError(Throwable throwable) { - logger.error(REGISTRY_ERROR_REQUEST_XDS, "", "", "xDS Client received error message! detail:", throwable); - adsObserver.triggerReConnectTask(); - } - - @Override - public void onCompleted() { - logger.info("xDS Client completed"); - adsObserver.triggerReConnectTask(); - } - } - - private void triggerReConnectTask() { - ScheduledExecutorService scheduledFuture = applicationModel - .getFrameworkModel() - .getBeanFactory() - .getBean(FrameworkExecutorRepository.class) - .getSharedScheduledExecutor(); - scheduledFuture.schedule(this::recover, 3, TimeUnit.SECONDS); - } - - private void recover() { - try { - xdsChannel = new XdsChannel(url); - if (xdsChannel.getChannel() != null) { - requestObserver = xdsChannel.createDeltaDiscoveryRequest(new ResponseObserver(this)); - observedResources.values().forEach(requestObserver::onNext); - return; - } else { - logger.error( - REGISTRY_ERROR_REQUEST_XDS, - "", - "", - "Recover failed for xDS connection. Will retry. Create channel failed."); - } - } catch (Exception e) { - logger.error(REGISTRY_ERROR_REQUEST_XDS, "", "", "Recover failed for xDS connection. Will retry.", e); - } - triggerReConnectTask(); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/NodeBuilder.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/NodeBuilder.java deleted file mode 100644 index eaa88f39047..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/NodeBuilder.java +++ /dev/null @@ -1,43 +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 org.apache.dubbo.registry.xds.util; - -import org.apache.dubbo.common.utils.NetUtils; -import org.apache.dubbo.registry.xds.istio.IstioEnv; - -import io.envoyproxy.envoy.config.core.v3.Node; - -public class NodeBuilder { - - private static final String SVC_CLUSTER_LOCAL = ".svc.cluster.local"; - - public static Node build() { - // String podName = System.getenv("metadata.name"); - // String podNamespace = System.getenv("metadata.namespace"); - - String podName = IstioEnv.getInstance().getPodName(); - String podNamespace = IstioEnv.getInstance().getWorkloadNameSpace(); - String svcName = IstioEnv.getInstance().getIstioMetaClusterId(); - - // id -> sidecar~ip~{POD_NAME}~{NAMESPACE_NAME}.svc.cluster.local - // cluster -> {SVC_NAME} - return Node.newBuilder() - .setId("sidecar~" + NetUtils.getLocalHost() + "~" + podName + "~" + podNamespace + SVC_CLUSTER_LOCAL) - .setCluster(svcName) - .build(); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/PilotExchanger.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/PilotExchanger.java deleted file mode 100644 index 87fa81083a9..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/PilotExchanger.java +++ /dev/null @@ -1,250 +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 org.apache.dubbo.registry.xds.util; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.registry.xds.util.protocol.AbstractProtocol; -import org.apache.dubbo.registry.xds.util.protocol.impl.EdsProtocol; -import org.apache.dubbo.registry.xds.util.protocol.impl.LdsProtocol; -import org.apache.dubbo.registry.xds.util.protocol.impl.RdsProtocol; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.registry.xds.util.protocol.message.EndpointResult; -import org.apache.dubbo.registry.xds.util.protocol.message.ListenerResult; -import org.apache.dubbo.registry.xds.util.protocol.message.RouteResult; -import org.apache.dubbo.rpc.cluster.router.xds.RdsVirtualHostListener; -import org.apache.dubbo.rpc.model.ApplicationModel; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class PilotExchanger { - - protected final XdsChannel xdsChannel; - - protected final LdsProtocol ldsProtocol; - - protected final RdsProtocol rdsProtocol; - - protected final EdsProtocol edsProtocol; - - protected Map listenerResult; - - protected Map routeResult; - - private final AtomicBoolean isRdsObserve = new AtomicBoolean(false); - private final Set domainObserveRequest = new ConcurrentHashSet(); - - private final Map>>> domainObserveConsumer = new ConcurrentHashMap<>(); - - private final Map> rdsObserveConsumer = new ConcurrentHashMap<>(); - - private static PilotExchanger GLOBAL_PILOT_EXCHANGER = null; - - private final ApplicationModel applicationModel; - - protected PilotExchanger(URL url) { - xdsChannel = new XdsChannel(url); - int pollingTimeout = url.getParameter("pollingTimeout", 10); - this.applicationModel = url.getOrDefaultApplicationModel(); - AdsObserver adsObserver = new AdsObserver(url, NodeBuilder.build()); - this.ldsProtocol = new LdsProtocol(adsObserver, NodeBuilder.build(), pollingTimeout); - this.rdsProtocol = new RdsProtocol(adsObserver, NodeBuilder.build(), pollingTimeout); - this.edsProtocol = new EdsProtocol(adsObserver, NodeBuilder.build(), pollingTimeout); - - this.listenerResult = ldsProtocol.getListeners(); - this.routeResult = rdsProtocol.getResource( - listenerResult.values().iterator().next().getRouteConfigNames()); - Set ldsResourcesName = new HashSet<>(); - ldsResourcesName.add(AbstractProtocol.emptyResourceName); - // Observer RDS update - if (CollectionUtils.isNotEmpty(listenerResult.values().iterator().next().getRouteConfigNames())) { - createRouteObserve(); - isRdsObserve.set(true); - } - // Observe LDS updated - ldsProtocol.observeResource( - ldsResourcesName, - (newListener) -> { - // update local cache - if (!newListener.equals(listenerResult)) { - this.listenerResult = newListener; - // update RDS observation - if (isRdsObserve.get()) { - createRouteObserve(); - } - } - }, - false); - } - - private void createRouteObserve() { - rdsProtocol.observeResource( - listenerResult.values().iterator().next().getRouteConfigNames(), - (newResult) -> { - // check if observed domain update ( will update endpoint observation ) - List domainsToUpdate = new LinkedList<>(); - domainObserveConsumer.forEach((domain, consumer) -> { - newResult.values().forEach(o -> { - Set newRoute = o.searchDomain(domain); - for (Map.Entry entry : routeResult.entrySet()) { - if (!entry.getValue().searchDomain(domain).equals(newRoute)) { - // routers in observed domain has been updated - // Long domainRequest = domainObserveRequest.get(domain); - // router list is empty when observeEndpoints() called and domainRequest has not - // been created yet - // create new observation - domainsToUpdate.add(domain); - // doObserveEndpoints(domain); - } - } - }); - }); - routeResult = newResult; - ExecutorService executorService = applicationModel - .getFrameworkModel() - .getBeanFactory() - .getBean(FrameworkExecutorRepository.class) - .getSharedExecutor(); - executorService.submit(() -> domainsToUpdate.forEach(this::doObserveEndpoints)); - }, - false); - } - - public static PilotExchanger initialize(URL url) { - synchronized (PilotExchanger.class) { - if (GLOBAL_PILOT_EXCHANGER != null) { - return GLOBAL_PILOT_EXCHANGER; - } - return (GLOBAL_PILOT_EXCHANGER = new PilotExchanger(url)); - } - } - - public static PilotExchanger getInstance() { - synchronized (PilotExchanger.class) { - return GLOBAL_PILOT_EXCHANGER; - } - } - - public static boolean isEnabled() { - return GLOBAL_PILOT_EXCHANGER != null; - } - - public void destroy() { - xdsChannel.destroy(); - } - - public Set getServices() { - Set domains = new HashSet<>(); - for (Map.Entry entry : routeResult.entrySet()) { - domains.addAll(entry.getValue().getDomains()); - } - return domains; - } - - public Set getEndpoints(String domain) { - Set endpoints = new HashSet<>(); - for (Map.Entry entry : routeResult.entrySet()) { - Set cluster = entry.getValue().searchDomain(domain); - if (CollectionUtils.isNotEmpty(cluster)) { - Map endpointResultList = edsProtocol.getResource(cluster); - endpointResultList.forEach((k, v) -> endpoints.addAll(v.getEndpoints())); - } else { - return Collections.emptySet(); - } - } - return endpoints; - } - - public void observeEndpoints(String domain, Consumer> consumer) { - // store Consumer - domainObserveConsumer.compute(domain, (k, v) -> { - if (v == null) { - v = new ConcurrentHashSet<>(); - } - // support multi-consumer - v.add(consumer); - return v; - }); - if (!domainObserveRequest.contains(domain)) { - doObserveEndpoints(domain); - } - } - - private void doObserveEndpoints(String domain) { - for (Map.Entry entry : routeResult.entrySet()) { - Set router = entry.getValue().searchDomain(domain); - // if router is empty, do nothing - // observation will be created when RDS updates - if (CollectionUtils.isNotEmpty(router)) { - edsProtocol.observeResource( - router, - (endpointResultMap) -> { - Set endpoints = endpointResultMap.values().stream() - .map(EndpointResult::getEndpoints) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - for (Consumer> consumer : domainObserveConsumer.get(domain)) { - consumer.accept(endpoints); - } - }, - false); - domainObserveRequest.add(domain); - } - } - } - - public void unObserveEndpoints(String domain, Consumer> consumer) { - domainObserveConsumer.get(domain).remove(consumer); - domainObserveRequest.remove(domain); - } - - public void observeEds(Set clusterNames, Consumer> consumer) { - edsProtocol.observeResource(clusterNames, consumer, false); - } - - public void unObserveEds(Set clusterNames, Consumer> consumer) { - edsProtocol.unobserveResource(clusterNames, consumer); - } - - public void observeRds(Set clusterNames, Consumer> consumer) { - rdsProtocol.observeResource(clusterNames, consumer, false); - } - - public void unObserveRds(Set clusterNames, Consumer> consumer) { - rdsProtocol.unobserveResource(clusterNames, consumer); - } - - public void observeLds(Consumer> consumer) { - ldsProtocol.observeResource(Collections.singleton(AbstractProtocol.emptyResourceName), consumer, false); - } - - public void unObserveLds(Consumer> consumer) { - ldsProtocol.unobserveResource(Collections.singleton(AbstractProtocol.emptyResourceName), consumer); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsChannel.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsChannel.java deleted file mode 100644 index a6f7dffde11..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsChannel.java +++ /dev/null @@ -1,142 +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 org.apache.dubbo.registry.xds.util; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.url.component.URLAddress; -import org.apache.dubbo.registry.xds.XdsCertificateSigner; -import org.apache.dubbo.registry.xds.util.bootstrap.Bootstrapper; -import org.apache.dubbo.registry.xds.util.bootstrap.BootstrapperImpl; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; - -import io.envoyproxy.envoy.service.discovery.v3.AggregatedDiscoveryServiceGrpc; -import io.envoyproxy.envoy.service.discovery.v3.DeltaDiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DeltaDiscoveryResponse; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ManagedChannel; -import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; -import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder; -import io.grpc.netty.shaded.io.netty.channel.epoll.EpollDomainSocketChannel; -import io.grpc.netty.shaded.io.netty.channel.epoll.EpollEventLoopGroup; -import io.grpc.netty.shaded.io.netty.channel.unix.DomainSocketAddress; -import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext; -import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import io.grpc.stub.StreamObserver; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_CREATE_CHANNEL_XDS; - -public class XdsChannel { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(XdsChannel.class); - - private static final String USE_AGENT = "use-agent"; - - private URL url; - - private static final String SECURE = "secure"; - - private static final String PLAINTEXT = "plaintext"; - - private final ManagedChannel channel; - - public URL getUrl() { - return url; - } - - public ManagedChannel getChannel() { - return channel; - } - - public XdsChannel(URL url) { - ManagedChannel managedChannel = null; - this.url = url; - try { - if (!url.getParameter(USE_AGENT, false)) { - if (PLAINTEXT.equals(url.getParameter(SECURE))) { - managedChannel = NettyChannelBuilder.forAddress(url.getHost(), url.getPort()) - .usePlaintext() - .build(); - } else { - XdsCertificateSigner signer = url.getOrDefaultApplicationModel() - .getExtensionLoader(XdsCertificateSigner.class) - .getExtension(url.getParameter("signer", "istio")); - XdsCertificateSigner.CertPair certPair = signer.GenerateCert(url); - SslContext context = GrpcSslContexts.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE) - .keyManager( - new ByteArrayInputStream( - certPair.getPublicKey().getBytes(StandardCharsets.UTF_8)), - new ByteArrayInputStream( - certPair.getPrivateKey().getBytes(StandardCharsets.UTF_8))) - .build(); - managedChannel = NettyChannelBuilder.forAddress(url.getHost(), url.getPort()) - .sslContext(context) - .build(); - } - } else { - BootstrapperImpl bootstrapper = new BootstrapperImpl(); - Bootstrapper.BootstrapInfo bootstrapInfo = bootstrapper.bootstrap(); - URLAddress address = - URLAddress.parse(bootstrapInfo.servers().get(0).target(), null, false); - EpollEventLoopGroup elg = new EpollEventLoopGroup(); - managedChannel = NettyChannelBuilder.forAddress(new DomainSocketAddress("/" + address.getPath())) - .eventLoopGroup(elg) - .channelType(EpollDomainSocketChannel.class) - .usePlaintext() - .build(); - } - } catch (Exception e) { - logger.error( - REGISTRY_ERROR_CREATE_CHANNEL_XDS, - "", - "", - "Error occurred when creating gRPC channel to control panel.", - e); - } - channel = managedChannel; - } - - public StreamObserver observeDeltaDiscoveryRequest( - StreamObserver observer) { - return AggregatedDiscoveryServiceGrpc.newStub(channel).deltaAggregatedResources(observer); - } - - public StreamObserver createDeltaDiscoveryRequest(StreamObserver observer) { - return AggregatedDiscoveryServiceGrpc.newStub(channel).streamAggregatedResources(observer); - } - - public StreamObserver observeDeltaDiscoveryRequestV2( - StreamObserver observer) { - return io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc.newStub(channel) - .deltaAggregatedResources(observer); - } - - public StreamObserver createDeltaDiscoveryRequestV2( - StreamObserver observer) { - return io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc.newStub(channel) - .streamAggregatedResources(observer); - } - - public void destroy() { - channel.shutdown(); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsListener.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsListener.java deleted file mode 100644 index 233d92198a5..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/XdsListener.java +++ /dev/null @@ -1,23 +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 org.apache.dubbo.registry.xds.util; - -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; - -public interface XdsListener { - void process(DiscoveryResponse discoveryResponse); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapInfoImpl.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapInfoImpl.java deleted file mode 100644 index 3570b20e32e..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapInfoImpl.java +++ /dev/null @@ -1,131 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import javax.annotation.Nullable; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import io.envoyproxy.envoy.config.core.v3.Node; - -public final class BootstrapInfoImpl extends Bootstrapper.BootstrapInfo { - - private final List servers; - - private final String serverListenerResourceNameTemplate; - - private final Map certProviders; - - private final Node node; - - BootstrapInfoImpl( - List servers, - String serverListenerResourceNameTemplate, - Map certProviders, - Node node) { - this.servers = servers; - this.serverListenerResourceNameTemplate = serverListenerResourceNameTemplate; - this.certProviders = certProviders; - this.node = node; - } - - @Override - public List servers() { - return servers; - } - - public Map certProviders() { - return certProviders; - } - - @Override - public Node node() { - return node; - } - - @Override - public String serverListenerResourceNameTemplate() { - return serverListenerResourceNameTemplate; - } - - @Override - public String toString() { - return "BootstrapInfo{" - + "servers=" + servers + ", " - + "serverListenerResourceNameTemplate=" + serverListenerResourceNameTemplate + ", " - + "node=" + node + ", " - + "}"; - } - - public static final class Builder extends Bootstrapper.BootstrapInfo.Builder { - private List servers; - private Node node; - - private Map certProviders; - - private String serverListenerResourceNameTemplate; - - Builder() {} - - @Override - Bootstrapper.BootstrapInfo.Builder servers(List servers) { - this.servers = new LinkedList<>(servers); - return this; - } - - @Override - Bootstrapper.BootstrapInfo.Builder node(Node node) { - if (node == null) { - throw new NullPointerException("Null node"); - } - this.node = node; - return this; - } - - @Override - Bootstrapper.BootstrapInfo.Builder certProviders( - @Nullable Map certProviders) { - this.certProviders = certProviders; - return this; - } - - @Override - Bootstrapper.BootstrapInfo.Builder serverListenerResourceNameTemplate( - @Nullable String serverListenerResourceNameTemplate) { - this.serverListenerResourceNameTemplate = serverListenerResourceNameTemplate; - return this; - } - - @Override - Bootstrapper.BootstrapInfo build() { - if (this.servers == null || this.node == null) { - StringBuilder missing = new StringBuilder(); - if (this.servers == null) { - missing.append(" servers"); - } - if (this.node == null) { - missing.append(" node"); - } - throw new IllegalStateException("Missing required properties:" + missing); - } - return new BootstrapInfoImpl( - this.servers, this.serverListenerResourceNameTemplate, this.certProviders, this.node); - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/Bootstrapper.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/Bootstrapper.java deleted file mode 100644 index 69a7ee89a51..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/Bootstrapper.java +++ /dev/null @@ -1,75 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import org.apache.dubbo.registry.xds.XdsInitializationException; - -import javax.annotation.Nullable; - -import java.util.List; -import java.util.Map; - -import io.envoyproxy.envoy.config.core.v3.Node; -import io.grpc.ChannelCredentials; - -public abstract class Bootstrapper { - - public abstract BootstrapInfo bootstrap() throws XdsInitializationException; - - BootstrapInfo bootstrap(Map rawData) throws XdsInitializationException { - throw new UnsupportedOperationException(); - } - - public abstract static class ServerInfo { - public abstract String target(); - - abstract ChannelCredentials channelCredentials(); - - abstract boolean useProtocolV3(); - - abstract boolean ignoreResourceDeletion(); - } - - public abstract static class CertificateProviderInfo { - public abstract String pluginName(); - - public abstract Map config(); - } - - public abstract static class BootstrapInfo { - public abstract List servers(); - - public abstract Map certProviders(); - - public abstract Node node(); - - public abstract String serverListenerResourceNameTemplate(); - - abstract static class Builder { - - abstract Builder servers(List servers); - - abstract Builder node(Node node); - - abstract Builder certProviders(@Nullable Map certProviders); - - abstract Builder serverListenerResourceNameTemplate(@Nullable String serverListenerResourceNameTemplate); - - abstract BootstrapInfo build(); - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperImpl.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperImpl.java deleted file mode 100644 index 66c7a623978..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperImpl.java +++ /dev/null @@ -1,179 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import org.apache.dubbo.common.logger.Logger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.xds.XdsInitializationException; - -import javax.annotation.Nullable; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import io.envoyproxy.envoy.config.core.v3.Node; -import io.grpc.ChannelCredentials; -import io.grpc.internal.JsonParser; -import io.grpc.internal.JsonUtil; - -public class BootstrapperImpl extends Bootstrapper { - - static final String BOOTSTRAP_PATH_SYS_ENV_VAR = "GRPC_XDS_BOOTSTRAP"; - static String bootstrapPathFromEnvVar = System.getenv(BOOTSTRAP_PATH_SYS_ENV_VAR); - - private static final Logger logger = LoggerFactory.getLogger(BootstrapperImpl.class); - private FileReader reader = LocalFileReader.INSTANCE; - - private static final String SERVER_FEATURE_XDS_V3 = "xds_v3"; - private static final String SERVER_FEATURE_IGNORE_RESOURCE_DELETION = "ignore_resource_deletion"; - - public BootstrapInfo bootstrap() throws XdsInitializationException { - String filePath = bootstrapPathFromEnvVar; - String fileContent = null; - if (filePath != null) { - try { - fileContent = reader.readFile(filePath); - } catch (IOException e) { - throw new XdsInitializationException("Fail to read bootstrap file", e); - } - } - if (fileContent == null) throw new XdsInitializationException("Cannot find bootstrap configuration"); - - Map rawBootstrap; - try { - rawBootstrap = (Map) JsonParser.parse(fileContent); - } catch (IOException e) { - throw new XdsInitializationException("Failed to parse JSON", e); - } - return bootstrap(rawBootstrap); - } - - @Override - BootstrapInfo bootstrap(Map rawData) throws XdsInitializationException { - BootstrapInfo.Builder builder = new BootstrapInfoImpl.Builder(); - - List rawServerConfigs = JsonUtil.getList(rawData, "xds_servers"); - if (rawServerConfigs == null) { - throw new XdsInitializationException("Invalid bootstrap: 'xds_servers' does not exist."); - } - List servers = parseServerInfos(rawServerConfigs); - builder.servers(servers); - - Node.Builder nodeBuilder = Node.newBuilder(); - Map rawNode = JsonUtil.getObject(rawData, "node"); - if (rawNode != null) { - String id = JsonUtil.getString(rawNode, "id"); - if (id != null) { - nodeBuilder.setId(id); - } - String cluster = JsonUtil.getString(rawNode, "cluster"); - if (cluster != null) { - nodeBuilder.setCluster(cluster); - } - Map metadata = JsonUtil.getObject(rawNode, "metadata"); - Map rawLocality = JsonUtil.getObject(rawNode, "locality"); - } - builder.node(nodeBuilder.build()); - - Map certProvidersBlob = JsonUtil.getObject(rawData, "certificate_providers"); - if (certProvidersBlob != null) { - Map certProviders = new HashMap<>(certProvidersBlob.size()); - for (String name : certProvidersBlob.keySet()) { - Map valueMap = JsonUtil.getObject(certProvidersBlob, name); - String pluginName = checkForNull(JsonUtil.getString(valueMap, "plugin_name"), "plugin_name"); - Map config = checkForNull(JsonUtil.getObject(valueMap, "config"), "config"); - CertificateProviderInfoImpl certificateProviderInfo = - new CertificateProviderInfoImpl(pluginName, config); - certProviders.put(name, certificateProviderInfo); - } - builder.certProviders(certProviders); - } - - return builder.build(); - } - - private static List parseServerInfos(List rawServerConfigs) throws XdsInitializationException { - List servers = new LinkedList<>(); - List> serverConfigList = JsonUtil.checkObjectList(rawServerConfigs); - for (Map serverConfig : serverConfigList) { - String serverUri = JsonUtil.getString(serverConfig, "server_uri"); - if (serverUri == null) { - throw new XdsInitializationException("Invalid bootstrap: missing 'server_uri'"); - } - List rawChannelCredsList = JsonUtil.getList(serverConfig, "channel_creds"); - if (rawChannelCredsList == null || rawChannelCredsList.isEmpty()) { - throw new XdsInitializationException( - "Invalid bootstrap: server " + serverUri + " 'channel_creds' required"); - } - ChannelCredentials channelCredentials = - parseChannelCredentials(JsonUtil.checkObjectList(rawChannelCredsList), serverUri); - // if (channelCredentials == null) { - // throw new XdsInitializationException( - // "Server " + serverUri + ": no supported channel credentials found"); - // } - - boolean useProtocolV3 = false; - boolean ignoreResourceDeletion = false; - List serverFeatures = JsonUtil.getListOfStrings(serverConfig, "server_features"); - if (serverFeatures != null) { - useProtocolV3 = serverFeatures.contains(SERVER_FEATURE_XDS_V3); - ignoreResourceDeletion = serverFeatures.contains(SERVER_FEATURE_IGNORE_RESOURCE_DELETION); - } - servers.add(new ServerInfoImpl(serverUri, channelCredentials, useProtocolV3, ignoreResourceDeletion)); - } - return servers; - } - - void setFileReader(FileReader reader) { - this.reader = reader; - } - - /** - * Reads the content of the file with the given path in the file system. - */ - interface FileReader { - String readFile(String path) throws IOException; - } - - private enum LocalFileReader implements FileReader { - INSTANCE; - - @Override - public String readFile(String path) throws IOException { - return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8); - } - } - - private static T checkForNull(T value, String fieldName) throws XdsInitializationException { - if (value == null) { - throw new XdsInitializationException("Invalid bootstrap: '" + fieldName + "' does not exist."); - } - return value; - } - - @Nullable - private static ChannelCredentials parseChannelCredentials(List> jsonList, String serverUri) - throws XdsInitializationException { - return null; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/CertificateProviderInfoImpl.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/CertificateProviderInfoImpl.java deleted file mode 100644 index 980b6e1fd30..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/CertificateProviderInfoImpl.java +++ /dev/null @@ -1,45 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import java.util.Map; - -final class CertificateProviderInfoImpl extends Bootstrapper.CertificateProviderInfo { - - private final String pluginName; - private final Map config; - - CertificateProviderInfoImpl(String pluginName, Map config) { - this.pluginName = pluginName; - this.config = config; - } - - @Override - public String pluginName() { - return pluginName; - } - - @Override - public Map config() { - return config; - } - - @Override - public String toString() { - return "CertificateProviderInfo{" + "pluginName=" + pluginName + ", " + "config=" + config + "}"; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/ServerInfoImpl.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/ServerInfoImpl.java deleted file mode 100644 index c15f4f28b74..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/bootstrap/ServerInfoImpl.java +++ /dev/null @@ -1,71 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import io.grpc.ChannelCredentials; - -final class ServerInfoImpl extends Bootstrapper.ServerInfo { - - private final String target; - - private final ChannelCredentials channelCredentials; - - private final boolean useProtocolV3; - - private final boolean ignoreResourceDeletion; - - ServerInfoImpl( - String target, - ChannelCredentials channelCredentials, - boolean useProtocolV3, - boolean ignoreResourceDeletion) { - this.target = target; - this.channelCredentials = channelCredentials; - this.useProtocolV3 = useProtocolV3; - this.ignoreResourceDeletion = ignoreResourceDeletion; - } - - @Override - public String target() { - return target; - } - - @Override - ChannelCredentials channelCredentials() { - return channelCredentials; - } - - @Override - boolean useProtocolV3() { - return useProtocolV3; - } - - @Override - boolean ignoreResourceDeletion() { - return ignoreResourceDeletion; - } - - @Override - public String toString() { - return "ServerInfo{" - + "target=" + target + ", " - + "channelCredentials=" + channelCredentials + ", " - + "useProtocolV3=" + useProtocolV3 + ", " - + "ignoreResourceDeletion=" + ignoreResourceDeletion - + "}"; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/AbstractProtocol.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/AbstractProtocol.java deleted file mode 100644 index a2e135f00db..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/AbstractProtocol.java +++ /dev/null @@ -1,269 +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 org.apache.dubbo.registry.xds.util.protocol; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.XdsListener; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_REQUEST; - -public abstract class AbstractProtocol> implements XdsProtocol, XdsListener { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractProtocol.class); - - protected AdsObserver adsObserver; - - protected final Node node; - - private final int checkInterval; - - protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - - protected final ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); - - protected final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); - - protected Set observeResourcesName; - - public static final String emptyResourceName = "emptyResourcesName"; - private final ReentrantLock resourceLock = new ReentrantLock(); - - protected Map, List>>> consumerObserveMap = new ConcurrentHashMap<>(); - - public Map, List>>> getConsumerObserveMap() { - return consumerObserveMap; - } - - protected Map resourcesMap = new ConcurrentHashMap<>(); - - public AbstractProtocol(AdsObserver adsObserver, Node node, int checkInterval) { - this.adsObserver = adsObserver; - this.node = node; - this.checkInterval = checkInterval; - adsObserver.addListener(this); - } - - /** - * Abstract method to obtain Type-URL from sub-class - * - * @return Type-URL of xDS - */ - public abstract String getTypeUrl(); - - public boolean isCacheExistResource(Set resourceNames) { - for (String resourceName : resourceNames) { - if ("".equals(resourceName)) { - continue; - } - if (!resourcesMap.containsKey(resourceName)) { - return false; - } - } - return true; - } - - public T getCacheResource(String resourceName) { - if (resourceName == null || resourceName.length() == 0) { - return null; - } - return resourcesMap.get(resourceName); - } - - @Override - public Map getResource(Set resourceNames) { - resourceNames = resourceNames == null ? Collections.emptySet() : resourceNames; - - if (!resourceNames.isEmpty() && isCacheExistResource(resourceNames)) { - return getResourceFromCache(resourceNames); - } else { - return getResourceFromRemote(resourceNames); - } - } - - private Map getResourceFromCache(Set resourceNames) { - return resourceNames.stream() - .filter(o -> !StringUtils.isEmpty(o)) - .collect(Collectors.toMap(k -> k, this::getCacheResource)); - } - - public Map getResourceFromRemote(Set resourceNames) { - try { - resourceLock.lock(); - CompletableFuture> future = new CompletableFuture<>(); - observeResourcesName = resourceNames; - Set consumerObserveResourceNames = new HashSet<>(); - if (resourceNames.isEmpty()) { - consumerObserveResourceNames.add(emptyResourceName); - } else { - consumerObserveResourceNames = resourceNames; - } - - Consumer> futureConsumer = future::complete; - try { - writeLock.lock(); - ConcurrentHashMapUtils.computeIfAbsent( - (ConcurrentHashMap, List>>>) consumerObserveMap, - consumerObserveResourceNames, - key -> new ArrayList<>()) - .add(futureConsumer); - } finally { - writeLock.unlock(); - } - - Set resourceNamesToObserve = new HashSet<>(resourceNames); - resourceNamesToObserve.addAll(resourcesMap.keySet()); - adsObserver.request(buildDiscoveryRequest(resourceNamesToObserve)); - logger.info("Send xDS Observe request to remote. Resource count: " + resourceNamesToObserve.size() - + ". Resource Type: " + getTypeUrl()); - - try { - Map result = future.get(); - - try { - writeLock.lock(); - consumerObserveMap.get(consumerObserveResourceNames).removeIf(o -> o.equals(futureConsumer)); - } finally { - writeLock.unlock(); - } - - return result; - } catch (InterruptedException e) { - logger.error( - INTERNAL_INTERRUPTED, - "", - "", - "InterruptedException occur when request control panel. error=", - e); - Thread.currentThread().interrupt(); - } catch (Exception e) { - logger.error(PROTOCOL_FAILED_REQUEST, "", "", "Error occur when request control panel. error=", e); - } - } finally { - resourceLock.unlock(); - } - return Collections.emptyMap(); - } - - public void observeResource(Set resourceNames, Consumer> consumer, boolean isReConnect) { - // call once for full data - if (!isReConnect) { - consumer.accept(getResource(resourceNames)); - try { - writeLock.lock(); - consumerObserveMap.compute(resourceNames, (k, v) -> { - if (v == null) { - v = new ArrayList<>(); - } - // support multi-consumer - v.add(consumer); - return v; - }); - } finally { - writeLock.unlock(); - } - } - try { - writeLock.lock(); - this.observeResourcesName = - consumerObserveMap.keySet().stream().flatMap(Set::stream).collect(Collectors.toSet()); - } finally { - writeLock.unlock(); - } - } - - public void unobserveResource(Set resourceNames, Consumer> consumer) { - // TODO - } - - protected DiscoveryRequest buildDiscoveryRequest(Set resourceNames) { - return DiscoveryRequest.newBuilder() - .setNode(node) - .setTypeUrl(getTypeUrl()) - .addAllResourceNames(resourceNames) - .build(); - } - - protected abstract Map decodeDiscoveryResponse(DiscoveryResponse response); - - @Override - public final void process(DiscoveryResponse discoveryResponse) { - Map newResult = decodeDiscoveryResponse(discoveryResponse); - Map oldResource = resourcesMap; - discoveryResponseListener(oldResource, newResult); - resourcesMap = newResult; - } - - private void discoveryResponseListener(Map oldResult, Map newResult) { - Set changedResourceNames = new HashSet<>(); - oldResult.forEach((key, origin) -> { - if (!Objects.equals(origin, newResult.get(key))) { - changedResourceNames.add(key); - } - }); - newResult.forEach((key, origin) -> { - if (!Objects.equals(origin, oldResult.get(key))) { - changedResourceNames.add(key); - } - }); - if (changedResourceNames.isEmpty()) { - return; - } - - logger.info("Receive resource update notification from xds server. Change resource count: " - + changedResourceNames.stream() + ". Type: " + getTypeUrl()); - - // call once for full data - try { - readLock.lock(); - for (Map.Entry, List>>> entry : consumerObserveMap.entrySet()) { - if (entry.getKey().stream().noneMatch(changedResourceNames::contains)) { - // none update - continue; - } - - Map dsResultMap = - entry.getKey().stream().collect(Collectors.toMap(k -> k, v -> newResult.get(v))); - entry.getValue().forEach(o -> o.accept(dsResultMap)); - } - } finally { - readLock.unlock(); - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/DeltaResource.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/DeltaResource.java deleted file mode 100644 index bcae39cee17..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/DeltaResource.java +++ /dev/null @@ -1,32 +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 org.apache.dubbo.registry.xds.util.protocol; - -/** - * A interface for resources in xDS, which can be updated by ADS delta stream - *
- * This interface is design to unify the way of fetching data in delta stream - * in {@link org.apache.dubbo.registry.xds.util.PilotExchanger} - */ -public interface DeltaResource { - /** - * Get resource from delta stream - * - * @return the newest resource from stream - */ - T getResource(); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/XdsProtocol.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/XdsProtocol.java deleted file mode 100644 index ce1a0881403..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/XdsProtocol.java +++ /dev/null @@ -1,41 +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 org.apache.dubbo.registry.xds.util.protocol; - -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -public interface XdsProtocol { - /** - * Gets all {@link T resource} by the specified resource name. - * For LDS, the {@param resourceNames} is ignored - * - * @param resourceNames specified resource name - * @return resources, null if request failed - */ - Map getResource(Set resourceNames); - - /** - * Add a observer resource with {@link Consumer} - * - * @param resourceNames specified resource name - * @param consumer resource notifier, will be called when resource updated - * @return requestId, used when resourceNames update with {@link XdsProtocol#updateObserve(long, Set)} - */ - void observeResource(Set resourceNames, Consumer> consumer, boolean isReConnect); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaEndpoint.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaEndpoint.java deleted file mode 100644 index 46988f38e5b..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaEndpoint.java +++ /dev/null @@ -1,48 +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 org.apache.dubbo.registry.xds.util.protocol.delta; - -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.registry.xds.util.protocol.DeltaResource; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.registry.xds.util.protocol.message.EndpointResult; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -public class DeltaEndpoint implements DeltaResource { - private final Map> data = new ConcurrentHashMap<>(); - - public void addResource(String resourceName, Set endpoints) { - data.put(resourceName, endpoints); - } - - public void removeResource(Collection resourceName) { - if (CollectionUtils.isNotEmpty(resourceName)) { - resourceName.forEach(data::remove); - } - } - - @Override - public EndpointResult getResource() { - Set set = data.values().stream().flatMap(Set::stream).collect(Collectors.toSet()); - return new EndpointResult(set); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaListener.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaListener.java deleted file mode 100644 index bca3024ed96..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaListener.java +++ /dev/null @@ -1,47 +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 org.apache.dubbo.registry.xds.util.protocol.delta; - -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.registry.xds.util.protocol.DeltaResource; -import org.apache.dubbo.registry.xds.util.protocol.message.ListenerResult; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -public class DeltaListener implements DeltaResource { - private final Map> data = new ConcurrentHashMap<>(); - - public void addResource(String resourceName, Set listeners) { - data.put(resourceName, listeners); - } - - public void removeResource(Collection resourceName) { - if (CollectionUtils.isNotEmpty(resourceName)) { - resourceName.forEach(data::remove); - } - } - - @Override - public ListenerResult getResource() { - Set set = data.values().stream().flatMap(Set::stream).collect(Collectors.toSet()); - return new ListenerResult(set); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaRoute.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaRoute.java deleted file mode 100644 index 71fdb479b39..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/delta/DeltaRoute.java +++ /dev/null @@ -1,47 +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 org.apache.dubbo.registry.xds.util.protocol.delta; - -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.registry.xds.util.protocol.DeltaResource; -import org.apache.dubbo.registry.xds.util.protocol.message.RouteResult; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -public class DeltaRoute implements DeltaResource { - private final Map>> data = new ConcurrentHashMap<>(); - - public void addResource(String resourceName, Map> route) { - data.put(resourceName, route); - } - - public void removeResource(Collection resourceName) { - if (CollectionUtils.isNotEmpty(resourceName)) { - resourceName.forEach(data::remove); - } - } - - @Override - public RouteResult getResource() { - Map> result = new ConcurrentHashMap<>(); - data.values().forEach(result::putAll); - return new RouteResult(result); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocol.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocol.java deleted file mode 100644 index 91759cab9b6..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocol.java +++ /dev/null @@ -1,97 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.AbstractProtocol; -import org.apache.dubbo.registry.xds.util.protocol.delta.DeltaEndpoint; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.registry.xds.util.protocol.message.EndpointResult; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import io.envoyproxy.envoy.config.core.v3.HealthStatus; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.config.core.v3.SocketAddress; -import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment; -import io.envoyproxy.envoy.config.endpoint.v3.LbEndpoint; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_RESPONSE_XDS; - -public class EdsProtocol extends AbstractProtocol { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(EdsProtocol.class); - - public EdsProtocol(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - @Override - public String getTypeUrl() { - return "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"; - } - - @Override - protected Map decodeDiscoveryResponse(DiscoveryResponse response) { - if (getTypeUrl().equals(response.getTypeUrl())) { - return response.getResourcesList().stream() - .map(EdsProtocol::unpackClusterLoadAssignment) - .filter(Objects::nonNull) - .collect(Collectors.toConcurrentMap( - ClusterLoadAssignment::getClusterName, this::decodeResourceToEndpoint)); - } - return new HashMap<>(); - } - - private EndpointResult decodeResourceToEndpoint(ClusterLoadAssignment resource) { - Set endpoints = resource.getEndpointsList().stream() - .flatMap(e -> e.getLbEndpointsList().stream()) - .map(e -> decodeLbEndpointToEndpoint(resource.getClusterName(), e)) - .collect(Collectors.toSet()); - return new EndpointResult(endpoints); - } - - private static Endpoint decodeLbEndpointToEndpoint(String clusterName, LbEndpoint lbEndpoint) { - Endpoint endpoint = new Endpoint(); - SocketAddress address = lbEndpoint.getEndpoint().getAddress().getSocketAddress(); - endpoint.setAddress(address.getAddress()); - endpoint.setPortValue(address.getPortValue()); - boolean healthy = HealthStatus.HEALTHY.equals(lbEndpoint.getHealthStatus()) - || HealthStatus.UNKNOWN.equals(lbEndpoint.getHealthStatus()); - endpoint.setHealthy(healthy); - endpoint.setWeight(lbEndpoint.getLoadBalancingWeight().getValue()); - return endpoint; - } - - private static ClusterLoadAssignment unpackClusterLoadAssignment(Any any) { - try { - return any.unpack(ClusterLoadAssignment.class); - } catch (InvalidProtocolBufferException e) { - logger.error(REGISTRY_ERROR_RESPONSE_XDS, "", "", "Error occur when decode xDS response.", e); - return null; - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocol.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocol.java deleted file mode 100644 index 00abe22f37d..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocol.java +++ /dev/null @@ -1,106 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.AbstractProtocol; -import org.apache.dubbo.registry.xds.util.protocol.delta.DeltaListener; -import org.apache.dubbo.registry.xds.util.protocol.message.ListenerResult; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.config.listener.v3.Filter; -import io.envoyproxy.envoy.config.listener.v3.Listener; -import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager; -import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.Rds; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_RESPONSE_XDS; - -public class LdsProtocol extends AbstractProtocol { - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(LdsProtocol.class); - - public LdsProtocol(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - @Override - public String getTypeUrl() { - return "type.googleapis.com/envoy.config.listener.v3.Listener"; - } - - public Map getListeners() { - return getResource(null); - } - - @Override - protected Map decodeDiscoveryResponse(DiscoveryResponse response) { - if (getTypeUrl().equals(response.getTypeUrl())) { - Set set = response.getResourcesList().stream() - .map(LdsProtocol::unpackListener) - .filter(Objects::nonNull) - .flatMap(e -> decodeResourceToListener(e).stream()) - .collect(Collectors.toSet()); - Map listenerDecodeResult = new ConcurrentHashMap<>(); - listenerDecodeResult.put(emptyResourceName, new ListenerResult(set)); - return listenerDecodeResult; - } - return new HashMap<>(); - } - - private Set decodeResourceToListener(Listener resource) { - return resource.getFilterChainsList().stream() - .flatMap(e -> e.getFiltersList().stream()) - .map(Filter::getTypedConfig) - .map(LdsProtocol::unpackHttpConnectionManager) - .filter(Objects::nonNull) - .map(HttpConnectionManager::getRds) - .map(Rds::getRouteConfigName) - .collect(Collectors.toSet()); - } - - private static Listener unpackListener(Any any) { - try { - return any.unpack(Listener.class); - } catch (InvalidProtocolBufferException e) { - logger.error(REGISTRY_ERROR_RESPONSE_XDS, "", "", "Error occur when decode xDS response.", e); - return null; - } - } - - private static HttpConnectionManager unpackHttpConnectionManager(Any any) { - try { - if (!any.is(HttpConnectionManager.class)) { - return null; - } - return any.unpack(HttpConnectionManager.class); - } catch (InvalidProtocolBufferException e) { - logger.error(REGISTRY_ERROR_RESPONSE_XDS, "", "", "Error occur when decode xDS response.", e); - return null; - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocol.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocol.java deleted file mode 100644 index 44bee78c1eb..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocol.java +++ /dev/null @@ -1,92 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.AbstractProtocol; -import org.apache.dubbo.registry.xds.util.protocol.delta.DeltaRoute; -import org.apache.dubbo.registry.xds.util.protocol.message.RouteResult; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import com.google.protobuf.Any; -import com.google.protobuf.InvalidProtocolBufferException; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.config.route.v3.Route; -import io.envoyproxy.envoy.config.route.v3.RouteAction; -import io.envoyproxy.envoy.config.route.v3.RouteConfiguration; -import io.envoyproxy.envoy.config.route.v3.VirtualHost; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; - -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERROR_RESPONSE_XDS; - -public class RdsProtocol extends AbstractProtocol { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(RdsProtocol.class); - - public RdsProtocol(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - @Override - public String getTypeUrl() { - return "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"; - } - - @Override - protected Map decodeDiscoveryResponse(DiscoveryResponse response) { - if (getTypeUrl().equals(response.getTypeUrl())) { - return response.getResourcesList().stream() - .map(RdsProtocol::unpackRouteConfiguration) - .filter(Objects::nonNull) - .collect(Collectors.toConcurrentMap(RouteConfiguration::getName, this::decodeResourceToListener)); - } - return new HashMap<>(); - } - - private RouteResult decodeResourceToListener(RouteConfiguration resource) { - Map> map = new HashMap<>(); - Map rdsVirtualhostMap = new ConcurrentHashMap<>(); - resource.getVirtualHostsList().forEach(virtualHost -> { - Set cluster = virtualHost.getRoutesList().stream() - .map(Route::getRoute) - .map(RouteAction::getCluster) - .collect(Collectors.toSet()); - for (String domain : virtualHost.getDomainsList()) { - map.put(domain, cluster); - rdsVirtualhostMap.put(domain, virtualHost); - } - }); - return new RouteResult(map, rdsVirtualhostMap); - } - - private static RouteConfiguration unpackRouteConfiguration(Any any) { - try { - return any.unpack(RouteConfiguration.class); - } catch (InvalidProtocolBufferException e) { - logger.error(REGISTRY_ERROR_RESPONSE_XDS, "", "", "Error occur when decode xDS response.", e); - return null; - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/Endpoint.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/Endpoint.java deleted file mode 100644 index ceed1632787..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/Endpoint.java +++ /dev/null @@ -1,96 +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 org.apache.dubbo.registry.xds.util.protocol.message; - -import java.util.Objects; - -public class Endpoint { - private String clusterName; - private String address; - private int portValue; - private boolean healthy; - private int weight; - - public String getClusterName() { - return clusterName; - } - - public void setClusterName(String clusterName) { - this.clusterName = clusterName; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public int getPortValue() { - return portValue; - } - - public void setPortValue(int portValue) { - this.portValue = portValue; - } - - public boolean isHealthy() { - return healthy; - } - - public void setHealthy(boolean healthy) { - this.healthy = healthy; - } - - public int getWeight() { - return weight; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - @Override - public String toString() { - return "Endpoint{" + "address='" - + address + '\'' + ", portValue='" - + portValue + '\'' + ", healthy=" - + healthy + ", weight=" - + weight + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Endpoint endpoint = (Endpoint) o; - return healthy == endpoint.healthy - && weight == endpoint.weight - && Objects.equals(address, endpoint.address) - && Objects.equals(portValue, endpoint.portValue); - } - - @Override - public int hashCode() { - return Objects.hash(address, portValue, healthy, weight); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/EndpointResult.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/EndpointResult.java deleted file mode 100644 index ead2c4de277..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/EndpointResult.java +++ /dev/null @@ -1,60 +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 org.apache.dubbo.registry.xds.util.protocol.message; - -import org.apache.dubbo.common.utils.ConcurrentHashSet; - -import java.util.Objects; -import java.util.Set; - -public class EndpointResult { - private Set endpoints; - - public EndpointResult() { - this.endpoints = new ConcurrentHashSet<>(); - } - - public EndpointResult(Set endpoints) { - this.endpoints = endpoints; - } - - public Set getEndpoints() { - return endpoints; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - EndpointResult that = (EndpointResult) o; - return Objects.equals(endpoints, that.endpoints); - } - - @Override - public int hashCode() { - return Objects.hash(endpoints); - } - - @Override - public String toString() { - return "EndpointResult{" + "endpoints=" + endpoints + '}'; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/ListenerResult.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/ListenerResult.java deleted file mode 100644 index 7c16703166a..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/ListenerResult.java +++ /dev/null @@ -1,68 +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 org.apache.dubbo.registry.xds.util.protocol.message; - -import org.apache.dubbo.common.utils.ConcurrentHashSet; - -import java.util.Objects; -import java.util.Set; - -public class ListenerResult { - private Set routeConfigNames; - - public ListenerResult() { - this.routeConfigNames = new ConcurrentHashSet<>(); - } - - public ListenerResult(Set routeConfigNames) { - this.routeConfigNames = routeConfigNames; - } - - public Set getRouteConfigNames() { - return routeConfigNames; - } - - public void setRouteConfigNames(Set routeConfigNames) { - this.routeConfigNames = routeConfigNames; - } - - public void mergeRouteConfigNames(Set names) { - this.routeConfigNames.addAll(names); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ListenerResult listenerResult = (ListenerResult) o; - return Objects.equals(routeConfigNames, listenerResult.routeConfigNames); - } - - @Override - public int hashCode() { - return Objects.hash(routeConfigNames); - } - - @Override - public String toString() { - return "ListenerResult{" + "routeConfigNames=" + routeConfigNames + '}'; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/RouteResult.java b/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/RouteResult.java deleted file mode 100644 index cf0ed1d8465..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/registry/xds/util/protocol/message/RouteResult.java +++ /dev/null @@ -1,94 +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 org.apache.dubbo.registry.xds.util.protocol.message; - -import org.apache.dubbo.common.utils.ConcurrentHashSet; - -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import io.envoyproxy.envoy.config.route.v3.VirtualHost; - -public class RouteResult { - private final Map> domainMap; - private Map virtualHostMap; - - public RouteResult() { - this.domainMap = new ConcurrentHashMap<>(); - this.virtualHostMap = new ConcurrentHashMap<>(); - } - - public RouteResult(Map> domainMap) { - this.domainMap = domainMap; - this.virtualHostMap = new ConcurrentHashMap<>(); - } - - public RouteResult(Map> domainMap, Map virtualHostMap) { - this.domainMap = domainMap; - this.virtualHostMap = virtualHostMap; - } - - public Map> getDomainMap() { - return domainMap; - } - - public boolean isNotEmpty() { - return !domainMap.isEmpty(); - } - - public Set searchDomain(String domain) { - return domainMap.getOrDefault(domain, new ConcurrentHashSet<>()); - } - - public Set getDomains() { - return Collections.unmodifiableSet(domainMap.keySet()); - } - - @Override - public boolean equals(Object o) { - - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RouteResult that = (RouteResult) o; - return Objects.equals(domainMap, that.domainMap) && Objects.equals(virtualHostMap, that.virtualHostMap); - } - - @Override - public int hashCode() { - return Objects.hash(domainMap, virtualHostMap); - } - - public VirtualHost searchVirtualHost(String domain) { - return virtualHostMap.get(domain); - } - - public void removeVirtualHost(String domain) { - virtualHostMap.remove(domain); - } - - @Override - public String toString() { - return "RouteResult{" + "domainMap=" + domainMap + ", virtualHostMap=" + virtualHostMap + '}'; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointListener.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointListener.java deleted file mode 100644 index 58aaa86234d..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointListener.java +++ /dev/null @@ -1,26 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; - -import java.util.Set; - -public interface EdsEndpointListener { - - void onEndPointChange(String cluster, Set endpoints); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManager.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManager.java deleted file mode 100644 index a54d74c7bf3..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManager.java +++ /dev/null @@ -1,127 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.registry.xds.util.PilotExchanger; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.registry.xds.util.protocol.message.EndpointResult; -import org.apache.dubbo.rpc.model.FrameworkModel; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class EdsEndpointManager { - - private static final ConcurrentHashMap> ENDPOINT_LISTENERS = - new ConcurrentHashMap<>(); - - private static final ConcurrentHashMap> ENDPOINT_DATA_CACHE = new ConcurrentHashMap<>(); - - private static final ConcurrentHashMap>> EDS_LISTENERS = - new ConcurrentHashMap<>(); - - public EdsEndpointManager() {} - - public synchronized void subscribeEds(String cluster, EdsEndpointListener listener) { - - Set listeners = - ConcurrentHashMapUtils.computeIfAbsent(ENDPOINT_LISTENERS, cluster, key -> new ConcurrentHashSet<>()); - if (CollectionUtils.isEmpty(listeners)) { - doSubscribeEds(cluster); - } - listeners.add(listener); - - if (ENDPOINT_DATA_CACHE.containsKey(cluster)) { - listener.onEndPointChange(cluster, ENDPOINT_DATA_CACHE.get(cluster)); - } - } - - private void doSubscribeEds(String cluster) { - ConcurrentHashMapUtils.computeIfAbsent(EDS_LISTENERS, cluster, key -> endpoints -> { - Set result = endpoints.values().stream() - .map(EndpointResult::getEndpoints) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - notifyEndpointChange(cluster, result); - }); - Consumer> consumer = EDS_LISTENERS.get(cluster); - if (PilotExchanger.isEnabled()) { - FrameworkModel.defaultModel() - .getBeanFactory() - .getBean(FrameworkExecutorRepository.class) - .getSharedExecutor() - .submit(() -> PilotExchanger.getInstance().observeEds(Collections.singleton(cluster), consumer)); - } - } - - public synchronized void unSubscribeEds(String cluster, EdsEndpointListener listener) { - Set listeners = ENDPOINT_LISTENERS.get(cluster); - if (CollectionUtils.isEmpty(listeners)) { - return; - } - listeners.remove(listener); - if (listeners.isEmpty()) { - ENDPOINT_LISTENERS.remove(cluster); - doUnsubscribeEds(cluster); - } - } - - private void doUnsubscribeEds(String cluster) { - Consumer> consumer = EDS_LISTENERS.remove(cluster); - - if (consumer != null && PilotExchanger.isEnabled()) { - PilotExchanger.getInstance().unObserveEds(Collections.singleton(cluster), consumer); - } - ENDPOINT_DATA_CACHE.remove(cluster); - } - - public void notifyEndpointChange(String cluster, Set endpoints) { - - ENDPOINT_DATA_CACHE.put(cluster, endpoints); - - Set listeners = ENDPOINT_LISTENERS.get(cluster); - if (CollectionUtils.isEmpty(listeners)) { - return; - } - for (EdsEndpointListener listener : listeners) { - listener.onEndPointChange(cluster, endpoints); - } - } - - // for test - static ConcurrentHashMap> getEndpointListeners() { - return ENDPOINT_LISTENERS; - } - - // for test - static ConcurrentHashMap> getEndpointDataCache() { - return ENDPOINT_DATA_CACHE; - } - - // for test - static ConcurrentHashMap>> getEdsListeners() { - return EDS_LISTENERS; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManager.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManager.java deleted file mode 100644 index b0371729eb3..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManager.java +++ /dev/null @@ -1,162 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.registry.xds.util.PilotExchanger; -import org.apache.dubbo.registry.xds.util.protocol.message.ListenerResult; -import org.apache.dubbo.registry.xds.util.protocol.message.RouteResult; -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Consumer; - -import io.envoyproxy.envoy.config.route.v3.VirtualHost; - -public class RdsRouteRuleManager { - - private static final ConcurrentHashMap> RULE_LISTENERS = - new ConcurrentHashMap<>(); - - private static final ConcurrentHashMap> ROUTE_DATA_CACHE = new ConcurrentHashMap<>(); - - private static final ConcurrentMap RDS_LISTENERS = new ConcurrentHashMap<>(); - - private static volatile Consumer> LDS_LISTENER; - - private static volatile Consumer> RDS_LISTENER; - - private static Map RDS_RESULT; - - public RdsRouteRuleManager() {} - - public synchronized void subscribeRds(String domain, XdsRouteRuleListener listener) { - - Set listeners = - ConcurrentHashMapUtils.computeIfAbsent(RULE_LISTENERS, domain, key -> new ConcurrentHashSet<>()); - if (CollectionUtils.isEmpty(listeners)) { - doSubscribeRds(domain); - } - listeners.add(listener); - - if (ROUTE_DATA_CACHE.containsKey(domain)) { - listener.onRuleChange(domain, ROUTE_DATA_CACHE.get(domain)); - } - } - - private void doSubscribeRds(String domain) { - synchronized (RdsRouteRuleManager.class) { - if (RDS_LISTENER == null) { - RDS_LISTENER = rds -> { - if (rds == null) { - return; - } - for (RouteResult routeResult : rds.values()) { - for (String domainToNotify : RDS_LISTENERS.keySet()) { - VirtualHost virtualHost = routeResult.searchVirtualHost(domainToNotify); - if (virtualHost != null) { - RDS_LISTENERS.get(domainToNotify).parseVirtualHost(virtualHost); - } - } - } - RDS_RESULT = rds; - }; - } - if (LDS_LISTENER == null) { - LDS_LISTENER = new Consumer>() { - private volatile Set configNames = null; - - @Override - public void accept(Map listenerResults) { - if (listenerResults.size() == 1) { - for (ListenerResult listenerResult : listenerResults.values()) { - Set newConfigNames = listenerResult.getRouteConfigNames(); - if (configNames == null) { - PilotExchanger.getInstance().observeRds(newConfigNames, RDS_LISTENER); - } else if (!configNames.equals(newConfigNames)) { - PilotExchanger.getInstance().unObserveRds(configNames, RDS_LISTENER); - PilotExchanger.getInstance().observeRds(newConfigNames, RDS_LISTENER); - } - configNames = newConfigNames; - } - } - } - }; - if (PilotExchanger.isEnabled()) { - PilotExchanger.getInstance().observeLds(LDS_LISTENER); - } - } - } - ConcurrentHashMapUtils.computeIfAbsent(RDS_LISTENERS, domain, key -> new RdsVirtualHostListener(domain, this)); - RDS_LISTENER.accept(RDS_RESULT); - } - - public synchronized void unSubscribeRds(String domain, XdsRouteRuleListener listener) { - Set listeners = RULE_LISTENERS.get(domain); - if (CollectionUtils.isEmpty(listeners)) { - return; - } - listeners.remove(listener); - if (listeners.isEmpty()) { - RULE_LISTENERS.remove(domain); - doUnsubscribeRds(domain); - } - } - - private void doUnsubscribeRds(String domain) { - RDS_LISTENERS.remove(domain); - } - - public void notifyRuleChange(String domain, List xdsRouteRules) { - - ROUTE_DATA_CACHE.put(domain, xdsRouteRules); - - Set listeners = RULE_LISTENERS.get(domain); - if (CollectionUtils.isEmpty(listeners)) { - return; - } - boolean empty = CollectionUtils.isEmpty(xdsRouteRules); - for (XdsRouteRuleListener listener : listeners) { - if (empty) { - listener.clearRule(domain); - } else { - listener.onRuleChange(domain, xdsRouteRules); - } - } - } - - // for test - static ConcurrentHashMap> getRuleListeners() { - return RULE_LISTENERS; - } - - // for test - static ConcurrentHashMap> getRouteDataCache() { - return ROUTE_DATA_CACHE; - } - - // for test - static Map getRdsListeners() { - return RDS_LISTENERS; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListener.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListener.java deleted file mode 100644 index 58771788eeb..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListener.java +++ /dev/null @@ -1,184 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.constants.LoggerCodeConstants; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.rpc.cluster.router.xds.rule.ClusterWeight; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HTTPRouteDestination; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HeaderMatcher; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HttpRequestMatch; -import org.apache.dubbo.rpc.cluster.router.xds.rule.LongRangeMatch; -import org.apache.dubbo.rpc.cluster.router.xds.rule.PathMatcher; -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import io.envoyproxy.envoy.config.route.v3.Route; -import io.envoyproxy.envoy.config.route.v3.RouteAction; -import io.envoyproxy.envoy.config.route.v3.RouteMatch; -import io.envoyproxy.envoy.config.route.v3.VirtualHost; - -public class RdsVirtualHostListener { - - private static final ErrorTypeAwareLogger LOGGER = - LoggerFactory.getErrorTypeAwareLogger(RdsVirtualHostListener.class); - - private final String domain; - - private final RdsRouteRuleManager routeRuleManager; - - public RdsVirtualHostListener(String domain, RdsRouteRuleManager routeRuleManager) { - this.domain = domain; - this.routeRuleManager = routeRuleManager; - } - - public void parseVirtualHost(VirtualHost virtualHost) { - if (virtualHost == null || CollectionUtils.isEmpty(virtualHost.getRoutesList())) { - // post empty - routeRuleManager.notifyRuleChange(domain, new ArrayList<>()); - return; - } - try { - List xdsRouteRules = virtualHost.getRoutesList().stream() - .map(route -> { - if (route.getMatch().getQueryParametersCount() != 0) { - return null; - } - HttpRequestMatch match = parseMatch(route.getMatch()); - HTTPRouteDestination action = parseAction(route); - return new XdsRouteRule(match, action); - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - // post rules - routeRuleManager.notifyRuleChange(domain, xdsRouteRules); - } catch (Exception e) { - LOGGER.error( - LoggerCodeConstants.INTERNAL_ERROR, - "", - "", - "parse domain: " + domain + " xds VirtualHost error", - e); - } - } - - private HttpRequestMatch parseMatch(RouteMatch match) { - PathMatcher pathMatcher = parsePathMatch(match); - List headerMatchers = parseHeadMatch(match); - return new HttpRequestMatch(pathMatcher, headerMatchers); - } - - private PathMatcher parsePathMatch(RouteMatch match) { - boolean caseSensitive = match.getCaseSensitive().getValue(); - PathMatcher pathMatcher = new PathMatcher(); - pathMatcher.setCaseSensitive(caseSensitive); - switch (match.getPathSpecifierCase()) { - case PREFIX: - pathMatcher.setPrefix(match.getPrefix()); - return pathMatcher; - case PATH: - pathMatcher.setPath(match.getPath()); - return pathMatcher; - case SAFE_REGEX: - String regex = match.getSafeRegex().getRegex(); - pathMatcher.setRegex(regex); - return pathMatcher; - case PATHSPECIFIER_NOT_SET: - return null; - default: - throw new IllegalArgumentException("Path specifier is not expect"); - } - } - - private List parseHeadMatch(RouteMatch routeMatch) { - List headerMatchers = new ArrayList<>(); - List headersList = routeMatch.getHeadersList(); - for (io.envoyproxy.envoy.config.route.v3.HeaderMatcher headerMatcher : headersList) { - HeaderMatcher matcher = new HeaderMatcher(); - matcher.setName(headerMatcher.getName()); - matcher.setInverted(headerMatcher.getInvertMatch()); - switch (headerMatcher.getHeaderMatchSpecifierCase()) { - case EXACT_MATCH: - matcher.setExactValue(headerMatcher.getExactMatch()); - headerMatchers.add(matcher); - break; - case SAFE_REGEX_MATCH: - matcher.setRegex(headerMatcher.getSafeRegexMatch().getRegex()); - headerMatchers.add(matcher); - break; - case RANGE_MATCH: - LongRangeMatch rang = new LongRangeMatch(); - rang.setStart(headerMatcher.getRangeMatch().getStart()); - rang.setEnd(headerMatcher.getRangeMatch().getEnd()); - matcher.setRange(rang); - headerMatchers.add(matcher); - break; - case PRESENT_MATCH: - matcher.setPresent(headerMatcher.getPresentMatch()); - headerMatchers.add(matcher); - break; - case PREFIX_MATCH: - matcher.setPrefix(headerMatcher.getPrefixMatch()); - headerMatchers.add(matcher); - break; - case SUFFIX_MATCH: - matcher.setSuffix(headerMatcher.getSuffixMatch()); - headerMatchers.add(matcher); - break; - case HEADERMATCHSPECIFIER_NOT_SET: - default: - throw new IllegalArgumentException("Header specifier is not expect"); - } - } - return headerMatchers; - } - - private HTTPRouteDestination parseAction(Route route) { - switch (route.getActionCase()) { - case ROUTE: - HTTPRouteDestination httpRouteDestination = new HTTPRouteDestination(); - // only support cluster and weight cluster - RouteAction routeAction = route.getRoute(); - RouteAction.ClusterSpecifierCase clusterSpecifierCase = routeAction.getClusterSpecifierCase(); - if (clusterSpecifierCase == RouteAction.ClusterSpecifierCase.CLUSTER) { - httpRouteDestination.setCluster(routeAction.getCluster()); - return httpRouteDestination; - } else if (clusterSpecifierCase == RouteAction.ClusterSpecifierCase.WEIGHTED_CLUSTERS) { - List clusterWeights = routeAction.getWeightedClusters().getClustersList().stream() - .map(c -> - new ClusterWeight(c.getName(), c.getWeight().getValue())) - .sorted(Comparator.comparing(ClusterWeight::getWeight)) - .collect(Collectors.toList()); - httpRouteDestination.setWeightedClusters(clusterWeights); - return httpRouteDestination; - } - case REDIRECT: - case DIRECT_RESPONSE: - case FILTER_ACTION: - case ACTION_NOT_SET: - default: - throw new IllegalArgumentException("Cluster specifier is not expect"); - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteRuleListener.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteRuleListener.java deleted file mode 100644 index 4e90fe2d41e..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteRuleListener.java +++ /dev/null @@ -1,28 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; - -import java.util.List; - -public interface XdsRouteRuleListener { - - void onRuleChange(String appName, List xdsRouteRules); - - void clearRule(String appName); -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouter.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouter.java deleted file mode 100644 index e043e2d3d74..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouter.java +++ /dev/null @@ -1,391 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.common.utils.Holder; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.registry.xds.util.PilotExchanger; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; -import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; -import org.apache.dubbo.rpc.cluster.router.state.BitList; -import org.apache.dubbo.rpc.cluster.router.xds.rule.ClusterWeight; -import org.apache.dubbo.rpc.cluster.router.xds.rule.DestinationSubset; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HTTPRouteDestination; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HeaderMatcher; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HttpRequestMatch; -import org.apache.dubbo.rpc.cluster.router.xds.rule.PathMatcher; -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; -import org.apache.dubbo.rpc.support.RpcUtils; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.Collectors; - -public class XdsRouter extends AbstractStateRouter implements XdsRouteRuleListener, EdsEndpointListener { - - private Set subscribeApplications; - - private final ConcurrentHashMap> xdsRouteRuleMap; - - private final ConcurrentHashMap> destinationSubsetMap; - - private final RdsRouteRuleManager rdsRouteRuleManager; - - private final EdsEndpointManager edsEndpointManager; - - private volatile BitList> currentInvokeList; - - private static final String BINARY_HEADER_SUFFIX = "-bin"; - - private final boolean isEnable; - - public XdsRouter(URL url) { - super(url); - isEnable = PilotExchanger.isEnabled(); - rdsRouteRuleManager = - url.getOrDefaultApplicationModel().getBeanFactory().getBean(RdsRouteRuleManager.class); - edsEndpointManager = url.getOrDefaultApplicationModel().getBeanFactory().getBean(EdsEndpointManager.class); - subscribeApplications = new ConcurrentHashSet<>(); - destinationSubsetMap = new ConcurrentHashMap<>(); - xdsRouteRuleMap = new ConcurrentHashMap<>(); - currentInvokeList = new BitList<>(new ArrayList<>()); - } - - /** - * @deprecated only for uts - */ - protected XdsRouter( - URL url, RdsRouteRuleManager rdsRouteRuleManager, EdsEndpointManager edsEndpointManager, boolean isEnable) { - super(url); - this.isEnable = isEnable; - this.rdsRouteRuleManager = rdsRouteRuleManager; - this.edsEndpointManager = edsEndpointManager; - subscribeApplications = new ConcurrentHashSet<>(); - destinationSubsetMap = new ConcurrentHashMap<>(); - xdsRouteRuleMap = new ConcurrentHashMap<>(); - currentInvokeList = new BitList<>(new ArrayList<>()); - } - - @Override - protected BitList> doRoute( - BitList> invokers, - URL url, - Invocation invocation, - boolean needToPrintMessage, - Holder> nodeHolder, - Holder messageHolder) - throws RpcException { - if (!isEnable) { - if (needToPrintMessage) { - messageHolder.set( - "Directly Return. Reason: Pilot exchanger has not been initialized, may not in mesh mode."); - } - return invokers; - } - - if (CollectionUtils.isEmpty(invokers)) { - if (needToPrintMessage) { - messageHolder.set("Directly Return. Reason: Invokers from previous router is empty."); - } - return invokers; - } - - if (CollectionUtils.isEmptyMap(xdsRouteRuleMap)) { - if (needToPrintMessage) { - messageHolder.set("Directly Return. Reason: xds route rule is empty."); - } - return invokers; - } - - StringBuilder stringBuilder = needToPrintMessage ? new StringBuilder() : null; - - // find match cluster - String matchCluster = null; - Set appNames = subscribeApplications; - for (String subscribeApplication : appNames) { - List rules = xdsRouteRuleMap.get(subscribeApplication); - if (CollectionUtils.isEmpty(rules)) { - continue; - } - for (XdsRouteRule rule : rules) { - String cluster = computeMatchCluster(invocation, rule); - if (cluster != null) { - matchCluster = cluster; - break; - } - } - if (matchCluster != null) { - if (stringBuilder != null) { - stringBuilder - .append("Match App: ") - .append(subscribeApplication) - .append(" Cluster: ") - .append(matchCluster) - .append(' '); - } - break; - } - } - // not match request just return - if (matchCluster == null) { - if (needToPrintMessage) { - messageHolder.set("Directly Return. Reason: xds rule not match."); - } - return invokers; - } - DestinationSubset destinationSubset = destinationSubsetMap.get(matchCluster); - // cluster no target provider - if (destinationSubset == null) { - if (needToPrintMessage) { - messageHolder.set(stringBuilder.append("no target subset").toString()); - } - return BitList.emptyList(); - } - if (needToPrintMessage) { - messageHolder.set(stringBuilder.toString()); - } - if (destinationSubset.getInvokers() == null) { - return BitList.emptyList(); - } - - return destinationSubset.getInvokers().and(invokers); - } - - private String computeMatchCluster(Invocation invocation, XdsRouteRule rule) { - // compute request match cluster - HttpRequestMatch requestMatch = rule.getMatch(); - if (requestMatch.getPathMatcher() == null && CollectionUtils.isEmpty(requestMatch.getHeaderMatcherList())) { - return null; - } - PathMatcher pathMatcher = requestMatch.getPathMatcher(); - if (pathMatcher != null) { - String path = "/" + invocation.getInvoker().getUrl().getPath() + "/" + RpcUtils.getMethodName(invocation); - if (!pathMatcher.isMatch(path)) { - return null; - } - } - List headerMatchers = requestMatch.getHeaderMatcherList(); - for (HeaderMatcher headerMatcher : headerMatchers) { - String headerName = headerMatcher.getName(); - // not support byte - if (headerName.endsWith(BINARY_HEADER_SUFFIX)) { - return null; - } - String headValue = invocation.getAttachment(headerName); - if (!headerMatcher.match(headValue)) { - return null; - } - } - HTTPRouteDestination route = rule.getRoute(); - if (route.getCluster() != null) { - return route.getCluster(); - } - return computeWeightCluster(route.getWeightedClusters()); - } - - private String computeWeightCluster(List weightedClusters) { - int totalWeight = Math.max( - weightedClusters.stream().mapToInt(ClusterWeight::getWeight).sum(), 1); - // target must greater than 0 - // if weight is 0, the destination will not receive any traffic. - int target = ThreadLocalRandom.current().nextInt(1, totalWeight + 1); - for (ClusterWeight weightedCluster : weightedClusters) { - int weight = weightedCluster.getWeight(); - target -= weight; - if (target <= 0) { - return weightedCluster.getName(); - } - } - return null; - } - - public void notify(BitList> invokers) { - BitList> invokerList = invokers == null ? BitList.emptyList() : invokers; - currentInvokeList = invokerList.clone(); - - // compute need subscribe/unsubscribe rds application - Set currentApplications = new HashSet<>(); - for (Invoker invoker : invokerList) { - String applicationName = invoker.getUrl().getRemoteApplication(); - if (StringUtils.isNotEmpty(applicationName)) { - currentApplications.add(applicationName); - } - } - - if (!subscribeApplications.equals(currentApplications)) { - synchronized (this) { - for (String currentApplication : currentApplications) { - if (!subscribeApplications.contains(currentApplication)) { - rdsRouteRuleManager.subscribeRds(currentApplication, this); - } - } - for (String preApplication : subscribeApplications) { - if (!currentApplications.contains(preApplication)) { - rdsRouteRuleManager.unSubscribeRds(preApplication, this); - } - } - subscribeApplications = currentApplications; - } - } - - // update subset - synchronized (this) { - BitList> allInvokers = currentInvokeList.clone(); - for (DestinationSubset subset : destinationSubsetMap.values()) { - computeSubset(subset, allInvokers); - } - } - } - - private void computeSubset(DestinationSubset subset, BitList> invokers) { - Set endpoints = subset.getEndpoints(); - List> filterInvokers = invokers.stream() - .filter(inv -> { - String host = inv.getUrl().getHost(); - int port = inv.getUrl().getPort(); - Optional any = endpoints.stream() - .filter(end -> host.equals(end.getAddress()) && port == end.getPortValue()) - .findAny(); - return any.isPresent(); - }) - .collect(Collectors.toList()); - subset.setInvokers(new BitList<>(filterInvokers)); - } - - @Override - public synchronized void onRuleChange(String appName, List xdsRouteRules) { - if (CollectionUtils.isEmpty(xdsRouteRules)) { - clearRule(appName); - return; - } - Set oldCluster = getAllCluster(); - xdsRouteRuleMap.put(appName, xdsRouteRules); - Set newCluster = getAllCluster(); - changeClusterSubscribe(oldCluster, newCluster); - } - - private Set getAllCluster() { - if (CollectionUtils.isEmptyMap(xdsRouteRuleMap)) { - return new HashSet<>(); - } - Set clusters = new HashSet<>(); - xdsRouteRuleMap.forEach((appName, rules) -> { - for (XdsRouteRule rule : rules) { - HTTPRouteDestination action = rule.getRoute(); - if (action.getCluster() != null) { - clusters.add(action.getCluster()); - } else if (CollectionUtils.isNotEmpty(action.getWeightedClusters())) { - for (ClusterWeight weightedCluster : action.getWeightedClusters()) { - clusters.add(weightedCluster.getName()); - } - } - } - }); - return clusters; - } - - private void changeClusterSubscribe(Set oldCluster, Set newCluster) { - Set removeSubscribe = new HashSet<>(oldCluster); - Set addSubscribe = new HashSet<>(newCluster); - - removeSubscribe.removeAll(newCluster); - addSubscribe.removeAll(oldCluster); - // remove subscribe cluster - for (String cluster : removeSubscribe) { - edsEndpointManager.unSubscribeEds(cluster, this); - destinationSubsetMap.remove(cluster); - } - // add subscribe cluster - for (String cluster : addSubscribe) { - destinationSubsetMap.put(cluster, new DestinationSubset<>(cluster)); - edsEndpointManager.subscribeEds(cluster, this); - } - } - - @Override - public synchronized void clearRule(String appName) { - Set oldCluster = getAllCluster(); - List oldRules = xdsRouteRuleMap.remove(appName); - if (CollectionUtils.isEmpty(oldRules)) { - return; - } - Set newCluster = getAllCluster(); - changeClusterSubscribe(oldCluster, newCluster); - } - - @Override - public synchronized void onEndPointChange(String cluster, Set endpoints) { - // find and update subset - DestinationSubset subset = destinationSubsetMap.get(cluster); - if (subset == null) { - return; - } - subset.setEndpoints(endpoints); - computeSubset(subset, currentInvokeList.clone()); - } - - @Override - public void stop() { - for (String app : subscribeApplications) { - rdsRouteRuleManager.unSubscribeRds(app, this); - } - for (String cluster : getAllCluster()) { - edsEndpointManager.unSubscribeEds(cluster, this); - } - } - - @Deprecated - Set getSubscribeApplications() { - return subscribeApplications; - } - - /** - * for ut only - */ - @Deprecated - BitList> getInvokerList() { - return currentInvokeList; - } - - /** - * for ut only - */ - @Deprecated - ConcurrentHashMap> getXdsRouteRuleMap() { - return xdsRouteRuleMap; - } - - /** - * for ut only - */ - @Deprecated - ConcurrentHashMap> getDestinationSubsetMap() { - return destinationSubsetMap; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouterFactory.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouterFactory.java deleted file mode 100644 index 0e9a0c57503..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouterFactory.java +++ /dev/null @@ -1,31 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.extension.Activate; -import org.apache.dubbo.rpc.cluster.router.state.StateRouter; -import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; - -@Activate(order = 100) -public class XdsRouterFactory implements StateRouterFactory { - - @Override - public StateRouter getRouter(Class interfaceClass, URL url) { - return new XdsRouter<>(url); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsScopeModelInitializer.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsScopeModelInitializer.java deleted file mode 100644 index b34b86ffce2..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/XdsScopeModelInitializer.java +++ /dev/null @@ -1,39 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.FrameworkModel; -import org.apache.dubbo.rpc.model.ModuleModel; -import org.apache.dubbo.rpc.model.ScopeModelInitializer; - -public class XdsScopeModelInitializer implements ScopeModelInitializer { - - @Override - public void initializeFrameworkModel(FrameworkModel frameworkModel) {} - - @Override - public void initializeApplicationModel(ApplicationModel applicationModel) { - ScopeBeanFactory beanFactory = applicationModel.getBeanFactory(); - beanFactory.registerBean(RdsRouteRuleManager.class); - beanFactory.registerBean(EdsEndpointManager.class); - } - - @Override - public void initializeModuleModel(ModuleModel moduleModel) {} -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/ClusterWeight.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/ClusterWeight.java deleted file mode 100644 index fe1307c8f64..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/ClusterWeight.java +++ /dev/null @@ -1,37 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -public class ClusterWeight { - - private final String name; - - private final int weight; - - public ClusterWeight(String name, int weight) { - this.name = name; - this.weight = weight; - } - - public String getName() { - return name; - } - - public int getWeight() { - return weight; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/DestinationSubset.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/DestinationSubset.java deleted file mode 100644 index 79fa2156f62..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/DestinationSubset.java +++ /dev/null @@ -1,57 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.cluster.router.state.BitList; - -import java.util.HashSet; -import java.util.Set; - -public class DestinationSubset { - - public DestinationSubset(String clusterName) { - this.clusterName = clusterName; - } - - private final String clusterName; - - private Set endpoints = new HashSet<>(); - - private BitList> invokers; - - public String getClusterName() { - return clusterName; - } - - public Set getEndpoints() { - return endpoints; - } - - public void setEndpoints(Set endpoints) { - this.endpoints = endpoints; - } - - public BitList> getInvokers() { - return invokers; - } - - public void setInvokers(BitList> invokers) { - this.invokers = invokers; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HTTPRouteDestination.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HTTPRouteDestination.java deleted file mode 100644 index 91d55d337f4..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HTTPRouteDestination.java +++ /dev/null @@ -1,42 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -import java.util.List; - -public class HTTPRouteDestination { - - private String cluster; - - private List weightedClusters; - - public String getCluster() { - return cluster; - } - - public void setCluster(String cluster) { - this.cluster = cluster; - } - - public List getWeightedClusters() { - return weightedClusters; - } - - public void setWeightedClusters(List weightedClusters) { - this.weightedClusters = weightedClusters; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcher.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcher.java deleted file mode 100644 index 04b0c45a04c..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcher.java +++ /dev/null @@ -1,121 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -public class HeaderMatcher { - - public String name; - - public String exactValue; - - private String regex; - - public LongRangeMatch range; - - public Boolean present; - - public String prefix; - - public String suffix; - - public boolean inverted; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getExactValue() { - return exactValue; - } - - public void setExactValue(String exactValue) { - this.exactValue = exactValue; - } - - public String getRegex() { - return regex; - } - - public void setRegex(String regex) { - this.regex = regex; - } - - public LongRangeMatch getRange() { - return range; - } - - public void setRange(LongRangeMatch range) { - this.range = range; - } - - public Boolean getPresent() { - return present; - } - - public void setPresent(Boolean present) { - this.present = present; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public boolean isInverted() { - return inverted; - } - - public void setInverted(boolean inverted) { - this.inverted = inverted; - } - - public boolean match(String input) { - if (getPresent() != null) { - return (input == null) == getPresent().equals(isInverted()); - } - if (input == null) { - return false; - } - if (getExactValue() != null) { - return getExactValue().equals(input) != isInverted(); - } else if (getRegex() != null) { - return input.matches(getRegex()) != isInverted(); - } else if (getRange() != null) { - return getRange().isMatch(input) != isInverted(); - } else if (getPrefix() != null) { - return input.startsWith(getPrefix()) != isInverted(); - } else if (getSuffix() != null) { - return input.endsWith(getSuffix()) != isInverted(); - } - return false; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HttpRequestMatch.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HttpRequestMatch.java deleted file mode 100644 index fef5aa18e48..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HttpRequestMatch.java +++ /dev/null @@ -1,39 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -import java.util.List; - -public class HttpRequestMatch { - - private final PathMatcher pathMatcher; - - private final List headerMatcherList; - - public HttpRequestMatch(PathMatcher pathMatcher, List headerMatcherList) { - this.pathMatcher = pathMatcher; - this.headerMatcherList = headerMatcherList; - } - - public PathMatcher getPathMatcher() { - return pathMatcher; - } - - public List getHeaderMatcherList() { - return headerMatcherList; - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/LongRangeMatch.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/LongRangeMatch.java deleted file mode 100644 index df482575bd4..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/LongRangeMatch.java +++ /dev/null @@ -1,47 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -public class LongRangeMatch { - private long start; - private long end; - - public long getStart() { - return start; - } - - public void setStart(long start) { - this.start = start; - } - - public long getEnd() { - return end; - } - - public void setEnd(long end) { - this.end = end; - } - - public boolean isMatch(String input) { - try { - long num = Long.parseLong(input); - return num >= getStart() && num <= getEnd(); - } catch (NumberFormatException ignore) { - return false; - } - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcher.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcher.java deleted file mode 100644 index cbf77e8711f..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcher.java +++ /dev/null @@ -1,71 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -public class PathMatcher { - - private String path; - - private String prefix; - - private String regex; - - private boolean caseSensitive; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getRegex() { - return regex; - } - - public void setRegex(String regex) { - this.regex = regex; - } - - public boolean isCaseSensitive() { - return caseSensitive; - } - - public void setCaseSensitive(boolean caseSensitive) { - this.caseSensitive = caseSensitive; - } - - public boolean isMatch(String input) { - if (getPath() != null) { - return isCaseSensitive() ? getPath().equals(input) : getPath().equalsIgnoreCase(input); - } else if (getPrefix() != null) { - return isCaseSensitive() - ? input.startsWith(getPrefix()) - : input.toLowerCase().startsWith(getPrefix()); - } - return input.matches(getRegex()); - } -} diff --git a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/XdsRouteRule.java b/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/XdsRouteRule.java deleted file mode 100644 index 5d2994d2d6b..00000000000 --- a/dubbo-xds/src/main/java/org/apache/dubbo/rpc/cluster/router/xds/rule/XdsRouteRule.java +++ /dev/null @@ -1,37 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -public class XdsRouteRule { - - private final HttpRequestMatch match; - - private final HTTPRouteDestination route; - - public XdsRouteRule(HttpRequestMatch match, HTTPRouteDestination route) { - this.match = match; - this.route = route; - } - - public HttpRequestMatch getMatch() { - return match; - } - - public HTTPRouteDestination getRoute() { - return route; - } -} diff --git a/dubbo-xds/src/main/proto/ca.proto b/dubbo-xds/src/main/proto/ca.proto deleted file mode 100644 index 41e6addb79f..00000000000 --- a/dubbo-xds/src/main/proto/ca.proto +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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. - -// The canonical version of this proto can be found at -// https://github.com/istio/api/blob/9abf4c87205f6ad04311fa021ce60803d8b95f78/security/v1alpha1/ca.proto - -syntax = "proto3"; - -import "google/protobuf/struct.proto"; - -// Keep this package for backward compatibility. -package istio.v1.auth; - -option go_package = "istio.io/api/security/v1alpha1"; -option java_generic_services = true; -option java_multiple_files = true; - -// Certificate request message. The authentication should be based on: -// 1. Bearer tokens carried in the side channel; -// 2. Client-side certificate via Mutual TLS handshake. -// Note: the service implementation is REQUIRED to verify the authenticated caller is authorize to -// all SANs in the CSR. The server side may overwrite any requested certificate field based on its -// policies. -message IstioCertificateRequest { - // PEM-encoded certificate request. - // The public key in the CSR is used to generate the certificate, - // and other fields in the generated certificate may be overwritten by the CA. - string csr = 1; - // Optional: requested certificate validity period, in seconds. - int64 validity_duration = 3; - - // $hide_from_docs - // Optional: Opaque metadata provided by the XDS node to Istio. - // Supported metadata: WorkloadName, WorkloadIP, ClusterID - google.protobuf.Struct metadata = 4; -} - -// Certificate response message. -message IstioCertificateResponse { - // PEM-encoded certificate chain. - // The leaf cert is the first element, and the root cert is the last element. - repeated string cert_chain = 1; -} - -// Service for managing certificates issued by the CA. -service IstioCertificateService { - // Using provided CSR, returns a signed certificate. - rpc CreateCertificate(IstioCertificateRequest) - returns (IstioCertificateResponse) { - } -} diff --git a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory deleted file mode 100644 index 2ee954e9592..00000000000 --- a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory +++ /dev/null @@ -1 +0,0 @@ -xds=org.apache.dubbo.registry.xds.XdsRegistryFactory diff --git a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory b/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory deleted file mode 100644 index e6dfce272ab..00000000000 --- a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory +++ /dev/null @@ -1 +0,0 @@ -xds=org.apache.dubbo.registry.xds.XdsServiceDiscoveryFactory diff --git a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner b/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner deleted file mode 100644 index bbfc0fb9d81..00000000000 --- a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner +++ /dev/null @@ -1 +0,0 @@ -istio=org.apache.dubbo.registry.xds.istio.IstioCitadelCertificateSigner diff --git a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory b/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory deleted file mode 100644 index ca9b94ea847..00000000000 --- a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory +++ /dev/null @@ -1 +0,0 @@ -xds=org.apache.dubbo.rpc.cluster.router.xds.XdsRouterFactory \ No newline at end of file diff --git a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer b/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer deleted file mode 100644 index 3005831c669..00000000000 --- a/dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer +++ /dev/null @@ -1 +0,0 @@ -xds-route=org.apache.dubbo.rpc.cluster.router.xds.XdsScopeModelInitializer diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java deleted file mode 100644 index 8efcdb02f08..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java +++ /dev/null @@ -1,148 +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 org.apache.dubbo.registry.xds.util.bootstrap; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.url.component.URLAddress; -import org.apache.dubbo.registry.xds.XdsInitializationException; - -import java.util.List; - -import io.grpc.netty.shaded.io.netty.channel.unix.DomainSocketAddress; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class BootstrapperTest { - @Test - void testParse() throws XdsInitializationException { - String rawData = "{\n" + " \"xds_servers\": [\n" - + " {\n" - + " \"server_uri\": \"unix:///etc/istio/proxy/XDS\",\n" - + " \"channel_creds\": [\n" - + " {\n" - + " \"type\": \"insecure\"\n" - + " }\n" - + " ],\n" - + " \"server_features\": [\n" - + " \"xds_v3\"\n" - + " ]\n" - + " }\n" - + " ],\n" - + " \"node\": {\n" - + " \"id\": \"sidecar~172.17.0.4~dubbo-demo-consumer-deployment-grpc-agent-58585cb9cd-gp79p.dubbo-demo~dubbo-demo.svc.cluster.local\",\n" - + " \"metadata\": {\n" - + " \"ANNOTATIONS\": {\n" - + " \"inject.istio.io/templates\": \"grpc-agent\",\n" - + " \"kubernetes.io/config.seen\": \"2022-07-19T12:53:29.742565722Z\",\n" - + " \"kubernetes.io/config.source\": \"api\",\n" - + " \"prometheus.io/path\": \"/stats/prometheus\",\n" - + " \"prometheus.io/port\": \"15020\",\n" - + " \"prometheus.io/scrape\": \"true\",\n" - + " \"proxy.istio.io/config\": \"{\\\"holdApplicationUntilProxyStarts\\\": true}\",\n" - + " \"proxy.istio.io/overrides\": \"{\\\"containers\\\":[{\\\"name\\\":\\\"app\\\",\\\"image\\\":\\\"gcr.io/istio-testing/app:latest\\\",\\\"args\\\":[\\\"--metrics=15014\\\",\\\"--port\\\",\\\"18080\\\",\\\"--tcp\\\",\\\"19090\\\",\\\"--xds-grpc-server=17070\\\",\\\"--grpc\\\",\\\"17070\\\",\\\"--grpc\\\",\\\"17171\\\",\\\"--port\\\",\\\"3333\\\",\\\"--port\\\",\\\"8080\\\",\\\"--version\\\",\\\"v1\\\",\\\"--crt=/cert.crt\\\",\\\"--key=/cert.key\\\"],\\\"ports\\\":[{\\\"containerPort\\\":17070,\\\"protocol\\\":\\\"TCP\\\"},{\\\"containerPort\\\":17171,\\\"protocol\\\":\\\"TCP\\\"},{\\\"containerPort\\\":8080,\\\"protocol\\\":\\\"TCP\\\"},{\\\"name\\\":\\\"tcp-health-port\\\",\\\"containerPort\\\":3333,\\\"protocol\\\":\\\"TCP\\\"}],\\\"env\\\":[{\\\"name\\\":\\\"INSTANCE_IP\\\",\\\"valueFrom\\\":{\\\"fieldRef\\\":{\\\"apiVersion\\\":\\\"v1\\\",\\\"fieldPath\\\":\\\"status.podIP\\\"}}}],\\\"resources\\\":{},\\\"volumeMounts\\\":[{\\\"name\\\":\\\"kube-api-access-2tknx\\\",\\\"readOnly\\\":true,\\\"mountPath\\\":\\\"/var/run/secrets/kubernetes.io/serviceaccount\\\"}],\\\"livenessProbe\\\":{\\\"tcpSocket\\\":{\\\"port\\\":\\\"tcp-health-port\\\"},\\\"initialDelaySeconds\\\":10,\\\"timeoutSeconds\\\":1,\\\"periodSeconds\\\":10,\\\"successThreshold\\\":1,\\\"failureThreshold\\\":10},\\\"readinessProbe\\\":{\\\"httpGet\\\":{\\\"path\\\":\\\"/\\\",\\\"port\\\":8080,\\\"scheme\\\":\\\"HTTP\\\"},\\\"initialDelaySeconds\\\":1,\\\"timeoutSeconds\\\":1,\\\"periodSeconds\\\":2,\\\"successThreshold\\\":1,\\\"failureThreshold\\\":10},\\\"startupProbe\\\":{\\\"tcpSocket\\\":{\\\"port\\\":\\\"tcp-health-port\\\"},\\\"timeoutSeconds\\\":1,\\\"periodSeconds\\\":10,\\\"successThreshold\\\":1,\\\"failureThreshold\\\":10},\\\"terminationMessagePath\\\":\\\"/dev/termination-log\\\",\\\"terminationMessagePolicy\\\":\\\"File\\\",\\\"imagePullPolicy\\\":\\\"Always\\\",\\\"securityContext\\\":{\\\"runAsUser\\\":1338,\\\"runAsGroup\\\":1338}},{\\\"name\\\":\\\"dubbo-demo-consumer\\\",\\\"image\\\":\\\"dockeddocking/dubbo:consumer.v1.0\\\",\\\"command\\\":[\\\"sh\\\",\\\"-c\\\",\\\"java $JAVA_OPTS -jar dubbo-demo-consumer.jar \\\"],\\\"resources\\\":{},\\\"volumeMounts\\\":[{\\\"name\\\":\\\"kube-api-access-2tknx\\\",\\\"readOnly\\\":true,\\\"mountPath\\\":\\\"/var/run/secrets/kubernetes.io/serviceaccount\\\"}],\\\"terminationMessagePath\\\":\\\"/dev/termination-log\\\",\\\"terminationMessagePolicy\\\":\\\"File\\\",\\\"imagePullPolicy\\\":\\\"Always\\\"}]}\",\n" - + " \"sidecar.istio.io/rewriteAppHTTPProbers\": \"false\",\n" - + " \"sidecar.istio.io/status\": \"{\\\"initContainers\\\":null,\\\"containers\\\":[\\\"app\\\",\\\"dubbo-demo-consumer\\\",\\\"istio-proxy\\\"],\\\"volumes\\\":[\\\"workload-socket\\\",\\\"workload-certs\\\",\\\"istio-xds\\\",\\\"istio-data\\\",\\\"istio-podinfo\\\",\\\"istio-token\\\",\\\"istiod-ca-cert\\\"],\\\"imagePullSecrets\\\":null,\\\"revision\\\":\\\"default\\\"}\"\n" - + " },\n" - + " \"APP_CONTAINERS\": \"app,dubbo-demo-consumer\",\n" - + " \"CLUSTER_ID\": \"Kubernetes\",\n" - + " \"ENVOY_PROMETHEUS_PORT\": 15090,\n" - + " \"ENVOY_STATUS_PORT\": 15021,\n" - + " \"GENERATOR\": \"grpc\",\n" - + " \"INSTANCE_IPS\": \"172.17.0.4\",\n" - + " \"INTERCEPTION_MODE\": \"REDIRECT\",\n" - + " \"ISTIO_PROXY_SHA\": \"2b6009118109b480e1d5abf3188fd7d9c0c0acf0\",\n" - + " \"ISTIO_VERSION\": \"1.14.1\",\n" - + " \"LABELS\": {\n" - + " \"app\": \"dubbo-demo-consumer-dev\",\n" - + " \"pod-template-hash\": \"58585cb9cd\",\n" - + " \"service.istio.io/canonical-name\": \"dubbo-demo-consumer-dev\",\n" - + " \"service.istio.io/canonical-revision\": \"v1\",\n" - + " \"version\": \"v1\"\n" - + " },\n" - + " \"MESH_ID\": \"cluster.local\",\n" - + " \"NAME\": \"dubbo-demo-consumer-deployment-grpc-agent-58585cb9cd-gp79p\",\n" - + " \"NAMESPACE\": \"dubbo-demo\",\n" - + " \"OWNER\": \"kubernetes://apis/apps/v1/namespaces/dubbo-demo/deployments/dubbo-demo-consumer-deployment-grpc-agent\",\n" - + " \"PILOT_SAN\": [\n" - + " \"istiod.istio-system.svc\"\n" - + " ],\n" - + " \"POD_PORTS\": \"[{\\\"containerPort\\\":17070,\\\"protocol\\\":\\\"TCP\\\"},{\\\"containerPort\\\":17171,\\\"protocol\\\":\\\"TCP\\\"},{\\\"containerPort\\\":8080,\\\"protocol\\\":\\\"TCP\\\"},{\\\"name\\\":\\\"tcp-health-port\\\",\\\"containerPort\\\":3333,\\\"protocol\\\":\\\"TCP\\\"}]\",\n" - + " \"PROV_CERT\": \"var/run/secrets/istio/root-cert.pem\",\n" - + " \"PROXY_CONFIG\": {\n" - + " \"binaryPath\": \"/usr/local/bin/envoy\",\n" - + " \"concurrency\": 2,\n" - + " \"configPath\": \"./etc/istio/proxy\",\n" - + " \"controlPlaneAuthPolicy\": \"MUTUAL_TLS\",\n" - + " \"discoveryAddress\": \"istiod.istio-system.svc:15012\",\n" - + " \"drainDuration\": \"45s\",\n" - + " \"holdApplicationUntilProxyStarts\": true,\n" - + " \"parentShutdownDuration\": \"60s\",\n" - + " \"proxyAdminPort\": 15000,\n" - + " \"serviceCluster\": \"istio-proxy\",\n" - + " \"statNameLength\": 189,\n" - + " \"statusPort\": 15020,\n" - + " \"terminationDrainDuration\": \"5s\",\n" - + " \"tracing\": {\n" - + " \"zipkin\": {\n" - + " \"address\": \"zipkin.istio-system:9411\"\n" - + " }\n" - + " }\n" - + " },\n" - + " \"SERVICE_ACCOUNT\": \"default\",\n" - + " \"WORKLOAD_NAME\": \"dubbo-demo-consumer-deployment-grpc-agent\"\n" - + " },\n" - + " \"locality\": {},\n" - + " \"UserAgentVersionType\": null\n" - + " },\n" - + " \"certificate_providers\": {\n" - + " \"default\": {\n" - + " \"plugin_name\": \"file_watcher\",\n" - + " \"config\": {\n" - + " \"certificate_file\": \"/var/lib/istio/data/cert-chain.pem\",\n" - + " \"private_key_file\": \"/var/lib/istio/data/key.pem\",\n" - + " \"ca_certificate_file\": \"/var/lib/istio/data/root-cert.pem\",\n" - + " \"refresh_interval\": \"900s\"\n" - + " }\n" - + " }\n" - + " },\n" - + " \"server_listener_resource_name_template\": \"xds.istio.io/grpc/lds/inbound/%s\"\n" - + "}"; - BootstrapperImpl.bootstrapPathFromEnvVar = ""; - BootstrapperImpl bootstrapper = new BootstrapperImpl(); - bootstrapper.setFileReader(createFileReader(rawData)); - Bootstrapper.BootstrapInfo info = bootstrapper.bootstrap(); - List serverInfoList = info.servers(); - Assertions.assertEquals(serverInfoList.get(0).target(), "unix:///etc/istio/proxy/XDS"); - URLAddress address = URLAddress.parse(serverInfoList.get(0).target(), null, false); - Assertions.assertEquals(new DomainSocketAddress(address.getPath()).path(), "etc/istio/proxy/XDS"); - } - - @Test - void testUrl() { - URL url = URL.valueOf("dubbo://127.0.0.1:23456/TestService?useAgent=true"); - Assertions.assertTrue(url.getParameter("useAgent", false)); - } - - private static BootstrapperImpl.FileReader createFileReader(final String rawData) { - return new BootstrapperImpl.FileReader() { - @Override - public String readFile(String path) { - return rawData; - } - }; - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocolMock.java b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocolMock.java deleted file mode 100644 index 6a9d3e46198..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/EdsProtocolMock.java +++ /dev/null @@ -1,51 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.message.EndpointResult; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -import io.envoyproxy.envoy.config.core.v3.Node; - -public class EdsProtocolMock extends EdsProtocol { - - public EdsProtocolMock(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - public Map getResourcesMap() { - return resourcesMap; - } - - public void setResourcesMap(Map resourcesMap) { - this.resourcesMap = resourcesMap; - } - - public void setConsumerObserveMap( - Map, List>>> consumerObserveMap) { - this.consumerObserveMap = consumerObserveMap; - } - - public void setObserveResourcesName(Set observeResourcesName) { - this.observeResourcesName = observeResourcesName; - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocolMock.java b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocolMock.java deleted file mode 100644 index bdeb636698d..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/LdsProtocolMock.java +++ /dev/null @@ -1,68 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.message.ListenerResult; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; - -public class LdsProtocolMock extends LdsProtocol { - - public LdsProtocolMock(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - public Map getResourcesMap() { - return resourcesMap; - } - - public void setResourcesMap(Map resourcesMap) { - this.resourcesMap = resourcesMap; - } - - protected DiscoveryRequest buildDiscoveryRequest(Set resourceNames) { - return DiscoveryRequest.newBuilder() - .setNode(node) - .setTypeUrl(getTypeUrl()) - .addAllResourceNames(resourceNames) - .build(); - } - - public Set getObserveResourcesName() { - return observeResourcesName; - } - - public void setObserveResourcesName(Set observeResourcesName) { - this.observeResourcesName = observeResourcesName; - } - - public Map, List>>> getConsumerObserveMap() { - return consumerObserveMap; - } - - public void setConsumerObserveMap( - Map, List>>> consumerObserveMap) { - this.consumerObserveMap = consumerObserveMap; - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocolMock.java b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocolMock.java deleted file mode 100644 index 7d9aa78d3a6..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/protocol/impl/RdsProtocolMock.java +++ /dev/null @@ -1,54 +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 org.apache.dubbo.registry.xds.util.protocol.impl; - -import org.apache.dubbo.registry.xds.util.AdsObserver; -import org.apache.dubbo.registry.xds.util.protocol.message.RouteResult; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - -import io.envoyproxy.envoy.config.core.v3.Node; - -public class RdsProtocolMock extends RdsProtocol { - - public RdsProtocolMock(AdsObserver adsObserver, Node node, int checkInterval) { - super(adsObserver, node, checkInterval); - } - - public Map getResourcesMap() { - return resourcesMap; - } - - public void setResourcesMap(Map resourcesMap) { - this.resourcesMap = resourcesMap; - } - - public Set getObserveResourcesName() { - return observeResourcesName; - } - - public void setConsumerObserveMap(Map, List>>> consumerObserveMap) { - this.consumerObserveMap = consumerObserveMap; - } - - public void setObserveResourcesName(Set observeResourcesName) { - this.observeResourcesName = observeResourcesName; - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManagerTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManagerTest.java deleted file mode 100644 index 1a1f2f8ceb7..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/EdsEndpointManagerTest.java +++ /dev/null @@ -1,108 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class EdsEndpointManagerTest { - - @BeforeEach - public void before() { - EdsEndpointManager.getEdsListeners().clear(); - EdsEndpointManager.getEndpointListeners().clear(); - EdsEndpointManager.getEndpointDataCache().clear(); - } - - @Test - public void subscribeEdsTest() { - EdsEndpointManager manager = new EdsEndpointManager(); - String cluster = "testApp"; - int subscribeNum = 3; - for (int i = 0; i < subscribeNum; i++) { - manager.subscribeEds(cluster, new EdsEndpointListener() { - @Override - public void onEndPointChange(String cluster, Set endpoints) {} - }); - } - assertNotNull(EdsEndpointManager.getEdsListeners().get(cluster)); - assertEquals(EdsEndpointManager.getEndpointListeners().get(cluster).size(), subscribeNum); - } - - @Test - public void unsubscribeRdsTest() { - EdsEndpointManager manager = new EdsEndpointManager(); - String domain = "testApp"; - EdsEndpointListener listener = new EdsEndpointListener() { - @Override - public void onEndPointChange(String cluster, Set endpoints) {} - }; - manager.subscribeEds(domain, listener); - assertNotNull(EdsEndpointManager.getEdsListeners().get(domain)); - assertEquals(EdsEndpointManager.getEndpointListeners().get(domain).size(), 1); - - manager.unSubscribeEds(domain, listener); - assertNull(EdsEndpointManager.getEdsListeners().get(domain)); - assertNull(EdsEndpointManager.getEndpointListeners().get(domain)); - } - - @Test - public void notifyRuleChangeTest() { - - Map> cacheData = new HashMap<>(); - String domain = "testApp"; - Set endpoints = new HashSet<>(); - Endpoint endpoint = new Endpoint(); - endpoints.add(endpoint); - - EdsEndpointListener listener = new EdsEndpointListener() { - @Override - public void onEndPointChange(String cluster, Set endpoints) { - cacheData.put(cluster, endpoints); - } - }; - - EdsEndpointManager manager = new EdsEndpointManager(); - manager.subscribeEds(domain, listener); - manager.notifyEndpointChange(domain, endpoints); - assertEquals(cacheData.get(domain), endpoints); - - Map> cacheData2 = new HashMap<>(); - EdsEndpointListener listener2 = new EdsEndpointListener() { - @Override - public void onEndPointChange(String cluster, Set endpoints) { - cacheData2.put(cluster, endpoints); - } - }; - manager.subscribeEds(domain, listener2); - assertEquals(cacheData2.get(domain), endpoints); - // clear - manager.notifyEndpointChange(domain, new HashSet<>()); - assertEquals(cacheData.get(domain).size(), 0); - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManagerTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManagerTest.java deleted file mode 100644 index eaef9cb320a..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsRouteRuleManagerTest.java +++ /dev/null @@ -1,126 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.rpc.cluster.router.xds.rule.HTTPRouteDestination; -import org.apache.dubbo.rpc.cluster.router.xds.rule.HttpRequestMatch; -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class RdsRouteRuleManagerTest { - - @BeforeEach - public void before() { - RdsRouteRuleManager.getRuleListeners().clear(); - RdsRouteRuleManager.getRouteDataCache().clear(); - RdsRouteRuleManager.getRdsListeners().clear(); - } - - @Test - public void subscribeRdsTest() { - RdsRouteRuleManager manager = new RdsRouteRuleManager(); - String domain = "testApp"; - int subscribeNum = 3; - for (int i = 0; i < subscribeNum; i++) { - manager.subscribeRds(domain, new XdsRouteRuleListener() { - @Override - public void onRuleChange(String appName, List xdsRouteRules) {} - - @Override - public void clearRule(String appName) {} - }); - } - assertNotNull(RdsRouteRuleManager.getRdsListeners().get(domain)); - assertEquals(RdsRouteRuleManager.getRuleListeners().get(domain).size(), subscribeNum); - } - - @Test - public void unsubscribeRdsTest() { - RdsRouteRuleManager manager = new RdsRouteRuleManager(); - String domain = "testApp"; - XdsRouteRuleListener listener = new XdsRouteRuleListener() { - @Override - public void onRuleChange(String appName, List xdsRouteRules) {} - - @Override - public void clearRule(String appName) {} - }; - manager.subscribeRds(domain, listener); - assertNotNull(RdsRouteRuleManager.getRdsListeners().get(domain)); - assertEquals(RdsRouteRuleManager.getRuleListeners().get(domain).size(), 1); - - manager.unSubscribeRds(domain, listener); - assertNull(RdsRouteRuleManager.getRdsListeners().get(domain)); - assertNull(RdsRouteRuleManager.getRuleListeners().get(domain)); - } - - @Test - public void notifyRuleChangeTest() { - - Map> cacheData = new HashMap<>(); - String domain = "testApp"; - List xdsRouteRules = new ArrayList<>(); - XdsRouteRule rule = new XdsRouteRule(new HttpRequestMatch(null, null), new HTTPRouteDestination()); - xdsRouteRules.add(rule); - - XdsRouteRuleListener listener = new XdsRouteRuleListener() { - @Override - public void onRuleChange(String appName, List xdsRouteRules) { - cacheData.put(appName, xdsRouteRules); - } - - @Override - public void clearRule(String appName) { - cacheData.remove(appName); - } - }; - - RdsRouteRuleManager manager = new RdsRouteRuleManager(); - manager.subscribeRds(domain, listener); - manager.notifyRuleChange(domain, xdsRouteRules); - assertEquals(cacheData.get(domain), xdsRouteRules); - - Map> cacheData2 = new HashMap<>(); - XdsRouteRuleListener listener2 = new XdsRouteRuleListener() { - @Override - public void onRuleChange(String appName, List xdsRouteRules) { - cacheData2.put(appName, xdsRouteRules); - } - - @Override - public void clearRule(String appName) { - cacheData2.remove(appName); - } - }; - manager.subscribeRds(domain, listener2); - assertEquals(cacheData2.get(domain), xdsRouteRules); - // clear - manager.notifyRuleChange(domain, new ArrayList<>()); - assertNull(cacheData.get(domain)); - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListenerTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListenerTest.java deleted file mode 100644 index d7985366a6e..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/RdsVirtualHostListenerTest.java +++ /dev/null @@ -1,258 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.rpc.cluster.router.xds.rule.ClusterWeight; -import org.apache.dubbo.rpc.cluster.router.xds.rule.XdsRouteRule; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.protobuf.BoolValue; -import com.google.protobuf.UInt32Value; -import io.envoyproxy.envoy.config.route.v3.HeaderMatcher; -import io.envoyproxy.envoy.config.route.v3.Route; -import io.envoyproxy.envoy.config.route.v3.RouteAction; -import io.envoyproxy.envoy.config.route.v3.RouteMatch; -import io.envoyproxy.envoy.config.route.v3.VirtualHost; -import io.envoyproxy.envoy.config.route.v3.WeightedCluster; -import io.envoyproxy.envoy.type.matcher.v3.RegexMatcher; -import io.envoyproxy.envoy.type.v3.Int64Range; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class RdsVirtualHostListenerTest { - - private final String domain = "testApp"; - - private final Map> dataCache = new HashMap<>(); - - private final XdsRouteRuleListener listener = new XdsRouteRuleListener() { - @Override - public void onRuleChange(String appName, List xdsRouteRules) { - dataCache.put(appName, xdsRouteRules); - } - - @Override - public void clearRule(String appName) { - dataCache.remove(appName); - } - }; - - private final RdsRouteRuleManager manager = new RdsRouteRuleManager(); - - private final RdsVirtualHostListener rdsVirtualHostListener = new RdsVirtualHostListener("testApp", manager); - - @BeforeEach - public void init() { - dataCache.clear(); - manager.subscribeRds(domain, listener); - } - - @Test - public void parsePathPathMatcherTest() { - String path = "/test/name"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder() - .setPath(path) - .setCaseSensitive( - BoolValue.newBuilder().setValue(true).build()) - .build()) - .setRoute(RouteAction.newBuilder() - .setCluster("cluster-test") - .build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - assertEquals(rules.get(0).getMatch().getPathMatcher().getPath(), path); - assertTrue(rules.get(0).getMatch().getPathMatcher().isCaseSensitive()); - } - - @Test - public void parsePrefixPathMatcherTest() { - String prefix = "/test"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPrefix(prefix).build()) - .setRoute(RouteAction.newBuilder() - .setCluster("cluster-test") - .build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - assertEquals(rules.get(0).getMatch().getPathMatcher().getPrefix(), prefix); - } - - @Test - public void parseRegexPathMatcherTest() { - String regex = "/test/.*"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder() - .setSafeRegex(RegexMatcher.newBuilder() - .setRegex(regex) - .build()) - .build()) - .setRoute(RouteAction.newBuilder() - .setCluster("cluster-test") - .build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - assertEquals(rules.get(0).getMatch().getPathMatcher().getRegex(), regex); - } - - @Test - public void parseHeadMatcherTest() { - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder() - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-exactValue") - .setExactMatch("exactValue") - .setInvertMatch(true) - .build()) - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-regex") - .setSafeRegexMatch(RegexMatcher.newBuilder() - .setRegex("regex") - .build()) - .build()) - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-range") - .setRangeMatch(Int64Range.newBuilder() - .setStart(1) - .setEnd(100) - .build()) - .build()) - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-present") - .setPresentMatch(true) - .build()) - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-prefix") - .setPrefixMatch("prefix") - .build()) - .addHeaders(HeaderMatcher.newBuilder() - .setName("head-suffix") - .setSuffixMatch("suffix") - .build()) - .build()) - .setRoute(RouteAction.newBuilder() - .setCluster("cluster-test") - .build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - List headerMatcherList = - rules.get(0).getMatch().getHeaderMatcherList(); - for (org.apache.dubbo.rpc.cluster.router.xds.rule.HeaderMatcher matcher : headerMatcherList) { - if (matcher.getName().equals("head-exactValue")) { - assertEquals(matcher.getExactValue(), "exactValue"); - } else if (matcher.getName().equals("head-regex")) { - assertEquals(matcher.getRegex(), "regex"); - } else if (matcher.getName().equals("head-range")) { - assertEquals(matcher.getRange().getStart(), 1); - assertEquals(matcher.getRange().getEnd(), 100); - } else if (matcher.getName().equals("head-present")) { - assertTrue(matcher.getPresent()); - } else if (matcher.getName().equals("head-prefix")) { - assertEquals(matcher.getPrefix(), "prefix"); - } else if (matcher.getName().equals("head-suffix")) { - assertEquals(matcher.getSuffix(), "suffix"); - } - } - } - - @Test - public void parseRouteClusterTest() { - String cluster = "cluster-test"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPrefix("/test").build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster).build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - assertEquals(rules.get(0).getRoute().getCluster(), cluster); - } - - @Test - public void parseRouteWeightClusterTest() { - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(domain) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPrefix("/test").build()) - .setRoute(RouteAction.newBuilder() - .setWeightedClusters(WeightedCluster.newBuilder() - .addClusters(WeightedCluster.ClusterWeight.newBuilder() - .setName("cluster-test1") - .setWeight(UInt32Value.newBuilder() - .setValue(40) - .build()) - .build()) - .addClusters(WeightedCluster.ClusterWeight.newBuilder() - .setName("cluster-test2") - .setWeight(UInt32Value.newBuilder() - .setValue(60) - .build()) - .build()) - .build()) - .build()) - .build()) - .build(); - rdsVirtualHostListener.parseVirtualHost(virtualHost); - List rules = dataCache.get(domain); - assertNotNull(rules); - List weightedClusters = rules.get(0).getRoute().getWeightedClusters(); - assertEquals(weightedClusters.size(), 2); - for (ClusterWeight weightedCluster : weightedClusters) { - if (weightedCluster.getName().equals("cluster-test1")) { - assertEquals(weightedCluster.getWeight(), 40); - } else if (weightedCluster.getName().equals("cluster-test2")) { - assertEquals(weightedCluster.getWeight(), 60); - } - } - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteTest.java deleted file mode 100644 index 11c7e3b5841..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/XdsRouteTest.java +++ /dev/null @@ -1,376 +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 org.apache.dubbo.rpc.cluster.router.xds; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.Holder; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.registry.xds.util.protocol.message.Endpoint; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.cluster.router.mesh.util.TracingContextProvider; -import org.apache.dubbo.rpc.cluster.router.state.BitList; -import org.apache.dubbo.rpc.cluster.router.xds.rule.DestinationSubset; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import com.google.protobuf.UInt32Value; -import io.envoyproxy.envoy.config.route.v3.HeaderMatcher; -import io.envoyproxy.envoy.config.route.v3.Route; -import io.envoyproxy.envoy.config.route.v3.RouteAction; -import io.envoyproxy.envoy.config.route.v3.RouteMatch; -import io.envoyproxy.envoy.config.route.v3.VirtualHost; -import io.envoyproxy.envoy.config.route.v3.WeightedCluster; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class XdsRouteTest { - - private EdsEndpointManager edsEndpointManager; - - private RdsRouteRuleManager rdsRouteRuleManager; - private Set tracingContextProviders; - private URL url; - - @BeforeEach - public void setup() { - edsEndpointManager = Mockito.spy(EdsEndpointManager.class); - rdsRouteRuleManager = Mockito.spy(RdsRouteRuleManager.class); - tracingContextProviders = new HashSet<>(); - - url = URL.valueOf("test://localhost/DemoInterface"); - } - - private Invoker createInvoker(String app) { - URL url = URL.valueOf( - "dubbo://localhost/DemoInterface?" + (StringUtils.isEmpty(app) ? "" : "remote.application=" + app)); - Invoker invoker = Mockito.mock(Invoker.class); - when(invoker.getUrl()).thenReturn(url); - return invoker; - } - - private Invoker createInvoker(String app, String address) { - URL url = URL.valueOf("dubbo://" + address + "/DemoInterface?" - + (StringUtils.isEmpty(app) ? "" : "remote.application=" + app)); - Invoker invoker = Mockito.mock(Invoker.class); - when(invoker.getUrl()).thenReturn(url); - return invoker; - } - - @Test - public void testNotifyInvoker() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - xdsRouter.notify(null); - assertEquals(0, xdsRouter.getSubscribeApplications().size()); - - BitList> invokers = new BitList<>(Arrays.asList(createInvoker(""), createInvoker("app1"))); - - xdsRouter.notify(invokers); - - assertEquals(1, xdsRouter.getSubscribeApplications().size()); - assertTrue(xdsRouter.getSubscribeApplications().contains("app1")); - assertEquals(invokers, xdsRouter.getInvokerList()); - - verify(rdsRouteRuleManager, times(1)).subscribeRds("app1", xdsRouter); - - invokers = new BitList<>(Arrays.asList(createInvoker("app2"))); - xdsRouter.notify(invokers); - verify(rdsRouteRuleManager, times(1)).subscribeRds("app2", xdsRouter); - verify(rdsRouteRuleManager, times(1)).unSubscribeRds("app1", xdsRouter); - assertEquals(invokers, xdsRouter.getInvokerList()); - - xdsRouter.stop(); - verify(rdsRouteRuleManager, times(1)).unSubscribeRds("app2", xdsRouter); - } - - @Test - public void testRuleChange() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - String cluster1 = "cluster-test1"; - String cluster2 = "cluster-test2"; - BitList> invokers = new BitList<>(Arrays.asList(createInvoker(appName))); - xdsRouter.notify(invokers); - String path = "/DemoInterface/call"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPath(path).build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster1).build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - assertEquals(xdsRouter.getXdsRouteRuleMap().get(appName).size(), 1); - verify(edsEndpointManager, times(1)).subscribeEds(cluster1, xdsRouter); - - VirtualHost virtualHost2 = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPath(path).build()) - .setRoute(RouteAction.newBuilder() - .setCluster("cluster-test2") - .build()) - .build()) - .build(); - hostListener.parseVirtualHost(virtualHost2); - assertEquals(xdsRouter.getXdsRouteRuleMap().get(appName).size(), 1); - verify(edsEndpointManager, times(1)).subscribeEds(cluster2, xdsRouter); - verify(edsEndpointManager, times(1)).unSubscribeEds(cluster1, xdsRouter); - } - - @Test - public void testEndpointChange() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - String cluster1 = "cluster-test1"; - BitList> invokers = new BitList<>( - Arrays.asList(createInvoker(appName, "1.1.1.1:20880"), createInvoker(appName, "2.2.2.2:20880"))); - xdsRouter.notify(invokers); - String path = "/DemoInterface/call"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPath(path).build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster1).build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - assertEquals(xdsRouter.getXdsRouteRuleMap().get(appName).size(), 1); - verify(edsEndpointManager, times(1)).subscribeEds(cluster1, xdsRouter); - - Set endpoints = new HashSet<>(); - Endpoint endpoint1 = new Endpoint(); - endpoint1.setAddress("1.1.1.1"); - endpoint1.setPortValue(20880); - Endpoint endpoint2 = new Endpoint(); - endpoint2.setAddress("2.2.2.2"); - endpoint2.setPortValue(20880); - endpoints.add(endpoint1); - endpoints.add(endpoint2); - edsEndpointManager.notifyEndpointChange(cluster1, endpoints); - - DestinationSubset objectDestinationSubset = - xdsRouter.getDestinationSubsetMap().get(cluster1); - assertEquals(invokers, objectDestinationSubset.getInvokers()); - } - - @Test - public void testRouteNotMatch() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - BitList> invokers = new BitList<>( - Arrays.asList(createInvoker(appName, "1.1.1.1:20880"), createInvoker(appName, "2.2.2.2:20880"))); - assertEquals(invokers, xdsRouter.route(invokers.clone(), null, null, false, null)); - Holder message = new Holder<>(); - xdsRouter.doRoute(invokers.clone(), null, null, true, null, message); - assertEquals("Directly Return. Reason: xds route rule is empty.", message.get()); - } - - @Test - public void testRoutePathMatch() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - String cluster1 = "cluster-test1"; - Invoker invoker1 = createInvoker(appName, "1.1.1.1:20880"); - BitList> invokers = - new BitList<>(Arrays.asList(invoker1, createInvoker(appName, "2.2.2.2:20880"))); - xdsRouter.notify(invokers); - String path = "/DemoInterface/call"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPath(path).build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster1).build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - Invocation invocation = Mockito.mock(Invocation.class); - Invoker invoker = Mockito.mock(Invoker.class); - URL url1 = Mockito.mock(URL.class); - when(invoker.getUrl()).thenReturn(url1); - when(url1.getPath()).thenReturn("DemoInterface"); - when(invocation.getInvoker()).thenReturn(invoker); - when(invocation.getMethodName()).thenReturn("call"); - - Set endpoints = new HashSet<>(); - Endpoint endpoint1 = new Endpoint(); - endpoint1.setAddress("1.1.1.1"); - endpoint1.setPortValue(20880); - endpoints.add(endpoint1); - edsEndpointManager.notifyEndpointChange(cluster1, endpoints); - BitList> routes = xdsRouter.route(invokers.clone(), null, invocation, false, null); - assertEquals(1, routes.size()); - assertEquals(invoker1, routes.get(0)); - } - - @Test - public void testRouteHeadMatch() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - String cluster1 = "cluster-test1"; - Invoker invoker1 = createInvoker(appName, "1.1.1.1:20880"); - BitList> invokers = - new BitList<>(Arrays.asList(invoker1, createInvoker(appName, "2.2.2.2:20880"))); - xdsRouter.notify(invokers); - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder() - .addHeaders(HeaderMatcher.newBuilder() - .setName("userId") - .setExactMatch("123") - .build()) - .build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster1).build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - Invocation invocation = Mockito.mock(Invocation.class); - when(invocation.getAttachment("userId")).thenReturn("123"); - Set endpoints = new HashSet<>(); - Endpoint endpoint1 = new Endpoint(); - endpoint1.setAddress("1.1.1.1"); - endpoint1.setPortValue(20880); - endpoints.add(endpoint1); - edsEndpointManager.notifyEndpointChange(cluster1, endpoints); - BitList> routes = xdsRouter.route(invokers.clone(), null, invocation, false, null); - assertEquals(1, routes.size()); - assertEquals(invoker1, routes.get(0)); - } - - @Test - public void testRouteWeightCluster() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName = "app1"; - String cluster1 = "cluster-test1"; - String cluster2 = "cluster-test2"; - Invoker invoker1 = createInvoker(appName, "1.1.1.1:20880"); - BitList> invokers = - new BitList<>(Arrays.asList(invoker1, createInvoker(appName, "2.2.2.2:20880"))); - xdsRouter.notify(invokers); - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder() - .addHeaders(HeaderMatcher.newBuilder() - .setName("userId") - .setExactMatch("123") - .build()) - .build()) - .setRoute(RouteAction.newBuilder() - .setWeightedClusters(WeightedCluster.newBuilder() - .addClusters(WeightedCluster.ClusterWeight.newBuilder() - .setName(cluster1) - .setWeight(UInt32Value.newBuilder() - .setValue(100) - .build()) - .build()) - .addClusters(WeightedCluster.ClusterWeight.newBuilder() - .setName(cluster2) - .setWeight(UInt32Value.newBuilder() - .setValue(0) - .build()) - .build()) - .build()) - .build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - Invocation invocation = Mockito.mock(Invocation.class); - when(invocation.getAttachment("userId")).thenReturn("123"); - Set endpoints = new HashSet<>(); - Endpoint endpoint1 = new Endpoint(); - endpoint1.setAddress("1.1.1.1"); - endpoint1.setPortValue(20880); - endpoints.add(endpoint1); - edsEndpointManager.notifyEndpointChange(cluster1, endpoints); - - endpoints = new HashSet<>(); - Endpoint endpoint2 = new Endpoint(); - endpoint2.setAddress("2.2.2.2"); - endpoint2.setPortValue(20880); - endpoints.add(endpoint2); - edsEndpointManager.notifyEndpointChange(cluster2, endpoints); - - for (int i = 0; i < 10; i++) { - BitList> routes = xdsRouter.route(invokers.clone(), null, invocation, false, null); - assertEquals(1, routes.size()); - assertEquals(invoker1, routes.get(0)); - } - } - - @Test - public void testRouteMultiApp() { - XdsRouter xdsRouter = new XdsRouter<>(url, rdsRouteRuleManager, edsEndpointManager, true); - String appName1 = "app1"; - String appName2 = "app2"; - String cluster1 = "cluster-test1"; - Invoker invoker1 = createInvoker(appName2, "1.1.1.1:20880"); - Invoker invoker2 = createInvoker(appName1, "2.2.2.2:20880"); - BitList> invokers = new BitList<>(Arrays.asList(invoker1, invoker2)); - xdsRouter.notify(invokers); - assertEquals(xdsRouter.getSubscribeApplications().size(), 2); - String path = "/DemoInterface/call"; - VirtualHost virtualHost = VirtualHost.newBuilder() - .addDomains(appName2) - .addRoutes(Route.newBuilder() - .setName("route-test") - .setMatch(RouteMatch.newBuilder().setPath(path).build()) - .setRoute(RouteAction.newBuilder().setCluster(cluster1).build()) - .build()) - .build(); - RdsVirtualHostListener hostListener = new RdsVirtualHostListener(appName2, rdsRouteRuleManager); - hostListener.parseVirtualHost(virtualHost); - Invocation invocation = Mockito.mock(Invocation.class); - Invoker invoker = Mockito.mock(Invoker.class); - URL url1 = Mockito.mock(URL.class); - when(invoker.getUrl()).thenReturn(url1); - when(url1.getPath()).thenReturn("DemoInterface"); - when(invocation.getInvoker()).thenReturn(invoker); - when(invocation.getMethodName()).thenReturn("call"); - - Set endpoints = new HashSet<>(); - Endpoint endpoint1 = new Endpoint(); - endpoint1.setAddress("1.1.1.1"); - endpoint1.setPortValue(20880); - endpoints.add(endpoint1); - edsEndpointManager.notifyEndpointChange(cluster1, endpoints); - BitList> routes = xdsRouter.route(invokers.clone(), null, invocation, false, null); - assertEquals(1, routes.size()); - assertEquals(invoker1, routes.get(0)); - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcherTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcherTest.java deleted file mode 100644 index 597c06e0de8..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/HeaderMatcherTest.java +++ /dev/null @@ -1,89 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class HeaderMatcherTest { - - @Test - public void exactValueMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setName("testHead"); - String value = "testValue"; - headMatcher.setExactValue(value); - assertTrue(headMatcher.match(value)); - } - - @Test - public void regexMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setRegex("test.*"); - String value = "testValue"; - headMatcher.setExactValue(value); - assertTrue(headMatcher.match(value)); - } - - @Test - public void rangMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - LongRangeMatch range = new LongRangeMatch(); - range.setStart(100); - range.setEnd(500); - headMatcher.setRange(range); - assertTrue(headMatcher.match("300")); - } - - @Test - public void presentMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setName("testHead"); - headMatcher.setPresent(true); - assertTrue(headMatcher.match("value")); - headMatcher.setPresent(false); - assertTrue(headMatcher.match(null)); - } - - @Test - public void prefixMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setName("testHead"); - headMatcher.setPrefix("test"); - assertTrue(headMatcher.match("testValue")); - } - - @Test - public void suffixMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setName("testHead"); - headMatcher.setSuffix("Value"); - assertTrue(headMatcher.match("testValue")); - } - - @Test - public void invertedMatcherTest() { - HeaderMatcher headMatcher = new HeaderMatcher(); - headMatcher.setName("testHead"); - String value = "testValue"; - headMatcher.setExactValue(value); - headMatcher.setInverted(true); - assertFalse(headMatcher.match("testValue")); - } -} diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcherTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcherTest.java deleted file mode 100644 index ce8e82b50b7..00000000000 --- a/dubbo-xds/src/test/java/org/apache/dubbo/rpc/cluster/router/xds/rule/PathMatcherTest.java +++ /dev/null @@ -1,57 +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 org.apache.dubbo.rpc.cluster.router.xds.rule; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class PathMatcherTest { - - @Test - public void pathMatcherTest() { - PathMatcher pathMatcher = new PathMatcher(); - String path = "/testService/test"; - pathMatcher.setPath(path); - assertTrue(pathMatcher.isMatch(path)); - assertTrue(pathMatcher.isMatch(path.toUpperCase())); - pathMatcher.setCaseSensitive(true); - assertFalse(pathMatcher.isMatch(path.toUpperCase())); - } - - @Test - public void prefixMatcherTest() { - PathMatcher pathMatcher = new PathMatcher(); - String prefix = "/test"; - String path = "/testService/test"; - pathMatcher.setPrefix(prefix); - assertTrue(pathMatcher.isMatch(path)); - assertTrue(pathMatcher.isMatch(path.toUpperCase())); - pathMatcher.setCaseSensitive(true); - assertFalse(pathMatcher.isMatch(path.toUpperCase())); - } - - @Test - public void regexMatcherTest() { - PathMatcher pathMatcher = new PathMatcher(); - String regex = "/testService/.*"; - String path = "/testService/test"; - pathMatcher.setRegex(regex); - assertTrue(pathMatcher.isMatch(path)); - } -} diff --git a/pom.xml b/pom.xml index dc6e5708ea0..d04b93350ac 100644 --- a/pom.xml +++ b/pom.xml @@ -100,8 +100,6 @@ dubbo-spring-boot dubbo-native dubbo-test - dubbo-kubernetes - dubbo-xds dubbo-native-plugin dubbo-maven-plugin