diff --git a/.github/codecov.yml b/.github/codecov.yml index e476062371..dc1bf1dc47 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -5,13 +5,20 @@ comment: coverage: # https://docs.codecov.com/docs/codecovyml-reference#coverage precision: 5 - range: - - 70.0 - - 75.0 + range: "80...100" status: project: default: branches: - ^master$ - target: 70.0 # the minimum coverage ratio that the commit must meet to be considered a success. - threshold: 1% # allow the coverage to drop by X%, and posting a success status. \ No newline at end of file + target: 80.0 + threshold: 1% + ignore: + - "**/test/**" + - "**/*Test.java" + - "**/*AuthCenter.java" + - "**/*QappPackage.java" + - "**/*TRPCProtocol.java" +parsers: + jacoco: + partials_as_hits: true \ No newline at end of file diff --git a/trpc-container/trpc-container-default/src/main/java/com/tencent/trpc/container/config/system/Environment.java b/trpc-container/trpc-container-default/src/main/java/com/tencent/trpc/container/config/system/Environment.java index fc2ab0e3f1..f83fa1a808 100644 --- a/trpc-container/trpc-container-default/src/main/java/com/tencent/trpc/container/config/system/Environment.java +++ b/trpc-container/trpc-container-default/src/main/java/com/tencent/trpc/container/config/system/Environment.java @@ -93,7 +93,6 @@ public Map parseMap(String configPath) { this.localConfigMap = this.applicationConfigParser.parseMap(configPath); this.overrideConfig(); if (override) { - logger.debug("use part of system config instead of local yaml config."); return this.propertySourceParser.parseFlattableMap(this.localFlattableConfigMap); } return this.localConfigMap; diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/cluster/RpcClusterClientManager.java b/trpc-core/src/main/java/com/tencent/trpc/core/cluster/RpcClusterClientManager.java index 8fbdbf2f4c..320b8b0f57 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/cluster/RpcClusterClientManager.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/cluster/RpcClusterClientManager.java @@ -71,7 +71,10 @@ public static void shutdownBackendConfig(BackendConfig backendConfig) { .ifPresent(proxyMap -> proxyMap.forEach((k, v) -> { try { v.close(); - logger.debug("Shutdown client:{} backendConfig:{} success", k, backendConfig.toSimpleString()); + if (logger.isDebugEnabled()) { + logger.debug("Shutdown client:{} backendConfig:{} success", k, + backendConfig.toSimpleString()); + } } catch (Exception ex) { logger.error("Shutdown client:{} backendConfig:{},exception", k, backendConfig.toSimpleString(), ex); @@ -107,8 +110,10 @@ private static ScheduledFuture startRpcClientCleaner() { public static void scanUnusedClient() { Map> unusedClientMap = Maps.newHashMap(); CLUSTER_MAP.forEach((bConfig, clusterMap) -> { - logger.debug("RpcClusterClient scheduler report clusterName={}, naming={}, num of client is {}", - bConfig.getName(), bConfig.getNamingOptions().getServiceNaming(), clusterMap.keySet().size()); + if (logger.isDebugEnabled()) { + logger.debug("RpcClusterClient scheduler report clusterName={}, naming={}, num of client is {}", + bConfig.getName(), bConfig.getNamingOptions().getServiceNaming(), clusterMap.keySet().size()); + } clusterMap.forEach((clientKey, clientValue) -> { try { if (isIdleTimeout(bConfig, clientValue)) { diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/cluster/def/DefClusterInvoker.java b/trpc-core/src/main/java/com/tencent/trpc/core/cluster/def/DefClusterInvoker.java index f4c6145587..653559b98e 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/cluster/def/DefClusterInvoker.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/cluster/def/DefClusterInvoker.java @@ -210,8 +210,6 @@ private void fillCallInfo(Request request, ServiceInstance serviceInstance) { Constants.CONTAINER_NAME)); request.getMeta().getCallInfo().setCalleeSetName(serviceInstance.getParameter( Constants.SET_DIVISION)); - logger.debug("[invoke] container:{},set:{}", serviceInstance.getParameter( - Constants.CONTAINER_NAME), serviceInstance.getParameter(Constants.SET_DIVISION)); } } diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/common/LifecycleBase.java b/trpc-core/src/main/java/com/tencent/trpc/core/common/LifecycleBase.java index 21f275cd46..acc7b7d51d 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/common/LifecycleBase.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/common/LifecycleBase.java @@ -306,7 +306,9 @@ private synchronized void setStateInternal(LifecycleState state) { } private synchronized void setStateInternal(LifecycleState state, Throwable ex) { - logger.debug(">>>Lifecycle state transfer,{obj={}, state({} -> {})}", this, getState(), state); + if (logger.isDebugEnabled()) { + logger.debug(">>>Lifecycle state transfer,{obj={}, state({} -> {})}", this, getState(), state); + } this.state = state; fireLifecycleEvent(state, ex); } diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/common/config/BackendConfig.java b/trpc-core/src/main/java/com/tencent/trpc/core/common/config/BackendConfig.java index 07cb9accb0..e350af6b0c 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/common/config/BackendConfig.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/common/config/BackendConfig.java @@ -334,7 +334,9 @@ public synchronized void init() { validateInterceptor(); namingServiceId = toNamingServiceId(); simpleString = "BackendConfig[name=" + name + ", naming=" + namingOptions.getServiceNaming() + "]"; - logger.debug("ConsumerConfig initialized:{}", toString()); + if (logger.isDebugEnabled()) { + logger.debug("ConsumerConfig initialized:{}", toString()); + } SelectorManager.getManager().validate(namingOptions.getSelectorId()); initRpcClusterClient(); inited = true; diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/extension/ExtensionClass.java b/trpc-core/src/main/java/com/tencent/trpc/core/extension/ExtensionClass.java index b0525e080c..0260ec1199 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/extension/ExtensionClass.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/extension/ExtensionClass.java @@ -90,8 +90,10 @@ private T createInstance() { T t = clazz.newInstance(); injectExtension(t, pluginConfig); initExtension(t); - logger.debug("Create plugin instance (name={}, type={}), config={}) success", name, - extensionType, ExtensionLoader.getPluginConfigMap(extensionType)); + if (logger.isDebugEnabled()) { + logger.debug("Create plugin instance (name={}, type={}), config={}) success", name, + extensionType, ExtensionLoader.getPluginConfigMap(extensionType)); + } return t; } catch (Exception e) { throw new TRpcExtensionException( diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/filter/ProviderFilterInvoker.java b/trpc-core/src/main/java/com/tencent/trpc/core/filter/ProviderFilterInvoker.java index 19d1f283b8..391f162bba 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/filter/ProviderFilterInvoker.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/filter/ProviderFilterInvoker.java @@ -1,7 +1,7 @@ /* * Tencent is pleased to support the open source community by making tRPC available. * - * Copyright (C) 2023 Tencent. + * Copyright (C) 2023 Tencent. * All rights reserved. * * If you have downloaded a copy of the tRPC source code from Tencent, @@ -49,7 +49,6 @@ private static ProviderInvoker buildProviderChain(boolean disableDefaultF : Stream.of(new ProviderInvokerHeadFilter(), new ProviderInvokerTailFilter()); List filters = Stream.concat(filterNames.stream().map(FilterManager::get), defaultFilters) .sorted(Comparator.comparing(Filter::getOrder)).collect(Collectors.toList()); - logger.debug("===Build invoke provider filter size: {}", filters.size()); for (int i = filters.size() - 1; i >= 0; i--) { final Filter filter = filters.get(i); @@ -68,12 +67,17 @@ public Class getInterface() { @Override public CompletionStage invoke(Request request) { RpcInvocation inv = request.getInvocation(); - logger.debug(">>>Before Invoke provider filter(service={}, rpcServiceName={}, rpcMehthodName={})", - filter.getClass(), inv.getRpcServiceName(), inv.getRpcMethodName()); + if (logger.isDebugEnabled()) { + logger.debug(">>>Before Invoke provider filter(service={}, rpcServiceName={}, " + + "rpcMehthodName={})", + filter.getClass(), inv.getRpcServiceName(), inv.getRpcMethodName()); + } CompletionStage f = filter.filter(before, request); - logger.debug("<< filter(Invoker invoker, Request request) Span span = null; try { span = buildSpan(invoker, request, context, meta, tracer, parentSpan); - logger.debug("before tjg TraceClientFilter reporting, span: {}", span); + if (logger.isDebugEnabled()) { + logger.debug("before tjg TraceClientFilter reporting, span: {}", span); + } } catch (Exception e) { logger.error("create trace client span error: ", e); } @@ -59,7 +61,9 @@ public CompletionStage filter(Invoker invoker, Request request) updateUpstreamSpanFlag(parentSpan, tempSpan); finish(tempSpan, request, r, t); } - logger.debug("after tjg TraceClientFilter reporting, span: {}", tempSpan); + if (logger.isDebugEnabled()) { + logger.debug("after tjg TraceClientFilter reporting, span: {}", tempSpan); + } } catch (Exception e) { logger.error("finish span error: ", e); } diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerFilter.java b/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerFilter.java index 911d34fa5c..3c79478f15 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerFilter.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerFilter.java @@ -91,7 +91,9 @@ public abstract Span start(SpanBuilder spanBuilder, RpcContext context, Invoker< */ public Tracer getTracer(RpcContext context, RequestMeta meta) throws TRpcException { try { - logger.debug("c context:{},meta:{}", context, meta); + if (logger.isDebugEnabled()) { + logger.debug("c context:{},meta:{}", context, meta); + } Tracer tracer = RpcContextUtils.getTracer(context); if (tracer != null) { return tracer; @@ -114,7 +116,9 @@ public Tracer getTracer(RpcContext context, RequestMeta meta) throws TRpcExcepti logger.error("tracer is null,this self server name is null"); } } - logger.debug("getTracer tracer:{}}", tracer); + if (logger.isDebugEnabled()) { + logger.debug("getTracer tracer:{}}", tracer); + } return tracer; } catch (Exception e) { logger.error("getTracer error", e); @@ -133,8 +137,10 @@ public Tracer getTracer(RpcContext context, RequestMeta meta) throws TRpcExcepti public SpanBuilder createSpanBuilder(Tracer tracer, SpanContext parentSpanContext, RequestMeta meta) { try { - logger.debug("createSpanBuilder tracer:{},parentSpanContext:{},meta:{}", tracer, - parentSpanContext, meta); + if (logger.isDebugEnabled()) { + logger.debug("createSpanBuilder tracer:{},parentSpanContext:{},meta:{}", tracer, + parentSpanContext, meta); + } if (tracer == null) { return null; } @@ -164,7 +170,9 @@ public SpanBuilder createSpanBuilder(Tracer tracer, SpanContext parentSpanContex */ public void updateSpanErrorFlag(Response response, Throwable throwable, Span span) { try { - logger.debug("updateSpanErrorFlag response:{},throwable:{},span:{}", response, throwable, span); + if (logger.isDebugEnabled()) { + logger.debug("updateSpanErrorFlag response:{},throwable:{},span:{}", response, throwable, span); + } if (span == null) { return; } diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerServerFilter.java b/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerServerFilter.java index 0a693f9220..5f33019d83 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerServerFilter.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/trace/TracerServerFilter.java @@ -54,7 +54,9 @@ public CompletionStage filter(Invoker invoker, Request request) RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, span); } } - logger.debug("before tjg TraceServerFilter reporting,span: {}", span); + if (logger.isDebugEnabled()) { + logger.debug("before tjg TraceServerFilter reporting,span: {}", span); + } } catch (Exception e) { logger.error("create trace server span error", e); } @@ -74,7 +76,9 @@ public CompletionStage filter(Invoker invoker, Request request) } finish(tempSpan, request, r, t); } - logger.debug("after tjg TraceClientFilter reporting,span:{}", tempSpan); + if (logger.isDebugEnabled()) { + logger.debug("after tjg TraceClientFilter reporting,span:{}", tempSpan); + } } catch (Exception e) { logger.error("finish span error", e); } diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/transport/AbstractClientTransport.java b/trpc-core/src/main/java/com/tencent/trpc/core/transport/AbstractClientTransport.java index 31638c552e..3c37a455dc 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/transport/AbstractClientTransport.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/transport/AbstractClientTransport.java @@ -231,7 +231,6 @@ protected CompletionStage createChannel() throws TransportException { } else { logger.debug("Client transport(remote addr={}, network={}) create connection success", rAddr, config.getNetwork()); - } // to prevent connection leakage, do one more check: when the connection is successfully established, if // it is found to be closed, close the established connection directly diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapter.java b/trpc-core/src/main/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapter.java index c900b24e3b..9272c4327b 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapter.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapter.java @@ -30,7 +30,9 @@ public void connected(com.tencent.trpc.core.transport.Channel channel) { @Override public void disconnected(com.tencent.trpc.core.transport.Channel channel) { - logger.debug("disconnected channel|{}", channel); + if (logger.isDebugEnabled()) { + logger.debug("disconnected channel|{}", channel); + } disconnectedCnt.incrementAndGet(); } diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/cluster/RpcClusterClientManagerTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/cluster/RpcClusterClientManagerTest.java index dd137a0a8b..7ee1943dae 100644 --- a/trpc-core/src/test/java/com/tencent/trpc/core/cluster/RpcClusterClientManagerTest.java +++ b/trpc-core/src/test/java/com/tencent/trpc/core/cluster/RpcClusterClientManagerTest.java @@ -43,6 +43,59 @@ public void test() throws IllegalArgumentException, IllegalAccessException, NoSu Thread.sleep(10); RpcClusterClientManager.scanUnusedClient(); assertEquals(0, clusterMap.get(backendConfig).size()); + BackendConfig backend = new BackendConfig(); + backend.setNamingUrl("ip://127.0.0.1:8081"); + RpcClusterClientManager.getOrCreateClient(backend, config); + RpcClusterClientManager.shutdownBackendConfig(backend); + } + + @Test + public void testDebugLog() throws Exception { + BackendConfig backendConfig = new BackendConfig(); + backendConfig.setIdleTimeout(100000); + backendConfig.setNamingUrl("ip://127.0.0.1:8082"); + ProtocolConfigTest config = new ProtocolConfigTest(); + RpcClient rpcClient = RpcClusterClientManager.getOrCreateClient(backendConfig, config); + Assert.assertNotNull(rpcClient); + RpcClusterClientManager.scanUnusedClient(); + RpcClusterClientManager.shutdownBackendConfig(backendConfig); + } + + @Test + public void testGetOrCreateClientTwice() throws Exception { + BackendConfig backendConfig = new BackendConfig(); + backendConfig.setIdleTimeout(100000); + backendConfig.setNamingUrl("ip://127.0.0.1:8083"); + ProtocolConfigTest config = new ProtocolConfigTest(); + RpcClient rpcClient1 = RpcClusterClientManager.getOrCreateClient(backendConfig, config); + RpcClient rpcClient2 = RpcClusterClientManager.getOrCreateClient(backendConfig, config); + Assert.assertNotNull(rpcClient1); + Assert.assertNotNull(rpcClient2); + RpcClusterClientManager.shutdownBackendConfig(backendConfig); + } + + @Test + public void testClose() throws Exception { + BackendConfig backendConfig = new BackendConfig(); + backendConfig.setIdleTimeout(100000); + backendConfig.setNamingUrl("ip://127.0.0.1:8084"); + ProtocolConfigTest config = new ProtocolConfigTest(); + RpcClient rpcClient = RpcClusterClientManager.getOrCreateClient(backendConfig, config); + Assert.assertNotNull(rpcClient); + RpcClusterClientManager.close(); + RpcClusterClientManager.reset(); + } + + @Test + public void testShutdownNonExistBackend() { + BackendConfig backendConfig = new BackendConfig(); + backendConfig.setNamingUrl("ip://127.0.0.1:9999"); + RpcClusterClientManager.shutdownBackendConfig(backendConfig); + } + + @Test + public void testScanWithEmptyCluster() { + RpcClusterClientManager.scanUnusedClient(); } private static class ProtocolConfigTest extends ProtocolConfig { diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/cluster/def/DefClusterInvokerTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/cluster/def/DefClusterInvokerTest.java index 93a90b91af..ff258e51cb 100644 --- a/trpc-core/src/test/java/com/tencent/trpc/core/cluster/def/DefClusterInvokerTest.java +++ b/trpc-core/src/test/java/com/tencent/trpc/core/cluster/def/DefClusterInvokerTest.java @@ -33,6 +33,8 @@ import com.tencent.trpc.core.worker.handler.TrpcThreadExceptionHandler; import com.tencent.trpc.core.worker.spi.WorkerPool; import com.tencent.trpc.core.worker.support.thread.ThreadWorkerPool; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -205,4 +207,45 @@ public void testDoInvoke() { } } + @Test + public void testDebugLog() { + DefRequest defRequest = new DefRequest(); + RpcInvocation invocation = new RpcInvocation(); + invocation.setFunc("a"); + defRequest.setInvocation(invocation); + consumerInvokerProxy.invoke(defRequest, new ServiceInstance()); + invocation.setFunc("n"); + consumerInvokerProxy.invoke(defRequest, new ServiceInstance()); + } + + @Test + public void testProxyIsAvailable() { + Assert.assertFalse(consumerInvokerProxy.isAvailable()); + } + + @Test + public void testProxyInvokeWithServiceInstance() { + DefRequest defRequest = new DefRequest(); + RpcInvocation invocation = new RpcInvocation(); + invocation.setFunc("a"); + defRequest.setInvocation(invocation); + Map params = new HashMap<>(); + params.put("container_name", "test-container"); + params.put("set_division", "test-set"); + ServiceInstance instance = new ServiceInstance("127.0.0.1", 12345, params); + consumerInvokerProxy.invoke(defRequest, instance); + } + + @Test + public void testDoInvokeWithCompletedFuture() { + DefRequest defRequest = new DefRequest(); + ServiceInstance instance = new ServiceInstance("127.0.0.1", 12345); + CompletionStage completedInstance = CompletableFuture.completedFuture(instance); + try { + defClusterInvoker.doInvoke(defRequest, completedInstance).toCompletableFuture().join(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/common/LifecycleBaseTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/common/LifecycleBaseTest.java new file mode 100644 index 0000000000..c838cb90c4 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/common/LifecycleBaseTest.java @@ -0,0 +1,16 @@ +package com.tencent.trpc.core.common; + +import org.junit.Test; + +public class LifecycleBaseTest { + + @Test + public void testDebug() { + TestLifecycle testLifecycle = new TestLifecycle(); + testLifecycle.init(); + } + + public class TestLifecycle extends LifecycleBase { + + } +} \ No newline at end of file diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/common/config/BackendConfigTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/common/config/BackendConfigTest.java index 6275573ff2..12d58cd796 100644 --- a/trpc-core/src/test/java/com/tencent/trpc/core/common/config/BackendConfigTest.java +++ b/trpc-core/src/test/java/com/tencent/trpc/core/common/config/BackendConfigTest.java @@ -410,6 +410,23 @@ public void testGenerateProtocolConfig() { assertEquals("tcp", protocolConfig.getNetwork()); } + @Test + public void testDebugLog() { + ExtensionLoader.registerPlugin(new PluginConfig("attalog", Filter.class, RemoteLoggerTest.class)); + ExtensionLoader.registerPlugin(ThreadWorkerPool.newThreadWorkerPoolConfig("thread", 10, Boolean.FALSE)); + BackendConfig config = new BackendConfig(); + config.setNamingUrl("ip://127.0.0.1:9999"); + config.setWorkerPool("thread"); + config.setServiceInterface(GenericClient.class); + config.init(); + try { + assertNotNull(config); + assertTrue(config.isInited()); + } finally { + config.stop(); + } + } + public static final class RemoteLoggerTest extends RemoteLoggerFilter { @Override diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/extension/ExtensionClassTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/extension/ExtensionClassTest.java new file mode 100644 index 0000000000..4131fd1e97 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/extension/ExtensionClassTest.java @@ -0,0 +1,63 @@ +/* + * Tencent is pleased to support the open source community by making tRPC available. + * + * Copyright (C) 2023 Tencent. + * All rights reserved. + * + * If you have downloaded a copy of the tRPC source code from Tencent, + * please note that tRPC source code is licensed under the Apache 2.0 License, + * A copy of the Apache 2.0 License can be found in the LICENSE file. + */ + +package com.tencent.trpc.core.extension; + +import com.tencent.trpc.core.common.config.PluginConfig; +import com.tencent.trpc.core.filter.spi.Filter; +import com.tencent.trpc.core.rpc.Invoker; +import com.tencent.trpc.core.rpc.Request; +import com.tencent.trpc.core.rpc.Response; +import java.util.concurrent.CompletionStage; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +public class ExtensionClassTest { + + @After + public void after() { + ExtensionLoader.destroyAllPlugin(); + } + + @Test + public void testCreateInstance() { + ExtensionLoader.registerPlugin(new PluginConfig("testFilter", Filter.class, TestFilter.class)); + ExtensionClass extensionClass = ExtensionLoader.getExtensionLoader(Filter.class) + .getExtensionClass("testFilter"); + Assert.assertNotNull(extensionClass); + Filter instance = extensionClass.getExtInstance(); + Assert.assertNotNull(instance); + Assert.assertTrue(instance instanceof TestFilter); + } + + @Test + public void testDebugLog() { + ExtensionLoader.registerPlugin(new PluginConfig("testFilter", Filter.class, TestFilter.class)); + ExtensionClass extensionClass = ExtensionLoader.getExtensionLoader(Filter.class) + .getExtensionClass("testFilter"); + Assert.assertNotNull(extensionClass); + // 测试创建实例时的 debug 日志 + Filter instance = extensionClass.getExtInstance(); + Assert.assertNotNull(instance); + // 再次获取实例,应该返回缓存的实例 + Filter instance2 = extensionClass.getExtInstance(); + Assert.assertSame(instance, instance2); + } + + public static class TestFilter implements Filter { + + @Override + public CompletionStage filter(Invoker invoker, Request request) { + return invoker.invoke(request); + } + } +} diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/filter/ProviderFilterInvokerTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/filter/ProviderFilterInvokerTest.java index d55068b43b..c89bf5eb9e 100644 --- a/trpc-core/src/test/java/com/tencent/trpc/core/filter/ProviderFilterInvokerTest.java +++ b/trpc-core/src/test/java/com/tencent/trpc/core/filter/ProviderFilterInvokerTest.java @@ -101,6 +101,19 @@ public void filterOrderedTest() { assertEquals("102,1,", r.getValue()); } + @Test + public void testDebugLog() { + FilterManager.registerPlugin("ProviderInovkrMockFilter", ProviderInovkrMockFilter.class); + ProviderConfig config = createProviderConfig(); + config.setFilters(Lists.newArrayList("ProviderInovkrMockFilter")); + ProtocolConfig protoConfig = createProtoConfig(); + ProviderInvoker buildProviderChain = FilterChain.buildProviderChain(config, + new ProviderInvokerMock(config, protoConfig)); + CompletionStage invoke = buildProviderChain.invoke(createRequest()); + Response r = (Response) (invoke.toCompletableFuture().join()); + Assert.assertNotNull(r); + } + public RpcServerContext createServerContext() { RpcServerContext context = new RpcServerContext(); return context; diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/trace/TraceServerFilterTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TraceServerFilterTest.java index d6c48a5704..6f4451e811 100644 --- a/trpc-core/src/test/java/com/tencent/trpc/core/trace/TraceServerFilterTest.java +++ b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TraceServerFilterTest.java @@ -235,6 +235,26 @@ public void testTRpcExceptionSpan() { filter.filter(invoker, request); } + @Test + public void testDebugLog() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("10.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("10.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(TRpcException.newBizException(10, "")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + private static class TestTraceFactory implements TracerFactory { @Override diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerClientFilterTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerClientFilterTest.java new file mode 100644 index 0000000000..12b1385571 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerClientFilterTest.java @@ -0,0 +1,384 @@ +/* + * Tencent is pleased to support the open source community by making tRPC available. + * + * Copyright (C) 2023 Tencent. + * All rights reserved. + * + * If you have downloaded a copy of the tRPC source code from Tencent, + * please note that tRPC source code is licensed under the Apache 2.0 License, + * A copy of the Apache 2.0 License can be found in the LICENSE file. + */ + +package com.tencent.trpc.core.trace; + +import com.tencent.trpc.core.extension.ExtensionLoader; +import com.tencent.trpc.core.logger.Logger; +import com.tencent.trpc.core.logger.LoggerFactory; +import com.tencent.trpc.core.rpc.Invoker; +import com.tencent.trpc.core.rpc.Request; +import com.tencent.trpc.core.rpc.Response; +import com.tencent.trpc.core.rpc.RpcClientContext; +import com.tencent.trpc.core.rpc.RpcContext; +import com.tencent.trpc.core.rpc.RpcContextValueKeys; +import com.tencent.trpc.core.rpc.RpcInvocation; +import com.tencent.trpc.core.rpc.def.DefRequest; +import com.tencent.trpc.core.rpc.def.DefResponse; +import com.tencent.trpc.core.trace.spi.TracerFactory; +import com.tencent.trpc.core.utils.RpcContextUtils; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.Tracer.SpanBuilder; +import io.opentracing.noop.NoopSpan; +import io.opentracing.noop.NoopTracerFactory; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PowerMockIgnore({"javax.management.*"}) +public class TracerClientFilterTest { + + private TracerClientFilter filter = new TracerClientFilter() { + + private final Logger logger = LoggerFactory.getLogger(TracerClientFilter.class); + + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null || request == null || request.getMeta() == null) { + return null; + } + return spanBuilder.start(); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + if (span == null) { + return; + } + span.finish(); + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + if (logger.isDebugEnabled()) { + logger.debug("inject tracer:{},span:{}", tracer, span); + } + return new HashMap<>(); + } + }; + + @Before + public void before() { + TracerFactoryManager.getManager().registPlugin("mtest", TestTraceFactory.class); + } + + @After + public void after() { + ExtensionLoader.destroyAllPlugin(); + } + + @Test + public void testNormalSpan() { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, NoopSpan.INSTANCE); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testDebugLog() { + RpcClientContext context = new RpcClientContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testException() { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(new RuntimeException("test")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testWithParentSpan() { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, NoopSpan.INSTANCE); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testWithErrorFlag() { + RpcClientContext context = new RpcClientContext(); + Span parentSpan = NoopSpan.INSTANCE; + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, parentSpan); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + Map attachments = new HashMap<>(); + attachments.put(TracerConstants.Keys.TRACE_ERROR_KEY, TracerConstants.Keys.TRACE_ERROR_VALUE); + rsp.setAttachments(attachments); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerClientFilter errorFilter = new TracerClientFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null) { + return null; + } + Span span = spanBuilder.start(); + span.setBaggageItem(TracerConstants.Keys.TRACE_ERROR_KEY, TracerConstants.Keys.TRACE_ERROR_VALUE); + return span; + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + if (span != null) { + span.finish(); + } + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return NoopSpan.INSTANCE.context(); + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + errorFilter.filter(invoker, request); + } + + @Test + public void testNullTracer() { + RpcClientContext context = new RpcClientContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerClientFilter nullTracerFilter = new TracerClientFilter() { + @Override + public String getPluginName() { + return "notexist"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + return null; + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + nullTracerFilter.filter(invoker, request); + } + + @Test + public void testCreateSpanException() { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerClientFilter exceptionFilter = new TracerClientFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + throw new RuntimeException("test exception"); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + exceptionFilter.filter(invoker, request); + } + + @Test + public void testFinishException() { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerClientFilter finishExceptionFilter = new TracerClientFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null) { + return null; + } + return spanBuilder.start(); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + throw new RuntimeException("finish exception"); + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + finishExceptionFilter.filter(invoker, request); + } + + private static class TestTraceFactory implements TracerFactory { + + @Override + public Tracer getTracer(String serverName, Integer port) { + return NoopTracerFactory.create(); + } + } +} diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerFilterTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerFilterTest.java new file mode 100644 index 0000000000..2ffd71d004 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerFilterTest.java @@ -0,0 +1,201 @@ +/* + * Tencent is pleased to support the open source community by making tRPC available. + * + * Copyright (C) 2023 Tencent. + * All rights reserved. + * + * If you have downloaded a copy of the tRPC source code from Tencent, + * please note that tRPC source code is licensed under the Apache 2.0 License, + * A copy of the Apache 2.0 License can be found in the LICENSE file. + */ + +package com.tencent.trpc.core.trace; + +import com.tencent.trpc.core.extension.ExtensionLoader; +import com.tencent.trpc.core.rpc.Invoker; +import com.tencent.trpc.core.rpc.Request; +import com.tencent.trpc.core.rpc.Response; +import com.tencent.trpc.core.rpc.RpcClientContext; +import com.tencent.trpc.core.rpc.RpcContext; +import com.tencent.trpc.core.rpc.RpcContextValueKeys; +import com.tencent.trpc.core.rpc.def.DefRequest; +import com.tencent.trpc.core.rpc.def.DefResponse; +import com.tencent.trpc.core.trace.spi.TracerFactory; +import com.tencent.trpc.core.utils.RpcContextUtils; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.Tracer.SpanBuilder; +import io.opentracing.noop.NoopSpan; +import io.opentracing.noop.NoopTracerFactory; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class TracerFilterTest { + + private TracerFilter filter = new TracerFilter() { + @Override + public String getPluginName() { + return "test"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null) { + return null; + } + return spanBuilder.start(); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + if (span != null) { + span.finish(); + } + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + + @Override + public CompletionStage filter(Invoker invoker, Request request) { + return invoker.invoke(request); + } + }; + + @Before + public void before() { + TracerFactoryManager.getManager().registPlugin("test", TestTraceFactory.class); + } + + @After + public void after() { + ExtensionLoader.destroyAllPlugin(); + } + + @Test + public void testGetTracer() throws Exception { + RpcClientContext context = new RpcClientContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + DefRequest request = new DefRequest(); + request.setContext(context); + Tracer tracer = filter.getTracer(context, request.getMeta()); + Assert.assertNotNull(tracer); + } + + @Test + public void testCreateSpanBuilder() { + Tracer tracer = NoopTracerFactory.create(); + DefRequest request = new DefRequest(); + Tracer.SpanBuilder spanBuilder = filter.createSpanBuilder(tracer, null, request.getMeta()); + Assert.assertNotNull(spanBuilder); + } + + @Test + public void testUpdateSpanErrorFlag() { + DefResponse response = new DefResponse(); + Span span = NoopSpan.INSTANCE; + filter.updateSpanErrorFlag(response, null, span); + filter.updateSpanErrorFlag(response, new RuntimeException("test"), span); + } + + @Test + public void testDebugLog() { + RpcClientContext context = new RpcClientContext(); + DefRequest request = new DefRequest(); + request.setContext(context); + try { + filter.getTracer(context, request.getMeta()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testGetTracerWithNullMeta() throws Exception { + RpcClientContext context = new RpcClientContext(); + Tracer tracer = filter.getTracer(context, null); + Assert.assertNull(tracer); + } + + @Test + public void testCreateSpanBuilderWithParent() { + Tracer tracer = NoopTracerFactory.create(); + SpanContext parentContext = NoopSpan.INSTANCE.context(); + DefRequest request = new DefRequest(); + Tracer.SpanBuilder spanBuilder = filter.createSpanBuilder(tracer, parentContext, request.getMeta()); + Assert.assertNotNull(spanBuilder); + } + + @Test + public void testCreateSpanBuilderWithNullTracer() { + DefRequest request = new DefRequest(); + Tracer.SpanBuilder spanBuilder = filter.createSpanBuilder(null, null, request.getMeta()); + Assert.assertNull(spanBuilder); + } + + @Test + public void testCreateSpanBuilderException() { + Tracer tracer = NoopTracerFactory.create(); + Tracer.SpanBuilder spanBuilder = filter.createSpanBuilder(tracer, null, null); + Assert.assertNull(spanBuilder); + } + + @Test + public void testUpdateSpanErrorFlagWithTRpcException() { + DefResponse response = new DefResponse(); + response.setException(com.tencent.trpc.core.exception.TRpcException.newFrameException(100, "test")); + Span span = NoopSpan.INSTANCE; + filter.updateSpanErrorFlag(response, null, span); + } + + @Test + public void testUpdateSpanErrorFlagWithThrowable() { + DefResponse response = new DefResponse(); + Span span = NoopSpan.INSTANCE; + filter.updateSpanErrorFlag(response, new RuntimeException("test"), span); + } + + @Test + public void testUpdateSpanErrorFlagWithNullSpan() { + DefResponse response = new DefResponse(); + filter.updateSpanErrorFlag(response, new RuntimeException("test"), null); + } + + @Test + public void testUpdateSpanErrorFlagException() { + DefResponse response = new DefResponse(); + response.setException(new RuntimeException("test")); + Span span = NoopSpan.INSTANCE; + filter.updateSpanErrorFlag(response, null, span); + } + + @Test + public void testUpdateSpanErrorFlagWithBothExceptions() { + DefResponse response = new DefResponse(); + response.setException( + com.tencent.trpc.core.exception.TRpcException.newFrameException(200, "response exception")); + Span span = NoopSpan.INSTANCE; + filter.updateSpanErrorFlag(response, new RuntimeException("throwable"), span); + } + + private static class TestTraceFactory implements TracerFactory { + + @Override + public Tracer getTracer(String serverName, Integer port) { + return NoopTracerFactory.create(); + } + } +} diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerServerFilterTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerServerFilterTest.java new file mode 100644 index 0000000000..fce798fe29 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/trace/TracerServerFilterTest.java @@ -0,0 +1,514 @@ +package com.tencent.trpc.core.trace; + +import com.tencent.trpc.core.exception.TRpcException; +import com.tencent.trpc.core.extension.ExtensionLoader; +import com.tencent.trpc.core.logger.Logger; +import com.tencent.trpc.core.logger.LoggerFactory; +import com.tencent.trpc.core.rpc.Invoker; +import com.tencent.trpc.core.rpc.Request; +import com.tencent.trpc.core.rpc.Response; +import com.tencent.trpc.core.rpc.RpcContext; +import com.tencent.trpc.core.rpc.RpcContextValueKeys; +import com.tencent.trpc.core.rpc.RpcInvocation; +import com.tencent.trpc.core.rpc.RpcServerContext; +import com.tencent.trpc.core.rpc.def.DefRequest; +import com.tencent.trpc.core.rpc.def.DefResponse; +import com.tencent.trpc.core.trace.spi.TracerFactory; +import com.tencent.trpc.core.utils.RpcContextUtils; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.Tracer.SpanBuilder; +import io.opentracing.noop.NoopSpan; +import io.opentracing.noop.NoopSpanContext; +import io.opentracing.noop.NoopTracerFactory; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMapAdapter; +import io.opentracing.tag.Tags; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PowerMockIgnore({"javax.management.*"}) +public class TracerServerFilterTest { + + private TracerServerFilter filter = new TracerServerFilter() { + + private final Logger logger = LoggerFactory.getLogger(TracerServerFilter.class); + + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, + RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null || request == null || request.getMeta() == null) { + return null; + } + spanBuilder.withTag(Tags.PEER_SERVICE.getKey(), + request.getMeta().getCallInfo().getCallee()); + return spanBuilder.start(); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + if (span == null) { + return; + } + span.finish(); + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + try { + if (logger.isDebugEnabled()) { + logger.debug("extract tracer:{},attachments:{}", tracer, attachments); + } + if (tracer == null || attachments == null) { + return null; + } + Map attachMap = new HashMap<>(); + Set> setEntries = attachments.entrySet(); + for (Entry entry : setEntries) { + if (entry.getValue() instanceof byte[]) { + attachMap.put(entry.getKey(), new String((byte[]) entry.getValue(), + TracerConstants.DEFAULT_CHARSET)); + } + } + return new SpanContext() { + + @Override + public String toTraceId() { + return ""; + } + + @Override + public String toSpanId() { + return ""; + } + + @Override + public Iterable> baggageItems() { + Map map = new HashMap(); + map.put(TracerConstants.Keys.TRACE_ERROR_KEY, + TracerConstants.Keys.TRACE_ERROR_VALUE); + List> list = new ArrayList>(); + list.add(map.entrySet().iterator().next()); + return list; + } + + @Override + public String toString() { + return NoopSpanContext.class.getSimpleName(); + } + }; + } catch (Exception e) { + logger.error("extract spancontext error", e); + } + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + logger.debug("inject tracer:{},span:{}", tracer, span); + Map attachments = new HashMap<>(); + try { + if (tracer == null || span == null) { + return attachments; + } + Map traceMap = new HashMap<>(); + tracer.inject(span.context(), Format.Builtin.TEXT_MAP, + new TextMapAdapter(traceMap)); + for (Entry entry : traceMap.entrySet()) { + if (entry.getValue() != null) { + attachments.put(entry.getKey(), entry.getValue() + .getBytes(TracerConstants.DEFAULT_CHARSET)); + } + } + } catch (Exception e) { + logger.error("inject spancontext error", e); + } + return attachments; + } + }; + + @Before + public void before() { + TracerFactoryManager.getManager().registPlugin("tjg", TestTraceFactory.class); + } + + @After + public void after() { + ExtensionLoader.destroyAllPlugin(); + } + + @Test + public void testNormalSpan() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, NoopSpan.INSTANCE); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("10.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("10.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testExceptionSpan() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, NoopSpan.INSTANCE); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("10.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("10.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(new IllegalArgumentException("")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testTRpcExceptionSpan() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACE_SPAN, NoopSpan.INSTANCE); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("10.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("10.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(TRpcException.newBizException(10, "")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testDebugLog() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("10.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("10.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(TRpcException.newBizException(10, "")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testNullTracer() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testExtractSpanContext() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + Map attachments = new HashMap<>(); + attachments.put("trace-id", "test-trace-id".getBytes()); + request.getAttachments().putAll(attachments); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testSpanWithErrorFlag() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + Map attachments = new HashMap<>(); + attachments.put("trace-id", "test-trace-id".getBytes()); + request.getAttachments().putAll(attachments); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(TRpcException.newBizException(100, "test error")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testCreateSpanException() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerServerFilter exceptionFilter = new TracerServerFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + throw new RuntimeException("test exception"); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + exceptionFilter.filter(invoker, request); + } + + @Test + public void testFinishSpanException() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerServerFilter exceptionFilter = new TracerServerFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + if (spanBuilder == null) { + return null; + } + return spanBuilder.start(); + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + throw new RuntimeException("finish exception"); + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + exceptionFilter.filter(invoker, request); + } + + @Test + public void testWhenCompleteWithThrowable() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.completeExceptionally(new RuntimeException("test throwable")); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + + try { + filter.filter(invoker, request).toCompletableFuture().join(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testInjectWithErrorFlag() { + RpcServerContext context = new RpcServerContext(); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + Map attachments = new HashMap<>(); + attachments.put("trace-id", "test-trace-id".getBytes()); + request.getAttachments().putAll(attachments); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + rsp.setException(new IllegalArgumentException("test error")); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + filter.filter(invoker, request); + } + + @Test + public void testNullSpanInWhenComplete() { + RpcServerContext context = new RpcServerContext(); + RpcContextUtils.putValueMapValue(context, RpcContextValueKeys.CTX_TRACER, NoopTracerFactory.create()); + Request request = new DefRequest(); + request.setContext(context); + RpcInvocation invocation = new RpcInvocation(); + invocation.setRpcServiceName("rpcServiceName"); + invocation.setRpcMethodName("rpcMethodName"); + request.getMeta().setRemoteAddress(InetSocketAddress.createUnresolved("127.0.0.1", 8888)); + request.getMeta().setLocalAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9999)); + request.setInvocation(invocation); + + CompletableFuture future = new CompletableFuture(); + Response rsp = new DefResponse(); + future.complete(rsp); + Invoker invoker = (Invoker) PowerMockito.mock(Invoker.class); + PowerMockito.when(invoker.invoke(request)).thenReturn(future); + TracerServerFilter nullSpanFilter = new TracerServerFilter() { + @Override + public String getPluginName() { + return "tjg"; + } + + @Override + public Span start(SpanBuilder spanBuilder, RpcContext context, Invoker invoker, Request request) { + return null; + } + + @Override + public void finish(Span span, Request request, Response response, Throwable t) { + } + + @Override + public SpanContext extract(Tracer tracer, Map attachments) { + return null; + } + + @Override + public Map inject(Tracer tracer, Span span) { + return new HashMap<>(); + } + }; + nullSpanFilter.filter(invoker, request); + } + + private static class TestTraceFactory implements TracerFactory { + + @Override + public Tracer getTracer(String serverName, Integer port) { + return NoopTracerFactory.create(); + } + } +} diff --git a/trpc-core/src/test/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapterTest.java b/trpc-core/src/test/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapterTest.java new file mode 100644 index 0000000000..878fac50c0 --- /dev/null +++ b/trpc-core/src/test/java/com/tencent/trpc/core/transport/handler/ChannelHandlerAdapterTest.java @@ -0,0 +1,17 @@ +package com.tencent.trpc.core.transport.handler; + +import com.tencent.trpc.core.common.config.ProtocolConfig; +import com.tencent.trpc.core.transport.common.TestChannel; +import org.junit.Test; + +public class ChannelHandlerAdapterTest { + + @Test + public void testDebug() { + ChannelHandlerAdapter channelHandlerAdapter = new ChannelHandlerAdapter(); + ProtocolConfig protocolConfig = ProtocolConfig.newInstance(); + protocolConfig.setIp("127.0.0.1"); + protocolConfig.setPort(8888); + channelHandlerAdapter.disconnected(new TestChannel(protocolConfig)); + } +} \ No newline at end of file diff --git a/trpc-core/src/test/resources/log4j2.xml b/trpc-core/src/test/resources/log4j2.xml index cf8ececea1..2e14aae730 100644 --- a/trpc-core/src/test/resources/log4j2.xml +++ b/trpc-core/src/test/resources/log4j2.xml @@ -133,32 +133,32 @@ - + - + - + - + - + - + - + - + - + diff --git a/trpc-limiter/trpc-limiter-sentinel/src/main/java/com/tencent/trpc/limiter/sentinel/filter/SentinelLimiterFilter.java b/trpc-limiter/trpc-limiter-sentinel/src/main/java/com/tencent/trpc/limiter/sentinel/filter/SentinelLimiterFilter.java index 9aeffb1182..373f75614c 100644 --- a/trpc-limiter/trpc-limiter-sentinel/src/main/java/com/tencent/trpc/limiter/sentinel/filter/SentinelLimiterFilter.java +++ b/trpc-limiter/trpc-limiter-sentinel/src/main/java/com/tencent/trpc/limiter/sentinel/filter/SentinelLimiterFilter.java @@ -44,7 +44,9 @@ public class SentinelLimiterFilter implements Filter, InitializingExtension { @Override public void init() throws TRpcExtensionException { sentinelLimiter = (SentinelLimiter) ExtensionLoader.getExtensionLoader(Limiter.class).getExtension(NAME); - logger.debug("init sentinel limiter success, sentinelLimiter:{}", sentinelLimiter); + if (logger.isDebugEnabled()) { + logger.debug("init sentinel limiter success, sentinelLimiter:{}", sentinelLimiter); + } } @Override diff --git a/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/AbstractHttpExecutor.java b/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/AbstractHttpExecutor.java index 2ab5880494..35070cc618 100644 --- a/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/AbstractHttpExecutor.java +++ b/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/AbstractHttpExecutor.java @@ -423,7 +423,6 @@ private void setRpcServerContext(HttpServletRequest request, HttpServletResponse // to maintain consistency. rpcRequest.getAttachments().put(header, value.getBytes(StandardCharsets.UTF_8)); } - logger.debug("request attachment: {}", JsonUtils.toJson(rpcRequest.getAttachments())); } /** diff --git a/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/DefaultHttpExecutor.java b/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/DefaultHttpExecutor.java index 68faf223e3..7a834cc16d 100644 --- a/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/DefaultHttpExecutor.java +++ b/trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/server/DefaultHttpExecutor.java @@ -68,9 +68,6 @@ protected RpcMethodInfoAndInvoker getRpcMethodInfoAndInvoker(Object object) { if (object instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) object; String func = methodRegister.getNativeHttpFunc(request.getPathInfo()); - - logger.debug("got http trpc request, func: {}", func); - RpcMethodInfoAndInvoker methodAndInvoker = methodRegister.route(func); if (null == methodAndInvoker) { String serviceName = request.getParameter(HttpConstants.RPC_CALL_PARAM_SERVICE); diff --git a/trpc-proto/trpc-proto-standard/src/main/java/com/tencent/trpc/proto/standard/stream/client/StreamConsumerInvoker.java b/trpc-proto/trpc-proto-standard/src/main/java/com/tencent/trpc/proto/standard/stream/client/StreamConsumerInvoker.java index f7367e97ed..0d63ca20a7 100644 --- a/trpc-proto/trpc-proto-standard/src/main/java/com/tencent/trpc/proto/standard/stream/client/StreamConsumerInvoker.java +++ b/trpc-proto/trpc-proto-standard/src/main/java/com/tencent/trpc/proto/standard/stream/client/StreamConsumerInvoker.java @@ -1,7 +1,7 @@ /* * Tencent is pleased to support the open source community by making tRPC available. * - * Copyright (C) 2023 Tencent. + * Copyright (C) 2023 Tencent. * All rights reserved. * * If you have downloaded a copy of the tRPC source code from Tencent, @@ -69,7 +69,7 @@ public class StreamConsumerInvoker implements ConsumerInvoker { private final ClientTransport clientTransport; public StreamConsumerInvoker(ConsumerConfig consumerConfig, ProtocolConfig protocolConfig, - ClientTransport clientTransport) { + ClientTransport clientTransport) { this.consumerConfig = Objects.requireNonNull(consumerConfig, "consumerConfig is null"); this.backendConfig = Objects .requireNonNull(consumerConfig.getBackendConfig(), "backendConfig is null"); diff --git a/trpc-registry/trpc-registry-api/pom.xml b/trpc-registry/trpc-registry-api/pom.xml index 7d80c11b84..64eb0d86e8 100644 --- a/trpc-registry/trpc-registry-api/pom.xml +++ b/trpc-registry/trpc-registry-api/pom.xml @@ -19,10 +19,6 @@ - - org.slf4j - slf4j-simple - com.tencent.trpc trpc-core diff --git a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractFailedRetryRegistryCenter.java b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractFailedRetryRegistryCenter.java index e397596036..9212d53069 100644 --- a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractFailedRetryRegistryCenter.java +++ b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractFailedRetryRegistryCenter.java @@ -403,8 +403,10 @@ protected void recoverSubscribed() { } recoverSubscribed.forEach((registerInfo, registryCenterListenerSet) -> registryCenterListenerSet.getNotifyListeners().forEach(notifyListener -> { - logger.debug("[Recover] Subscribe registerInfo: {}, listener: {}", - registerInfo, notifyListener); + if (logger.isDebugEnabled()) { + logger.debug("[Recover] Subscribe registerInfo: {}, listener: {}", + registerInfo, notifyListener); + } addFailedSubscribedTask(registerInfo, notifyListener); }) ); diff --git a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractRegistryCenter.java b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractRegistryCenter.java index 8cc01421f7..3d48599098 100644 --- a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractRegistryCenter.java +++ b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/center/AbstractRegistryCenter.java @@ -123,8 +123,9 @@ public void register(RegisterInfo registerInfo) { @Override public void unregister(RegisterInfo registerInfo) { Objects.requireNonNull(registerInfo, "registerInfo can not be null"); - logger.debug("[unregister] registerInfo: {}", registerInfo); - + if (logger.isDebugEnabled()) { + logger.debug("[unregister] registerInfo: {}", registerInfo); + } registeredRegisterInfos.remove(registerInfo); } @@ -139,7 +140,9 @@ public void unregister(RegisterInfo registerInfo) { public void subscribe(RegisterInfo registerInfo, NotifyListener notifyListener) { Objects.requireNonNull(registerInfo, "registerInfo can not be null"); Objects.requireNonNull(notifyListener, "notifyListener can not be null"); - logger.debug("[subscribe] registerInfo: {}, notifyListener: {}", registerInfo, notifyListener); + if (logger.isDebugEnabled()) { + logger.debug("[subscribe] registerInfo: {}, notifyListener: {}", registerInfo, notifyListener); + } synchronized (this) { RegistryCenterListenerSet registryCenterListenerSet = subscribedRegisterInfos @@ -160,7 +163,9 @@ public void subscribe(RegisterInfo registerInfo, NotifyListener notifyListener) public void unsubscribe(RegisterInfo registerInfo, NotifyListener notifyListener) { Objects.requireNonNull(registerInfo, "registerInfo can not be null"); Objects.requireNonNull(notifyListener, "notifyListener can not be null"); - logger.debug("[unsubscribe] registerInfo: {}, notifyListener: {}", registerInfo, notifyListener); + if (logger.isDebugEnabled()) { + logger.debug("[unsubscribe] registerInfo: {}, notifyListener: {}", registerInfo, notifyListener); + } synchronized (this) { RegistryCenterListenerSet registryCenterListenerSet = subscribedRegisterInfos.get(registerInfo); @@ -209,7 +214,9 @@ public void notify(RegisterInfo registerInfo, NotifyListener notifyListener, */ @Override public void destroy() { - logger.debug("[Destroy] registry center: {}", config); + if (logger.isDebugEnabled()) { + logger.debug("[Destroy] registry center: {}", config); + } destroyRegistered(); destroySubscribed(); AbstractRegistryFactory.removeDestroyedRegistry(this); @@ -252,7 +259,9 @@ protected void recoverRegistered() { recoverRegistered.forEach(registerInfo -> { try { - logger.debug("[Recover] Register registerInfo: {}", registerInfo); + if (logger.isDebugEnabled()) { + logger.debug("[Recover] Register registerInfo: {}", registerInfo); + } register(registerInfo); } catch (Exception e) { logger.warn("[Recover] Failed to register registerInfo: {}, cause: ", registerInfo, e); @@ -272,8 +281,10 @@ protected void recoverSubscribed() { recoverSubscribed.forEach((registerInfo, registryCenterListenerSet) -> registryCenterListenerSet.getNotifyListeners().forEach(notifyListener -> { try { - logger.debug("[Recover] Subscribe registerInfo: {}, listener: {}", - registerInfo, notifyListener); + if (logger.isDebugEnabled()) { + logger.debug("[Recover] Subscribe registerInfo: {}, listener: {}", + registerInfo, notifyListener); + } subscribe(registerInfo, notifyListener); } catch (Exception e) { logger.warn("[Recover] Failed to subscribe registerInfo: {}, cause: ", registerInfo, e); @@ -306,7 +317,9 @@ private void destroyRegistered() { } destroyRegistered.forEach(registerInfo -> { try { - logger.debug("[Destroy] Unregister registerInfo: {}", registerInfo); + if (logger.isDebugEnabled()) { + logger.debug("[Destroy] Unregister registerInfo: {}", registerInfo); + } unregister(registerInfo); } catch (Exception e) { logger.warn("[Destroy] Failed to unregister registerInfo: {}, cause: ", registerInfo, e); @@ -325,8 +338,10 @@ private void destroySubscribed() { destroySubscribed.forEach((registerInfo, registryCenterListenerSet) -> registryCenterListenerSet.getNotifyListeners().forEach(notifyListener -> { try { - logger.debug("[Destroy] Unsubscribe registerInfo: {}, listener: {}", - registerInfo, notifyListener); + if (logger.isDebugEnabled()) { + logger.debug("[Destroy] Unsubscribe registerInfo: {}, listener: {}", + registerInfo, notifyListener); + } unsubscribe(registerInfo, notifyListener); } catch (Exception e) { logger.warn("[Destroy] Failed to unsubscribe registerInfo: {}, cause: ", registerInfo, e); diff --git a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/task/AbstractRetryTask.java b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/task/AbstractRetryTask.java index 5db23b2c37..67c743c370 100644 --- a/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/task/AbstractRetryTask.java +++ b/trpc-registry/trpc-registry-api/src/main/java/com/tencent/trpc/registry/task/AbstractRetryTask.java @@ -107,7 +107,9 @@ protected void retryAgain(Timeout timeout) { */ @Override public void run(Timeout timeout) throws Exception { - logger.debug("taskName: {}, registerInfo: {}", taskName, registerInfo); + if (logger.isDebugEnabled()) { + logger.debug("taskName: {}, registerInfo: {}", taskName, registerInfo); + } if (timeout.isCancelled() || isCancelled()) { return; } diff --git a/trpc-registry/trpc-registry-api/src/test/java/com/tencent/trpc/registry/center/AbstractRegistryCenterTest.java b/trpc-registry/trpc-registry-api/src/test/java/com/tencent/trpc/registry/center/AbstractRegistryCenterTest.java index d108ee6eaa..b9b1486709 100644 --- a/trpc-registry/trpc-registry-api/src/test/java/com/tencent/trpc/registry/center/AbstractRegistryCenterTest.java +++ b/trpc-registry/trpc-registry-api/src/test/java/com/tencent/trpc/registry/center/AbstractRegistryCenterTest.java @@ -315,7 +315,8 @@ public void testInvalidSyncFile() IllegalAccessException { try { serverRegistry.setPluginConfig( - initPluginConfig("0.0.0.0", 2181, false, false, "/xxxx/" + serverCacheFilePath, + initPluginConfig("0.0.0.0", 2181, + false, false, "/xxxx/" + serverCacheFilePath, CACHE_EXPIRE_TIME)); } catch (Exception e) { Assert.assertTrue(e instanceof IllegalArgumentException); @@ -334,4 +335,73 @@ public void testRecoverSubscribed() { serverRegistry.recoverSubscribed(); } + @Test + public void testGetRegistryCenterConfig() { + Assert.assertNotNull(clientRegistry.getRegistryCenterConfig()); + } + + @Test + public void testGetRegisteredRegisterInfos() { + RegisterInfo registerInfo = buildRegisterInfo(); + clientRegistry.register(registerInfo); + Assert.assertEquals(1, clientRegistry.getRegisteredRegisterInfos().size()); + } + + @Test + public void testGetSubscribedRegisterInfos() { + RegisterInfo registerInfo = buildRegisterInfo(); + NotifyListener discovery = getNotifyListener(registerInfo); + clientRegistry.subscribe(registerInfo, discovery); + Assert.assertEquals(1, clientRegistry.getSubscribedRegisterInfos().size()); + } + + @Test + public void testGetNotifiedRegisterInfos() { + RegisterInfo registerInfo = buildRegisterInfo(); + List registerInfos = new ArrayList<>(); + registerInfos.add(buildRegisterInfo(12000)); + NotifyListener discovery = getNotifyListener(registerInfo); + clientRegistry.notify(registerInfo, discovery, registerInfos); + Assert.assertEquals(1, clientRegistry.getNotifiedRegisterInfos().size()); + } + + @Test + public void testUnsubscribeWithEmptyListeners() { + RegisterInfo registerInfo = buildRegisterInfo(); + NotifyListener discovery = getNotifyListener(registerInfo); + clientRegistry.unsubscribe(registerInfo, discovery); + } + + @Test + public void testUnsubscribeMultipleTimes() { + RegisterInfo registerInfo = buildRegisterInfo(); + NotifyListener discovery1 = new NotifyListener() { + @Override + public void notify(List registerInfos) { + } + + @Override + public void destroy() throws TRpcExtensionException { + } + }; + NotifyListener discovery2 = new NotifyListener() { + @Override + public void notify(List registerInfos) { + } + + @Override + public void destroy() throws TRpcExtensionException { + } + }; + clientRegistry.subscribe(registerInfo, discovery1); + clientRegistry.subscribe(registerInfo, discovery2); + Assert.assertEquals(2, + clientRegistry.getSubscribedRegisterInfos().get(registerInfo).getNotifyListeners().size()); + clientRegistry.unsubscribe(registerInfo, discovery1); + Assert.assertEquals(1, + clientRegistry.getSubscribedRegisterInfos().get(registerInfo).getNotifyListeners().size()); + clientRegistry.unsubscribe(registerInfo, discovery2); + Assert.assertEquals(0, clientRegistry.getSubscribedRegisterInfos().size()); + } + } diff --git a/trpc-registry/trpc-registry-api/src/test/resources/log4j2.xml b/trpc-registry/trpc-registry-api/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..408d1a7599 --- /dev/null +++ b/trpc-registry/trpc-registry-api/src/test/resources/log4j2.xml @@ -0,0 +1,40 @@ + + + + ../log + + + + + + + + + %d [%-5p]%C{1}(%L)(trace:%X{printTraceId) %m%n + + + + + + + + %d [%-5p]%C{1}(%L) %m%n + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trpc-registry/trpc-registry-zookeeper/pom.xml b/trpc-registry/trpc-registry-zookeeper/pom.xml index 5ff31c64a4..2117690eed 100644 --- a/trpc-registry/trpc-registry-zookeeper/pom.xml +++ b/trpc-registry/trpc-registry-zookeeper/pom.xml @@ -36,11 +36,6 @@ com.tencent.trpc trpc-transport-netty - - org.slf4j - slf4j-simple - - org.apache.curator curator-recipes diff --git a/trpc-registry/trpc-registry-zookeeper/src/main/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClient.java b/trpc-registry/trpc-registry-zookeeper/src/main/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClient.java index 8fd18f579b..71c64919b2 100644 --- a/trpc-registry/trpc-registry-zookeeper/src/main/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClient.java +++ b/trpc-registry/trpc-registry-zookeeper/src/main/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClient.java @@ -454,7 +454,9 @@ public void setDataListener(DataListener dataListener) { */ @Override public void event(Type type, ChildData oldData, ChildData data) { - logger.debug("zookeeper data changed. type: {}, oldData: {}, newData: {}", type, oldData, data); + if (logger.isDebugEnabled()) { + logger.debug("zookeeper data changed. type: {}, oldData: {}, newData: {}", type, oldData, data); + } if (dataListener == null) { return; diff --git a/trpc-registry/trpc-registry-zookeeper/src/test/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClientTest.java b/trpc-registry/trpc-registry-zookeeper/src/test/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClientTest.java index 8baf205dc0..ccd994cc11 100644 --- a/trpc-registry/trpc-registry-zookeeper/src/test/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClientTest.java +++ b/trpc-registry/trpc-registry-zookeeper/src/test/java/com/tencent/trpc/registry/transporter/curator/CuratorZookeeperClientTest.java @@ -392,4 +392,220 @@ public void testCreatePersistentError() { } } + @Test + public void testCheckExists() throws Exception { + client.create(testNodeFullPath, false); + boolean exists = Whitebox.invokeMethod(client, "checkExists", testNodeFullPath); + Assert.assertTrue(exists); + + boolean notExists = Whitebox.invokeMethod(client, "checkExists", testNodeFullPath + "/notexist"); + Assert.assertFalse(notExists); + } + + @Test + public void testCheckExistsError() throws Exception { + ZookeeperClient client = new CuratorZookeeperClient(buildConfig()); + ((CuratorZookeeperClient) client).setClient(null); + + boolean exists = Whitebox.invokeMethod(client, "checkExists", testNodeFullPath); + Assert.assertFalse(exists); + } + + @Test + public void testCreatePersistentNoData() throws Exception { + Whitebox.invokeMethod(client, "createPersistent", testRootPath); + List children = client.getChildren("/"); + Assert.assertTrue(children.contains(testRootName)); + } + + @Test + public void testCreatePersistentNoDataError() throws Exception { + ZookeeperClient client = new CuratorZookeeperClient(buildConfig()); + ((CuratorZookeeperClient) client).setClient(null); + + try { + Whitebox.invokeMethod(client, "createPersistent", testRootPath); + } catch (Exception e) { + LOGGER.info("testCreatePersistentNoDataError success"); + } + } + + @Test + public void testCreateEphemeralNodeExists() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, true); + + Whitebox.invokeMethod(client, "createEphemeral", providerPath); + List children = client.getChildren(testNodeFullPath); + Assert.assertEquals(1, children.size()); + } + + @Test + public void testCreateEphemeralWithDataNodeExists() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, "data1", true); + + Whitebox.invokeMethod(client, "createEphemeral", providerPath, "data2"); + List children = client.getChildren(testNodeFullPath); + Assert.assertEquals(1, children.size()); + } + + @Test + public void testCreatePersistentWithDataNodeExists() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, "data1", false); + + Whitebox.invokeMethod(client, "createPersistent", providerPath, "data2"); + List children = client.getChildren(testNodeFullPath); + Assert.assertEquals(1, children.size()); + } + + @Test + public void testStateListener() throws Exception { + final Map stateMap = new HashMap<>(); + client.addStateListener(state -> { + stateMap.put(state.name(), stateMap.getOrDefault(state.name(), 0) + 1); + }); + + client.create(testRootPath, false); + Thread.sleep(500); + Assert.assertTrue(client.isConnected()); + } + + @Test + public void testGetCuratorConnectStringError() { + try { + RegistryCenterConfig config = new RegistryCenterConfig(); + config.setAddresses(""); + ZookeeperClient client = new CuratorZookeeperClient(config); + } catch (Exception e) { + LOGGER.info("testGetCuratorConnectStringError success"); + } + } + + @Test + public void testCuratorChildWatcherProcess() throws Exception { + client.create(testNodeFullPath, false); + + final Map> childrenMap = new HashMap<>(); + ChildListener childListener = (path, children) -> { + childrenMap.put(path, children); + }; + + client.addChildListener(testNodeFullPath, childListener); + + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, true); + + Thread.sleep(1000); + Assert.assertTrue(childrenMap.containsKey(testNodeFullPath)); + Assert.assertEquals(1, childrenMap.get(testNodeFullPath).size()); + } + + @Test + public void testCuratorChildWatcherUnwatch() throws Exception { + client.create(testNodeFullPath, false); + + final Map> childrenMap = new HashMap<>(); + ChildListener childListener = (path, children) -> { + childrenMap.put(path, children); + }; + + client.addChildListener(testNodeFullPath, childListener); + client.removeChildListener(testNodeFullPath, childListener); + + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, true); + + Thread.sleep(1000); + Assert.assertFalse(childrenMap.containsKey(testNodeFullPath)); + } + + @Test + public void testCuratorDataCacheGetterSetter() throws Exception { + DataListener dataListener1 = (type, oldData, data) -> {}; + DataListener dataListener2 = (type, oldData, data) -> {}; + + CuratorZookeeperClient.CuratorDataCacheImpl cache = + new CuratorZookeeperClient.CuratorDataCacheImpl(dataListener1); + + Assert.assertEquals(dataListener1, cache.getDataListener()); + + cache.setDataListener(dataListener2); + Assert.assertEquals(dataListener2, cache.getDataListener()); + } + + @Test + public void testRemoveDataListenerWithNullCache() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + + DataListener dataListener = (type, oldData, data) -> {}; + client.removeDataListener(providerPath, dataListener); + } + + @Test + public void testCreateWithContent() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, "testContent", false); + + List children = client.getChildren(testNodeFullPath); + Assert.assertEquals(1, children.size()); + Assert.assertEquals("provider1", children.get(0)); + } + + @Test + public void testCreateEphemeralWithContent() throws Exception { + client.create(testNodeFullPath, false); + String providerPath = testNodeFullPath + "/provider1"; + client.create(providerPath, "testContent", true); + + List children = client.getChildren(testNodeFullPath); + Assert.assertEquals(1, children.size()); + Assert.assertEquals("provider1", children.get(0)); + } + + @Test + public void testDoClose() throws Exception { + ZookeeperClient newClient = curatorZookeeperFactory.connect(buildConfig()); + newClient.create(testRootPath, false); + Assert.assertTrue(newClient.isConnected()); + newClient.close(); + newClient.close(); + } + + @Test + public void testGetState() throws Exception { + client.create(testRootPath, false); + Thread.sleep(500); + } + + @Test + public void testAddStateListener() throws Exception { + final Map stateMap = new HashMap<>(); + client.addStateListener(state -> { + stateMap.put(state.name(), stateMap.getOrDefault(state.name(), 0) + 1); + }); + + client.removeStateListener(state -> {}); + } + + @Test + public void testGetContent() throws Exception { + client.create(testNodeFullPath, "testContent", false); + String content = client.getContent(testNodeFullPath); + Assert.assertNull(content); + } + + @Test + public void testGetContentNotExist() throws Exception { + String content = client.getContent(testNodeFullPath + "/notexist"); + Assert.assertNull(content); + } + } + diff --git a/trpc-registry/trpc-registry-zookeeper/src/test/resources/log4j2.xml b/trpc-registry/trpc-registry-zookeeper/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..408d1a7599 --- /dev/null +++ b/trpc-registry/trpc-registry-zookeeper/src/test/resources/log4j2.xml @@ -0,0 +1,40 @@ + + + + ../log + + + + + + + + + %d [%-5p]%C{1}(%L)(trace:%X{printTraceId) %m%n + + + + + + + + %d [%-5p]%C{1}(%L) %m%n + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/polaris/common/PolarisTrans.java b/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/polaris/common/PolarisTrans.java index c39dcda747..cb8d5e2f3d 100644 --- a/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/polaris/common/PolarisTrans.java +++ b/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/polaris/common/PolarisTrans.java @@ -63,7 +63,6 @@ public static ServiceInstance toServiceInstance(InstancesResponse response, Instance polarisInstance) { String containerName = getContainerName(polarisInstance); String setName = getSetName(polarisInstance); - LOGGER.debug("[PolarisTrans] containerName:{},setName:{}", containerName, setName); ServiceInstance serviceInstance = new ServiceInstance(polarisInstance.getHost(), polarisInstance.getPort(), polarisInstance.isHealthy()); @@ -161,7 +160,6 @@ public static String getPolarisInstanceId(ServiceInstance serviceInstance) { public static Map trans2PolarisMetadata(Map originMap) { Object metadataObj = originMap.get(Constants.METADATA); if (metadataObj == null || !(metadataObj instanceof Map)) { - LOGGER.debug("metadata is empty or param error metadata:{}", metadataObj); return Maps.newHashMap(); } Map metadata = (Map) metadataObj; diff --git a/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/selector/polaris/PolarisSelector.java b/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/selector/polaris/PolarisSelector.java index bb37defea8..82bfd31df6 100644 --- a/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/selector/polaris/PolarisSelector.java +++ b/trpc-selector/trpc-selector-open-polaris/src/main/java/com/tencent/trpc/selector/polaris/PolarisSelector.java @@ -145,8 +145,10 @@ public void warmup(ServiceId serviceId) { PolarisFutureUtil.toCompletableFuture(polarisAPI.asyncGetInstances(req), selectorConfig.getWorkerPool().toExecutor()) .thenApply(res -> { - logger.debug("[selector] warmup polaris asyncSelectAll return success:{}", - res); + if (logger.isDebugEnabled()) { + logger.debug("[selector] warmup polaris asyncSelectAll return success:{}", + res); + } if (res == null || res.getInstances() == null || res.getInstances().length == 0) { return Collections.emptyList(); @@ -181,7 +183,9 @@ public CompletionStage asyncSelectOne(ServiceId serviceId, Requ ConfigurationLoader loader = ConfigurationManager.getConfigurationLoader(configCenter); return Optional.ofNullable(loader.getValue(key, ConfigManager.getInstance().getServerConfig().getApp())); }); - logger.debug("[asyncSelectOne] GetOneInstanceRequest:{}", req); + if (logger.isDebugEnabled()) { + logger.debug("[asyncSelectOne] GetOneInstanceRequest:{}", req); + } try { MetadataContext metadataContext = buildCalleeMetadataManager(request); @@ -193,8 +197,10 @@ public CompletionStage asyncSelectOne(ServiceId serviceId, Requ () -> polarisAPI.getOneInstance(req), executor); return future.thenCompose(res -> { if (res != null && res.getInstances() != null && res.getInstances().length > 0) { - logger.debug("[selector] selector asyncSelectOne ServiceId:{} return success:{}", - serviceId, res.getInstances()[0]); + if (logger.isDebugEnabled()) { + logger.debug("[selector] selector asyncSelectOne ServiceId:{} return success:{}", + serviceId, res.getInstances()[0]); + } return CompletableFuture.completedFuture( PolarisTrans.toServiceInstance(res, res.getInstances()[0])); } @@ -214,12 +220,16 @@ public CompletionStage asyncSelectOne(ServiceId serviceId, Requ public CompletionStage> asyncSelectAll(ServiceId serviceId, Request request) { GetInstancesRequest req = createSelectAllReq(serviceId, request, false); - logger.debug("[asyncSelectAll] GetInstancesRequest:{}", req); + if (logger.isDebugEnabled()) { + logger.debug("[asyncSelectAll] GetInstancesRequest:{}", req); + } try { return PolarisFutureUtil.toCompletableFuture(polarisAPI.asyncGetInstances(req), selectorConfig.getWorkerPool().toExecutor()) .thenApply(res -> { - logger.debug("[selector] polaris asyncSelectAll return success:{}", res); + if (logger.isDebugEnabled()) { + logger.debug("[selector] polaris asyncSelectAll return success:{}", res); + } if (res == null || res.getInstances() == null || res.getInstances().length == 0) { return Collections.emptyList(); @@ -249,7 +259,9 @@ public void report(ServiceInstance serviceInstance, int code, long costMs) */ private CompletableFuture selectOneFallback(ServiceId serviceId, Request request) { - logger.debug("[selector] selectOneFallback call for ServiceId:{}", serviceId); + if (logger.isDebugEnabled()) { + logger.debug("[selector] selectOneFallback call for ServiceId:{}", serviceId); + } GetInstancesRequest req = createSelectAllReq(serviceId, request, true); try { return PolarisFutureUtil.toCompletableFuture(polarisAPI.asyncGetInstances(req), diff --git a/trpc-selector/trpc-selector-open-polaris/src/test/java/com/tencent/trpc/selector/open/polaris/PolarisSelectorTest.java b/trpc-selector/trpc-selector-open-polaris/src/test/java/com/tencent/trpc/selector/open/polaris/PolarisSelectorTest.java index 8a7066f940..37d0dfefdc 100644 --- a/trpc-selector/trpc-selector-open-polaris/src/test/java/com/tencent/trpc/selector/open/polaris/PolarisSelectorTest.java +++ b/trpc-selector/trpc-selector-open-polaris/src/test/java/com/tencent/trpc/selector/open/polaris/PolarisSelectorTest.java @@ -28,12 +28,16 @@ import com.tencent.polaris.factory.api.APIFactory; import com.tencent.trpc.core.common.ConfigManager; import com.tencent.trpc.core.common.config.PluginConfig; +import com.tencent.trpc.core.constant.proto.HttpConstants; import com.tencent.trpc.core.rpc.Request; +import com.tencent.trpc.core.rpc.RequestMeta; +import com.tencent.trpc.core.rpc.RpcClientContext; import com.tencent.trpc.core.selector.ServiceId; import com.tencent.trpc.core.selector.ServiceInstance; import com.tencent.trpc.polaris.common.PolarisTrans; import com.tencent.trpc.selector.polaris.PolarisSelector; import com.tencent.trpc.selector.polaris.common.pojo.PolarisServiceInstances; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -43,6 +47,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -103,6 +108,39 @@ public void testEmptyReturn() { }); } + @Test + public void testWarmupWithEmptyInstances() { + ServiceId serviceId = DataTest.newServiceId(); + serviceId.setServiceName("service_empty"); + + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + try { + clusterNaming.warmup(serviceId); + } catch (Exception e) { + Assert.fail("warmup should not throw exception for empty instances: " + e.getMessage()); + } + } + + @Test + public void testSelectEmptyInstances() throws Exception { + ServiceId serviceId = DataTest.newServiceId(); + serviceId.setServiceName("service_empty"); + + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + CompletionStage> future = clusterNaming.asyncSelectAll(serviceId, DataTest.request); + List result = future.toCompletableFuture().get(); + + Assert.assertNotNull("result should not be null", result); + Assert.assertTrue("result should be empty list", result.isEmpty()); + Assert.assertEquals("result size should be 0", 0, result.size()); + } + @Test public void testExp() { ServiceId expService = DataTest.getExpService(); @@ -250,6 +288,9 @@ private Answer newPolarisAnswer(boolean getOne) { if (service.contains("fallback") && getOne) { size = 0; } + if (service.contains("fallback_null")) { + size = 0; + } CompletableFuture instancesResponseCompletableFuture = CompletableFuture .completedFuture(new InstancesResponse(getServiceInstances(size), null, null)); InstancesFuture instancesFuture = new InstancesFuture(() -> { @@ -334,4 +375,339 @@ public void testGetConsumerAPI() { Assert.assertNotNull(polarisSelector.getPolarisAPI()); polarisSelector.destroy(); } + + @Test + public void testAsyncSelectOneWithHashVal() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + Request request = DataTest.mockRequest(); + RequestMeta meta = request.getMeta(); + meta.setHashVal("test-hash-value"); + ServiceId serviceId = DataTest.newServiceId(); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + AtomicReference resultRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + resultRef.set(res); + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + } + + @Test + public void testNullExtMap() { + Map extMap = new HashMap<>(); + extMap.put("worker_pool", "selector_pool1"); + PluginConfig config = new PluginConfig("selector_null_ext", PolarisSelector.class, extMap); + + PolarisSelector selector = new PolarisSelector(); + selector.setPluginConfig(config); + selector.init(); + Assert.assertNotNull(selector.getPolarisAPI()); + selector.destroy(); + } + + @Test + public void testWarmupException() { + ServiceId serviceId = DataTest.getExpService(); + + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + try { + clusterNaming.warmup(serviceId); + } catch (Exception e) { + Assert.assertTrue(e.getMessage().contains("call polaris error") + || e.getCause() != null && e.getCause().getMessage().contains("test polaris exp")); + } + } + + @Test + public void testAsyncSelectAllException() { + ServiceId serviceId = DataTest.getExpService(); + + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + try { + CompletionStage> future = clusterNaming.asyncSelectAll(serviceId, DataTest.request); + future.toCompletableFuture().join(); + } catch (Exception e) { + Assert.assertTrue(e.getMessage().contains("call polaris error") + || (e.getCause() != null && e.getCause().getMessage().contains("test polaris exp"))); + } + } + + @Test + public void testSelectOneFallbackReturnsNull() { + ServiceId serviceId = DataTest.newServiceId(); + serviceId.setServiceName("fallback_null"); + + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, DataTest.request); + AtomicReference resultRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + resultRef.set(res); + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + } + + @Test + public void tesSelectAllNamespace() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + CompletionStage> future = clusterNaming.asyncSelectAll(serviceId, DataTest.request); + + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage> stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + + @Test + public void testSelectOneMetadataContext() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testServletRequest() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RpcClientContext context = new RpcClientContext(); + + HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class); + Mockito.when(servletRequest.getHeader(Mockito.anyString())).thenReturn("test-value"); + context.getReqAttachMap().put(HttpConstants.TRPC_ATTACH_SERVLET_REQUEST, servletRequest); + Mockito.when(request.getContext()).thenReturn(context); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testCustomHeaders() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RpcClientContext context = new RpcClientContext(); + context.getReqAttachMap().put("custom-header", "custom-value"); + Mockito.when(request.getContext()).thenReturn(context); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testRemoteAddress() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RequestMeta meta = new RequestMeta(); + meta.setRemoteAddress(new InetSocketAddress("192.168.1.1", 8080)); + meta.getCallInfo().setCalleeMethod("testMethod"); + Mockito.when(request.getMeta()).thenReturn(meta); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testSpringHeaders() throws Exception { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RpcClientContext context = new RpcClientContext(); + + Object mockHeaders = new Object() { + public String getFirst(String headerName) { + return "header-value"; + } + }; + context.getReqAttachMap().put("headers", mockHeaders); + Mockito.when(request.getContext()).thenReturn(context); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testHeadersException() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RpcClientContext context = new RpcClientContext(); + + Object mockHeaders = new Object(); + context.getReqAttachMap().put("headers", mockHeaders); + Mockito.when(request.getContext()).thenReturn(context); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testNoCriteria() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = DataTest.newServiceId(); + Request request = DataTest.mockRequest(); + RequestMeta meta = new RequestMeta(); + Mockito.when(request.getMeta()).thenReturn(meta); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testWithExtMap() { + Map extMap = new HashMap<>(); + extMap.put("worker_pool", "selector_pool1"); + extMap.put("test_key", "test_value"); + PluginConfig config = new PluginConfig("selector_ext", PolarisSelector.class, extMap); + + PolarisSelector selector = new PolarisSelector(); + selector.setPluginConfig(config); + selector.init(); + Assert.assertNotNull(selector.getPolarisAPI()); + selector.destroy(); + } + + @Test + public void testReqNoNamespace() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = new ServiceId(); + serviceId.setServiceName(DataTest.getService()); + serviceId.setVersion("1.0"); + serviceId.setGroup("group"); + serviceId.setParameters(new HashMap<>()); + + CompletionStage future = clusterNaming.asyncSelectOne(serviceId, DataTest.request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } + + @Test + public void testAllReqNoNamespace() { + PolarisSelector clusterNaming = new PolarisSelector(); + clusterNaming.setPluginConfig(selectorConfig); + clusterNaming.init(); + + ServiceId serviceId = new ServiceId(); + serviceId.setServiceName(DataTest.getService()); + serviceId.setVersion("1.0"); + serviceId.setGroup("group"); + serviceId.setParameters(new HashMap<>()); + + CompletionStage> future = clusterNaming.asyncSelectAll(serviceId, DataTest.request); + AtomicReference errorRef = new AtomicReference<>(); + CompletionStage> stage = future.whenComplete((res, err) -> { + if (err != null) { + errorRef.set(err); + } + }); + CompletableFuture.allOf(stage.toCompletableFuture()).join(); + Assert.assertNull(errorRef.get()); + } }