Merge branch '3.2' into dependabot/maven/fabric8_kubernetes_version-6.7.2

This commit is contained in:
Albumen Kevin 2023-06-25 09:18:35 +08:00 committed by GitHub
commit ba22019d28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 1289 additions and 1714 deletions

View File

@ -114,5 +114,4 @@ dubbo-nacos-spring-boot-starter
dubbo-zookeeper-spring-boot-starter
dubbo-zookeeper-curator5-spring-boot-starter
dubbo-spring-security
dubbo-tracing
dubbo-xds

View File

@ -86,5 +86,10 @@
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -476,15 +476,21 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
private boolean addValidInvoker(Invoker<T> invoker) {
boolean result;
synchronized (this.validInvokers) {
return this.validInvokers.add(invoker);
result = this.validInvokers.add(invoker);
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
return result;
}
private boolean removeValidInvoker(Invoker<T> invoker) {
boolean result;
synchronized (this.validInvokers) {
return this.validInvokers.remove(invoker);
result = this.validInvokers.remove(invoker);
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
return result;
}
protected abstract List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain,

View File

@ -36,6 +36,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
*/
public class StaticDirectory<T> extends AbstractDirectory<T> {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StaticDirectory.class);
private final Class<T> interfaceClass;
public StaticDirectory(List<Invoker<T>> invokers) {
this(null, invokers, null);
@ -55,11 +56,12 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
throw new IllegalArgumentException("invokers == null");
}
this.setInvokers(new BitList<>(invokers));
this.interfaceClass = invokers.get(0).getInterface();
}
@Override
public Class<T> getInterface() {
return getInvokers().get(0).getInterface();
return interfaceClass;
}
@Override

View File

@ -14,9 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.rpc.cluster.filter.support;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.metrics.observation.DefaultDubboClientObservationConvention;
import org.apache.dubbo.metrics.observation.DubboClientContext;
import org.apache.dubbo.metrics.observation.DubboClientObservationConvention;
import org.apache.dubbo.metrics.observation.DubboObservationDocumentation;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
@ -26,10 +30,6 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import org.apache.dubbo.tracing.DefaultDubboClientObservationConvention;
import org.apache.dubbo.tracing.DubboClientObservationConvention;
import org.apache.dubbo.tracing.DubboObservationDocumentation;
import org.apache.dubbo.tracing.context.DubboClientContext;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
@ -39,7 +39,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
/**
* A {@link Filter} that creates an {@link Observation} around the outgoing message.
*/
@Activate(group = CONSUMER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry")
@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
private ObservationRegistry observationRegistry;
@ -47,8 +47,12 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
private DubboClientObservationConvention clientObservationConvention;
public ObservationSenderFilter(ApplicationModel applicationModel) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> {
if (Boolean.TRUE.equals(cfg.getEnabled())) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
}
});
}
@Override
@ -71,9 +75,6 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
if (observation == null) {
return;
}
if (appResponse != null && appResponse.hasException()) {
observation.error(appResponse.getException());
}
observation.stop();
}

View File

@ -1,4 +1,5 @@
consumercontext=org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter
consumer-classloader=org.apache.dubbo.rpc.cluster.filter.support.ConsumerClassLoaderFilter
router-snapshot=org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter
observationsender=org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter
metricsClusterFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter

View File

@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.filter;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.AppResponse;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.micrometer.tracing.test.SampleTestRunner;
import org.junit.jupiter.api.AfterEach;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
abstract class AbstractObservationFilterTest extends SampleTestRunner {
ApplicationModel applicationModel;
RpcInvocation invocation;
BaseFilter filter;
Invoker<?> invoker = mock(Invoker.class);
static final String INTERFACE_NAME = "org.apache.dubbo.MockInterface";
static final String METHOD_NAME = "mockMethod";
static final String GROUP = "mockGroup";
static final String VERSION = "1.0.0";
@AfterEach
public void teardown() {
if (applicationModel != null) {
applicationModel.destroy();
}
}
abstract BaseFilter createFilter(ApplicationModel applicationModel);
void setupConfig() {
ApplicationConfig config = new ApplicationConfig();
config.setName("MockObservations");
applicationModel = ApplicationModel.defaultModel();
applicationModel.getApplicationConfigManager().setApplication(config);
invocation = new RpcInvocation(new MockInvocation());
invocation.addInvokedInvoker(invoker);
applicationModel.getBeanFactory().registerBean(getObservationRegistry());
TracingConfig tracingConfig = new TracingConfig();
tracingConfig.setEnabled(true);
applicationModel.getApplicationConfigManager().setTracing(tracingConfig);
filter = createFilter(applicationModel);
given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
initParam();
}
private void initParam() {
invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION);
invocation.setMethodName(METHOD_NAME);
invocation.setParameterTypes(new Class[] {String.class});
}
}

View File

@ -15,22 +15,23 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.rpc.cluster.filter;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.micrometer.common.KeyValues;
import io.micrometer.core.tck.MeterRegistryAssert;
import io.micrometer.tracing.test.SampleTestRunner;
import io.micrometer.tracing.test.simple.SpansAssert;
import org.assertj.core.api.BDDAssertions;
class ObservationSenderFilterTest extends AbstractObservationFilterTest {
@Override
public SampleTestRunnerConsumer yourCode() {
public SampleTestRunner.SampleTestRunnerConsumer yourCode() {
return (buildingBlocks, meterRegistry) -> {
setupConfig();
setupAttachments();

View File

@ -17,46 +17,28 @@
package com.alibaba.dubbo.rpc.service;
import org.apache.dubbo.common.utils.StringUtils;
@Deprecated
public class GenericException extends RuntimeException {
public class GenericException extends org.apache.dubbo.rpc.service.GenericException {
private static final long serialVersionUID = -1182299763306599962L;
private String exceptionClass;
private String exceptionMessage;
public GenericException() {
}
public GenericException(String exceptionClass, String exceptionMessage) {
public GenericException(String exceptionMessage) {
super(exceptionMessage);
this.exceptionClass = exceptionClass;
this.exceptionMessage = exceptionMessage;
}
public GenericException(String exceptionClass, String exceptionMessage) {
super(exceptionClass, exceptionMessage);
}
public GenericException(Throwable cause) {
super(StringUtils.toString(cause));
this.exceptionClass = cause.getClass().getName();
this.exceptionMessage = cause.getMessage();
super(cause);
}
public String getExceptionClass() {
return exceptionClass;
public GenericException(String message, Throwable cause, String exceptionClass, String exceptionMessage) {
super(message, cause, exceptionClass, exceptionMessage);
}
public void setExceptionClass(String exceptionClass) {
this.exceptionClass = exceptionClass;
}
public String getExceptionMessage() {
return exceptionMessage;
}
public void setExceptionMessage(String exceptionMessage) {
this.exceptionMessage = exceptionMessage;
}
}

View File

@ -22,5 +22,5 @@ public interface GenericService extends org.apache.dubbo.rpc.service.GenericServ
@Override
Object $invoke(String method, String[] parameterTypes, Object[] args)
throws com.alibaba.dubbo.rpc.service.GenericException;
throws GenericException;
}

View File

@ -92,8 +92,6 @@ public interface LoggerCodeConstants {
String VULNERABILITY_WARNING = "0-28";
String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29";
// Registry module

View File

@ -14,24 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter;
package org.apache.dubbo.common.constants;
import brave.handler.SpanHandler;
import io.opentelemetry.sdk.trace.export.SpanExporter;
public interface TraceExporter {
/**
* Indicate that a service need to be registered to registry or not
*/
public enum RegisterTypeEnum {
/**
* for otel
*
* @return
* Never register. Cannot be registered by any command(like QoS-online).
*/
SpanExporter getSpanExporter();
NEVER_REGISTER,
/**
* for brave
*
* @return
* Manual register. Can be registered by command(like QoS-online), but not register by default.
*/
SpanHandler getSpanHandler();
MANUAL_REGISTER,
/**
* (INTERNAL) Auto register by deployer. Will be registered after deployer started.
* (Delay publish when starting. Prevent service from being invoked before all services are started)
*/
AUTO_REGISTER_BY_DEPLOYER,
/**
* Auto register. Will be registered when one service is exported.
*/
AUTO_REGISTER;
}

View File

@ -73,6 +73,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static java.util.ServiceLoader.load;
@ -346,7 +347,9 @@ public class ExtensionLoader<T> {
checkDestroyed();
// solve the bug of using @SPI's wrapper method to report a null pointer exception.
Map<Class<?>, T> activateExtensionsMap = new TreeMap<>(activateComparator);
List<String> names = values == null ? new ArrayList<>(0) : asList(values);
List<String> names = values == null ?
new ArrayList<>(0) :
Arrays.stream(values).map(StringUtils::trim).collect(Collectors.toList());
Set<String> namesSet = new HashSet<>(names);
if (!namesSet.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) {
if (cachedActivateGroups.size() == 0) {

View File

@ -21,6 +21,8 @@ import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import java.beans.Transient;
import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
@ -184,6 +186,7 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
}
@Override
@Transient
protected boolean isNeedCheckMethod() {
return StringUtils.isEmpty(getGeneric());
}

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;
@ -135,11 +136,13 @@ public class ModuleConfig extends AbstractConfig {
}
@Override
@Transient
public ModuleModel getScopeModel() {
return (ModuleModel) super.getScopeModel();
}
@Override
@Transient
protected ScopeModel getDefaultModel() {
return ApplicationModel.defaultModel().getDefaultModule();
}

View File

@ -150,6 +150,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
}
@Override
@Transient
public Map<String, String> getMetaData() {
return getMetaData(null);
}
@ -226,7 +227,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
public static Class<?> determineInterfaceClass(String generic, String interfaceName, ClassLoader classLoader) {
if (ProtocolUtils.isGeneric(generic)) {
return GenericService.class;
return com.alibaba.dubbo.rpc.service.GenericService.class;
}
try {
if (StringUtils.isNotEmpty(interfaceName)) {

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.RegisterTypeEnum;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Service;
@ -180,6 +181,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
}
@Override
@Transient
public Map<String, String> getMetaData() {
return getMetaData(null);
}
@ -416,7 +418,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
* export service and auto start application instance
*/
public final void export() {
export(true);
export(RegisterTypeEnum.AUTO_REGISTER);
}
public abstract void unexport();
@ -425,7 +427,24 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
public abstract boolean isUnexported();
public abstract void export(boolean register);
/**
* Export service to network
*
* @param registerType register type of current export action.
*/
public abstract void export(RegisterTypeEnum registerType);
public abstract void register();
/**
* Register delay published service to registry.
*/
public final void register() {
register(false);
}
/**
* Register delay published service to registry.
*
* @param byDeployer register by deployer or not.
*/
public abstract void register(boolean byDeployer);
}

View File

@ -39,19 +39,6 @@ public class BaggageConfig implements Serializable {
*/
private List<String> remoteFields = new ArrayList<>();
public BaggageConfig() {
}
public BaggageConfig(Boolean enabled) {
this.enabled = enabled;
}
public BaggageConfig(Boolean enabled, Correlation correlation, List<String> remoteFields) {
this.enabled = enabled;
this.correlation = correlation;
this.remoteFields = remoteFields;
}
public Boolean getEnabled() {
return enabled;
}
@ -89,18 +76,6 @@ public class BaggageConfig implements Serializable {
*/
private List<String> fields = new ArrayList<>();
public Correlation() {
}
public Correlation(boolean enabled) {
this.enabled = enabled;
}
public Correlation(boolean enabled, List<String> fields) {
this.enabled = enabled;
this.fields = fields;
}
public boolean isEnabled() {
return this.enabled;
}

View File

@ -56,28 +56,15 @@ public class ExporterConfig implements Serializable {
private String endpoint;
/**
* Connection timeout for requests to Zipkin. (seconds)
* Connection timeout for requests to Zipkin.
*/
private Duration connectTimeout = Duration.ofSeconds(1);
/**
* Read timeout for requests to Zipkin. (seconds)
* Read timeout for requests to Zipkin.
*/
private Duration readTimeout = Duration.ofSeconds(10);
public ZipkinConfig() {
}
public ZipkinConfig(String endpoint) {
this.endpoint = endpoint;
}
public ZipkinConfig(String endpoint, Duration connectTimeout, Duration readTimeout) {
this.endpoint = endpoint;
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
}
public String getEndpoint() {
return endpoint;
}
@ -111,7 +98,7 @@ public class ExporterConfig implements Serializable {
private String endpoint;
/**
* The maximum time to wait for the collector to process an exported batch of spans. (seconds)
* The maximum time to wait for the collector to process an exported batch of spans.
*/
private Duration timeout = Duration.ofSeconds(10);
@ -123,24 +110,6 @@ public class ExporterConfig implements Serializable {
private Map<String, String> headers = new HashMap<>();
public OtlpConfig() {
}
public OtlpConfig(String endpoint) {
this.endpoint = endpoint;
}
public OtlpConfig(String endpoint, Duration timeout) {
this.endpoint = endpoint;
this.timeout = timeout;
}
public OtlpConfig(String endpoint, Duration timeout, String compressionMethod) {
this.endpoint = endpoint;
this.timeout = timeout;
this.compressionMethod = compressionMethod;
}
public String getEndpoint() {
return endpoint;
}

View File

@ -29,13 +29,6 @@ public class PropagationConfig implements Serializable {
*/
private String type = W3C;
public PropagationConfig() {
}
public PropagationConfig(String type) {
this.type = type;
}
public String getType() {
return type;
}

View File

@ -25,13 +25,6 @@ public class SamplingConfig implements Serializable {
*/
private float probability = 0.10f;
public SamplingConfig() {
}
public SamplingConfig(float probability) {
this.probability = probability;
}
public float getProbability() {
return this.probability;
}

View File

@ -16,12 +16,8 @@
*/
package org.apache.dubbo.rpc.service;
import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.common.utils.StringUtils;
import java.beans.Transient;
import java.io.Serializable;
/**
* GenericException
*
@ -31,169 +27,50 @@ public class GenericException extends RuntimeException {
private static final long serialVersionUID = -1182299763306599962L;
private boolean useCause;
private String exceptionClass;
private String exceptionMessage;
private final GenericExceptionInfo genericExceptionInfo;
public GenericException() {
this(null, null);
}
public GenericException(String exceptionMessage) {
super(exceptionMessage);
this.exceptionMessage = exceptionMessage;
}
public GenericException(String exceptionClass, String exceptionMessage) {
super(exceptionMessage);
this.useCause = false;
this.exceptionClass = exceptionClass;
this.exceptionMessage = exceptionMessage;
this.genericExceptionInfo = new GenericExceptionInfo(exceptionClass, exceptionMessage, exceptionMessage, getStackTrace());
}
public GenericException(Throwable cause) {
super(StringUtils.toString(cause));
this.useCause = false;
this.exceptionClass = cause.getClass().getName();
this.exceptionMessage = cause.getMessage();
this.genericExceptionInfo = new GenericExceptionInfo(this.exceptionClass, this.exceptionMessage, super.getMessage(), getStackTrace());
}
protected GenericException(GenericExceptionInfo info) {
super(info.getMsg(), null, true, false);
setStackTrace(info.getStackTrace());
this.useCause = false;
this.exceptionClass = info.getExClass();
this.exceptionMessage = info.getExMsg();
this.genericExceptionInfo = info;
public GenericException(String message, Throwable cause, String exceptionClass, String exceptionMessage) {
super(message, cause);
this.exceptionClass = exceptionClass;
this.exceptionMessage = exceptionMessage;
}
@Transient
public String getExceptionClass() {
if(this.useCause) {
return ((GenericException)getCause()).getExceptionClass();
}
return exceptionClass;
}
public void setExceptionClass(String exceptionClass) {
if(this.useCause) {
((GenericException)getCause()).setExceptionClass(exceptionClass);
return;
}
this.exceptionClass = exceptionClass;
}
@Transient
public String getExceptionMessage() {
if(this.useCause) {
return ((GenericException)getCause()).getExceptionMessage();
}
return exceptionMessage;
}
public void setExceptionMessage(String exceptionMessage) {
if(this.useCause) {
((GenericException)getCause()).setExceptionMessage(exceptionMessage);
return;
}
this.exceptionMessage = exceptionMessage;
}
@Override
@Transient
public StackTraceElement[] getStackTrace() {
if(this.useCause) {
return ((GenericException)getCause()).getStackTrace();
}
return super.getStackTrace();
}
@Override
@Transient
public String getMessage() {
if(this.useCause) {
return getCause().getMessage();
}
return JsonUtils.toJson(GenericExceptionInfo.createNoStackTrace(genericExceptionInfo));
}
public String getGenericException() {
if(this.useCause) {
return ((GenericException)getCause()).getGenericException();
}
return JsonUtils.toJson(genericExceptionInfo);
}
public void setGenericException(String json) {
GenericExceptionInfo info = JsonUtils.toJavaObject(json, GenericExceptionInfo.class);
if(info == null) {
return;
}
this.useCause = true;
initCause(new GenericException(info));
}
@Override
@Transient
public String getLocalizedMessage() {
return getMessage();
}
/**
* create generic exception info
*/
public static class GenericExceptionInfo implements Serializable {
private String exClass;
private String exMsg;
private String msg;
private StackTraceElement[] stackTrace;
public GenericExceptionInfo() {
}
public GenericExceptionInfo(String exceptionClass, String exceptionMessage, String message, StackTraceElement[] stackTrace) {
this.exClass = exceptionClass;
this.exMsg = exceptionMessage;
this.msg = message;
this.stackTrace = stackTrace;
}
public static GenericExceptionInfo createNoStackTrace(GenericExceptionInfo info) {
return new GenericExceptionInfo(info.getExClass(), info.getExMsg(), info.getMsg(), null);
}
public String getMsg() {
return msg;
}
public String getExClass() {
return exClass;
}
public String getExMsg() {
return exMsg;
}
public void setExClass(String exClass) {
this.exClass = exClass;
}
public void setExMsg(String exMsg) {
this.exMsg = exMsg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public StackTraceElement[] getStackTrace() {
return stackTrace;
}
public void setStackTrace(StackTraceElement[] stackTrace) {
this.stackTrace = stackTrace;
}
}
}

View File

@ -221,7 +221,7 @@ class ExtensionLoaderTest {
}
@Test
void test_getActivateExtension_WithWrapper() {
void test_getActivateExtension_WithWrapper1() {
URL url = URL.valueOf("test://localhost/test");
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "order");
@ -596,7 +596,7 @@ class ExtensionLoaderTest {
}
@Test
void testLoadDefaultActivateExtension() {
void testLoadDefaultActivateExtension1() {
// test default
URL url = URL.valueOf("test://localhost/test?ext=order1,default");
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
@ -620,6 +620,31 @@ class ExtensionLoaderTest {
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
}
@Test
void testLoadDefaultActivateExtension2() {
// test default
URL url = URL.valueOf("test://localhost/test?ext=order1 , default");
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, "ext", "default_group");
Assertions.assertEquals(2, list.size());
assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class);
assertSame(list.get(1).getClass(), ActivateExt1Impl1.class);
url = URL.valueOf("test://localhost/test?ext=default, order1");
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, "ext", "default_group");
Assertions.assertEquals(2, list.size());
assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
url = URL.valueOf("test://localhost/test?ext=order1");
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, "ext", "default_group");
Assertions.assertEquals(2, list.size());
assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
}
@Test
void testInjectExtension() {
// register bean for test ScopeBeanExtensionInjector

View File

@ -23,21 +23,532 @@ import org.apache.dubbo.common.constants.QosConstants;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.constants.RemotingConstants;
import java.util.concurrent.ExecutorService;
import java.util.regex.Pattern;
@Deprecated
public class Constants implements CommonConstants,
QosConstants,
FilterConstants,
RegistryConstants,
RemotingConstants,
org.apache.dubbo.config.Constants,
org.apache.dubbo.remoting.Constants,
org.apache.dubbo.rpc.cluster.Constants,
org.apache.dubbo.monitor.Constants,
org.apache.dubbo.rpc.Constants,
org.apache.dubbo.rpc.protocol.dubbo.Constants,
org.apache.dubbo.common.serialize.Constants,
org.apache.dubbo.common.config.configcenter.Constants,
org.apache.dubbo.metadata.report.support.Constants ,
org.apache.dubbo.rpc.protocol.rest.Constants,
org.apache.dubbo.registry.Constants {
QosConstants,
FilterConstants,
RegistryConstants,
RemotingConstants,
org.apache.dubbo.config.Constants,
org.apache.dubbo.remoting.Constants,
org.apache.dubbo.rpc.cluster.Constants,
org.apache.dubbo.monitor.Constants,
org.apache.dubbo.rpc.Constants,
org.apache.dubbo.rpc.protocol.dubbo.Constants,
org.apache.dubbo.common.serialize.Constants,
org.apache.dubbo.common.config.configcenter.Constants,
org.apache.dubbo.metadata.report.support.Constants,
org.apache.dubbo.rpc.protocol.rest.Constants,
org.apache.dubbo.registry.Constants {
public static final String PROVIDER = "provider";
public static final String CONSUMER = "consumer";
public static final String REGISTER = "register";
public static final String UNREGISTER = "unregister";
public static final String SUBSCRIBE = "subscribe";
public static final String UNSUBSCRIBE = "unsubscribe";
public static final String CATEGORY_KEY = "category";
public static final String PROVIDERS_CATEGORY = "providers";
public static final String CONSUMERS_CATEGORY = "consumers";
public static final String ROUTERS_CATEGORY = "routers";
public static final String CONFIGURATORS_CATEGORY = "configurators";
public static final String DEFAULT_CATEGORY = PROVIDERS_CATEGORY;
public static final String ENABLED_KEY = "enabled";
public static final String DISABLED_KEY = "disabled";
public static final String VALIDATION_KEY = "validation";
public static final String CACHE_KEY = "cache";
public static final String DYNAMIC_KEY = "dynamic";
public static final String DUBBO_PROPERTIES_KEY = "dubbo.properties.file";
public static final String DEFAULT_DUBBO_PROPERTIES = "dubbo.properties";
public static final String SENT_KEY = "sent";
public static final boolean DEFAULT_SENT = false;
public static final String REGISTRY_PROTOCOL = "registry";
public static final String $INVOKE = "$invoke";
public static final String $ECHO = "$echo";
public static final int DEFAULT_IO_THREADS = Runtime.getRuntime()
.availableProcessors() + 1;
public static final String DEFAULT_PROXY = "javassist";
public static final int DEFAULT_PAYLOAD = 8 * 1024 * 1024;
public static final String DEFAULT_CLUSTER = "failover";
public static final String DEFAULT_DIRECTORY = "dubbo";
public static final String DEFAULT_LOADBALANCE = "random";
public static final String DEFAULT_PROTOCOL = "dubbo";
public static final String DEFAULT_EXCHANGER = "header";
public static final String DEFAULT_TRANSPORTER = "netty";
public static final String DEFAULT_REMOTING_SERVER = "netty";
public static final String DEFAULT_REMOTING_CLIENT = "netty";
public static final String DEFAULT_REMOTING_CODEC = "dubbo";
public static final String DEFAULT_REMOTING_SERIALIZATION = "hessian2";
public static final String DEFAULT_HTTP_SERVER = "servlet";
public static final String DEFAULT_HTTP_CLIENT = "jdk";
public static final String DEFAULT_HTTP_SERIALIZATION = "json";
public static final String DEFAULT_CHARSET = "UTF-8";
public static final int DEFAULT_WEIGHT = 100;
public static final int DEFAULT_FORKS = 2;
public static final String DEFAULT_THREAD_NAME = "Dubbo";
public static final int DEFAULT_CORE_THREADS = 0;
public static final int DEFAULT_THREADS = 200;
public static final int DEFAULT_QUEUES = 0;
public static final int DEFAULT_ALIVE = 60 * 1000;
public static final int DEFAULT_CONNECTIONS = 0;
public static final int DEFAULT_ACCEPTS = 0;
public static final int DEFAULT_IDLE_TIMEOUT = 600 * 1000;
public static final int DEFAULT_HEARTBEAT = 60 * 1000;
public static final int DEFAULT_TIMEOUT = 1000;
public static final int DEFAULT_CONNECT_TIMEOUT = 3000;
public static final int DEFAULT_RETRIES = 2;
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
public static final int MAX_BUFFER_SIZE = 16 * 1024;
public static final int MIN_BUFFER_SIZE = 1 * 1024;
public static final String REMOVE_VALUE_PREFIX = "-";
public static final String HIDE_KEY_PREFIX = ".";
public static final String DEFAULT_KEY_PREFIX = "default.";
public static final String DEFAULT_KEY = "default";
public static final String LOADBALANCE_KEY = "loadbalance";
public static final String ROUTER_KEY = "router";
public static final String CLUSTER_KEY = "cluster";
public static final String REGISTRY_KEY = "registry";
public static final String MONITOR_KEY = "monitor";
public static final String SIDE_KEY = "side";
public static final String PROVIDER_SIDE = "provider";
public static final String CONSUMER_SIDE = "consumer";
public static final String DEFAULT_REGISTRY = "dubbo";
public static final String BACKUP_KEY = "backup";
public static final String DIRECTORY_KEY = "directory";
public static final String DEPRECATED_KEY = "deprecated";
public static final String ANYHOST_KEY = "anyhost";
public static final String ANYHOST_VALUE = "0.0.0.0";
public static final String LOCALHOST_KEY = "localhost";
public static final String LOCALHOST_VALUE = "127.0.0.1";
public static final String APPLICATION_KEY = "application";
public static final String LOCAL_KEY = "local";
public static final String STUB_KEY = "stub";
public static final String MOCK_KEY = "mock";
public static final String PROTOCOL_KEY = "protocol";
public static final String PROXY_KEY = "proxy";
public static final String WEIGHT_KEY = "weight";
public static final String FORKS_KEY = "forks";
public static final String DEFAULT_THREADPOOL = "limited";
public static final String DEFAULT_CLIENT_THREADPOOL = "cached";
public static final String THREADPOOL_KEY = "threadpool";
public static final String THREAD_NAME_KEY = "threadname";
public static final String IO_THREADS_KEY = "iothreads";
public static final String CORE_THREADS_KEY = "corethreads";
public static final String THREADS_KEY = "threads";
public static final String QUEUES_KEY = "queues";
public static final String ALIVE_KEY = "alive";
public static final String EXECUTES_KEY = "executes";
public static final String BUFFER_KEY = "buffer";
public static final String PAYLOAD_KEY = "payload";
public static final String REFERENCE_FILTER_KEY = "reference.filter";
public static final String INVOKER_LISTENER_KEY = "invoker.listener";
public static final String SERVICE_FILTER_KEY = "service.filter";
public static final String EXPORTER_LISTENER_KEY = "exporter.listener";
public static final String ACCESS_LOG_KEY = "accesslog";
public static final String ACTIVES_KEY = "actives";
public static final String CONNECTIONS_KEY = "connections";
public static final String ACCEPTS_KEY = "accepts";
public static final String IDLE_TIMEOUT_KEY = "idle.timeout";
public static final String HEARTBEAT_KEY = "heartbeat";
public static final String HEARTBEAT_TIMEOUT_KEY = "heartbeat.timeout";
public static final String CONNECT_TIMEOUT_KEY = "connect.timeout";
public static final String TIMEOUT_KEY = "timeout";
public static final String RETRIES_KEY = "retries";
public static final String PROMPT_KEY = "prompt";
public static final String DEFAULT_PROMPT = "dubbo>";
public static final String CODEC_KEY = "codec";
public static final String SERIALIZATION_KEY = "serialization";
public static final String EXCHANGER_KEY = "exchanger";
public static final String TRANSPORTER_KEY = "transporter";
public static final String SERVER_KEY = "server";
public static final String CLIENT_KEY = "client";
public static final String ID_KEY = "id";
public static final String ASYNC_KEY = "async";
public static final String RETURN_KEY = "return";
public static final String TOKEN_KEY = "token";
public static final String METHOD_KEY = "method";
public static final String METHODS_KEY = "methods";
public static final String CHARSET_KEY = "charset";
public static final String RECONNECT_KEY = "reconnect";
public static final String SEND_RECONNECT_KEY = "send.reconnect";
public static final int DEFAULT_RECONNECT_PERIOD = 2000;
public static final String SHUTDOWN_TIMEOUT_KEY = "shutdown.timeout";
public static final int DEFAULT_SHUTDOWN_TIMEOUT = 1000 * 60 * 15;
public static final String PID_KEY = "pid";
public static final String TIMESTAMP_KEY = "timestamp";
public static final String WARMUP_KEY = "warmup";
public static final int DEFAULT_WARMUP = 10 * 60 * 1000;
public static final String CHECK_KEY = "check";
public static final String REGISTER_KEY = "register";
public static final String SUBSCRIBE_KEY = "subscribe";
public static final String GROUP_KEY = "group";
public static final String PATH_KEY = "path";
public static final String INTERFACE_KEY = "interface";
public static final String GENERIC_KEY = "generic";
public static final String FILE_KEY = "file";
public static final String WAIT_KEY = "wait";
public static final String CLASSIFIER_KEY = "classifier";
public static final String VERSION_KEY = "version";
public static final String REVISION_KEY = "revision";
public static final String DUBBO_VERSION_KEY = "dubbo";
public static final String HESSIAN_VERSION_KEY = "hessian.version";
public static final String DISPATCHER_KEY = "dispatcher";
public static final String CHANNEL_HANDLER_KEY = "channel.handler";
public static final String DEFAULT_CHANNEL_HANDLER = "default";
public static final String ANY_VALUE = "*";
public static final String COMMA_SEPARATOR = ",";
public static final Pattern COMMA_SPLIT_PATTERN = Pattern
.compile("\\s*[,]+\\s*");
public final static String PATH_SEPARATOR = "/";
public static final String REGISTRY_SEPARATOR = "|";
public static final Pattern REGISTRY_SPLIT_PATTERN = Pattern
.compile("\\s*[|;]+\\s*");
public static final String SEMICOLON_SEPARATOR = ";";
public static final Pattern SEMICOLON_SPLIT_PATTERN = Pattern
.compile("\\s*[;]+\\s*");
public static final String CONNECT_QUEUE_CAPACITY = "connect.queue.capacity";
public static final String CONNECT_QUEUE_WARNING_SIZE = "connect.queue.warning.size";
public static final int DEFAULT_CONNECT_QUEUE_WARNING_SIZE = 1000;
public static final String CHANNEL_ATTRIBUTE_READONLY_KEY = "channel.readonly";
public static final String CHANNEL_READONLYEVENT_SENT_KEY = "channel.readonly.sent";
public static final String CHANNEL_SEND_READONLYEVENT_KEY = "channel.readonly.send";
public static final String COUNT_PROTOCOL = "count";
public static final String TRACE_PROTOCOL = "trace";
public static final String EMPTY_PROTOCOL = "empty";
public static final String ADMIN_PROTOCOL = "admin";
public static final String PROVIDER_PROTOCOL = "provider";
public static final String CONSUMER_PROTOCOL = "consumer";
public static final String ROUTE_PROTOCOL = "route";
public static final String SCRIPT_PROTOCOL = "script";
public static final String CONDITION_PROTOCOL = "condition";
public static final String MOCK_PROTOCOL = "mock";
public static final String RETURN_PREFIX = "return ";
public static final String THROW_PREFIX = "throw";
public static final String FAIL_PREFIX = "fail:";
public static final String FORCE_PREFIX = "force:";
public static final String FORCE_KEY = "force";
public static final String MERGER_KEY = "merger";
public static final String CLUSTER_AVAILABLE_CHECK_KEY = "cluster.availablecheck";
public static final boolean DEFAULT_CLUSTER_AVAILABLE_CHECK = true;
public static final String CLUSTER_STICKY_KEY = "sticky";
public static final boolean DEFAULT_CLUSTER_STICKY = false;
public static final String LAZY_CONNECT_KEY = "lazy";
public static final String LAZY_CONNECT_INITIAL_STATE_KEY = "connect.lazy.initial.state";
public static final boolean DEFAULT_LAZY_CONNECT_INITIAL_STATE = true;
public static final String REGISTRY_FILESAVE_SYNC_KEY = "save.file";
public static final String REGISTRY_RETRY_PERIOD_KEY = "retry.period";
public static final int DEFAULT_REGISTRY_RETRY_PERIOD = 5 * 1000;
public static final String REGISTRY_RECONNECT_PERIOD_KEY = "reconnect.period";
public static final int DEFAULT_REGISTRY_RECONNECT_PERIOD = 3 * 1000;
public static final String SESSION_TIMEOUT_KEY = "session";
public static final int DEFAULT_SESSION_TIMEOUT = 60 * 1000;
public static final String EXPORT_KEY = "export";
public static final String REFER_KEY = "refer";
public static final String CALLBACK_SERVICE_KEY = "callback.service.instid";
public static final String CALLBACK_INSTANCES_LIMIT_KEY = "callbacks";
public static final int DEFAULT_CALLBACK_INSTANCES = 1;
public static final String CALLBACK_SERVICE_PROXY_KEY = "callback.service.proxy";
public static final String IS_CALLBACK_SERVICE = "is_callback_service";
public static final String CHANNEL_CALLBACK_KEY = "channel.callback.invokers.key";
@Deprecated
public static final String SHUTDOWN_WAIT_SECONDS_KEY = "dubbo.service.shutdown.wait.seconds";
public static final String SHUTDOWN_WAIT_KEY = "dubbo.service.shutdown.wait";
public static final String IS_SERVER_KEY = "isserver";
public static final int DEFAULT_SERVER_SHUTDOWN_TIMEOUT = 10000;
public static final String ON_CONNECT_KEY = "onconnect";
public static final String ON_DISCONNECT_KEY = "ondisconnect";
public static final String ON_INVOKE_METHOD_KEY = "oninvoke.method";
public static final String ON_RETURN_METHOD_KEY = "onreturn.method";
public static final String ON_THROW_METHOD_KEY = "onthrow.method";
public static final String ON_INVOKE_INSTANCE_KEY = "oninvoke.instance";
public static final String ON_RETURN_INSTANCE_KEY = "onreturn.instance";
public static final String ON_THROW_INSTANCE_KEY = "onthrow.instance";
public static final String OVERRIDE_PROTOCOL = "override";
public static final String PRIORITY_KEY = "priority";
public static final String RULE_KEY = "rule";
public static final String TYPE_KEY = "type";
public static final String RUNTIME_KEY = "runtime";
public static final String ROUTER_TYPE_CLEAR = "clean";
public static final String DEFAULT_SCRIPT_TYPE_KEY = "javascript";
public static final String STUB_EVENT_KEY = "dubbo.stub.event";
public static final boolean DEFAULT_STUB_EVENT = false;
public static final String STUB_EVENT_METHODS_KEY = "dubbo.stub.event.methods";
public static final String INVOCATION_NEED_MOCK = "invocation.need.mock";
public static final String LOCAL_PROTOCOL = "injvm";
public static final String AUTO_ATTACH_INVOCATIONID_KEY = "invocationid.autoattach";
public static final String SCOPE_KEY = "scope";
public static final String SCOPE_LOCAL = "local";
public static final String SCOPE_REMOTE = "remote";
public static final String SCOPE_NONE = "none";
public static final String RELIABLE_PROTOCOL = "napoli";
public static final String TPS_LIMIT_RATE_KEY = "tps";
public static final String TPS_LIMIT_INTERVAL_KEY = "tps.interval";
public static final long DEFAULT_TPS_LIMIT_INTERVAL = 60 * 1000;
public static final String DECODE_IN_IO_THREAD_KEY = "decode.in.io";
public static final boolean DEFAULT_DECODE_IN_IO_THREAD = true;
public static final String INPUT_KEY = "input";
public static final String OUTPUT_KEY = "output";
public static final String EXECUTOR_SERVICE_COMPONENT_KEY = ExecutorService.class.getName();
public static final String GENERIC_SERIALIZATION_NATIVE_JAVA = "nativejava";
public static final String GENERIC_SERIALIZATION_DEFAULT = "true";
public static final String INVOKER_CONNECTED_KEY = "connected";
public static final String INVOKER_INSIDE_INVOKERS_KEY = "inside.invokers";
public static final String INVOKER_INSIDE_INVOKER_COUNT_KEY = "inside.invoker.count";
public static final String CLUSTER_SWITCH_FACTOR = "cluster.switch.factor";
public static final String CLUSTER_SWITCH_LOG_ERROR = "cluster.switch.log.error";
public static final double DEFAULT_CLUSTER_SWITCH_FACTOR = 2;
public static final String DISPATHER_KEY = "dispather";
}

View File

@ -17,14 +17,15 @@
package com.alibaba.dubbo.rpc;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.beans.Transient;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.apache.dubbo.rpc.model.ServiceModel;
@Deprecated
public interface Invocation extends org.apache.dubbo.rpc.Invocation {
@ -184,6 +185,7 @@ public interface Invocation extends org.apache.dubbo.rpc.Invocation {
}
@Override
@Transient
public Invoker<?> getInvoker() {
return new Invoker.CompatibleInvoker(delegate.getInvoker());
}

View File

@ -37,6 +37,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
@Deprecated
public class RpcContext {
@ -320,6 +321,25 @@ public class RpcContext {
return isConsumerSide();
}
@Deprecated
public Invoker<?> getInvoker() {
org.apache.dubbo.rpc.Invoker<?> invoker = newRpcContext.getInvoker();
if (invoker == null) {
return null;
}
return new Invoker.CompatibleInvoker<>(invoker);
}
@Deprecated
public List<Invoker<?>> getInvokers() {
List<org.apache.dubbo.rpc.Invoker<?>> invokers = newRpcContext.getInvokers();
if (CollectionUtils.isEmpty(invokers)) {
return Collections.emptyList();
}
return invokers.stream()
.map(Invoker.CompatibleInvoker::new)
.collect(Collectors.toList());
}
/**
* Async invocation. Timeout will be handled even if <code>Future.get()</code> is not called.
*

View File

@ -17,6 +17,10 @@
package com.alibaba.dubbo.rpc;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import java.beans.Transient;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;
@ -24,9 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
@Deprecated
public class RpcInvocation implements Invocation, Serializable {
private static final long serialVersionUID = -4355285085441097045L;
@ -101,6 +103,7 @@ public class RpcInvocation implements Invocation, Serializable {
this.invoker = invoker;
}
@Transient
public Invoker<?> getInvoker() {
return invoker;
}

View File

@ -72,12 +72,6 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-api</artifactId>

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.constants.RegisterTypeEnum;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -57,11 +58,14 @@ import java.beans.Transient;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -148,7 +152,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
/**
* The exported services
*/
private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
private final Map<RegisterTypeEnum, List<Exporter<?>>> exporters = new ConcurrentHashMap<>();
private final List<ServiceListener> serviceListeners = new ArrayList<>();
@ -196,19 +200,23 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
return;
}
if (!exporters.isEmpty()) {
for (Exporter<?> exporter : exporters) {
try {
exporter.unregister();
} catch (Throwable t) {
logger.warn(CONFIG_UNEXPORT_ERROR, "", "", "Unexpected error occurred when unexport " + exporter, t);
for (List<Exporter<?>> es : exporters.values()) {
for (Exporter<?> exporter : es) {
try {
exporter.unregister();
} catch (Throwable t) {
logger.warn(CONFIG_UNEXPORT_ERROR, "", "", "Unexpected error occurred when unexport " + exporter, t);
}
}
}
waitForIdle();
for (Exporter<?> exporter : exporters) {
try {
exporter.unexport();
} catch (Throwable t) {
logger.warn(CONFIG_UNEXPORT_ERROR, "", "", "Unexpected error occurred when unexport " + exporter, t);
for (List<Exporter<?>> es : exporters.values()) {
for (Exporter<?> exporter : es) {
try {
exporter.unexport();
} catch (Throwable t) {
logger.warn(CONFIG_UNEXPORT_ERROR, "", "", "Unexpected error occurred when unexport " + exporter, t);
}
}
}
exporters.clear();
@ -280,7 +288,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
}
@Override
public void export(boolean register) {
public void export(RegisterTypeEnum registerType) {
if (this.exported) {
return;
}
@ -301,16 +309,19 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
if (shouldDelay()) {
// should register if delay export
doDelayExport(true);
doDelayExport();
} else if (Integer.valueOf(-1).equals(getDelay())) {
// should not register by default
doExport(RegisterTypeEnum.MANUAL_REGISTER);
} else {
doExport(register);
doExport(registerType);
}
}
}
}
@Override
public void register() {
public void register(boolean byDeployer) {
if (!this.exported) {
return;
}
@ -320,17 +331,23 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
return;
}
for (Exporter<?> exporter : exporters) {
for (Exporter<?> exporter : exporters.getOrDefault(RegisterTypeEnum.AUTO_REGISTER, Collections.emptyList())) {
exporter.register();
}
if (byDeployer) {
for (Exporter<?> exporter : exporters.getOrDefault(RegisterTypeEnum.AUTO_REGISTER_BY_DEPLOYER, Collections.emptyList())) {
exporter.register();
}
}
}
}
protected void doDelayExport(boolean register) {
protected void doDelayExport() {
ExecutorRepository.getInstance(getScopeModel().getApplicationModel()).getServiceExportExecutor()
.schedule(() -> {
try {
doExport(register);
doExport(RegisterTypeEnum.AUTO_REGISTER);
} catch (Exception e) {
logger.error(CONFIG_FAILED_EXPORT_SERVICE, "configuration server disconnected", "", "Failed to (async)export service config: " + interfaceName, e);
}
@ -457,7 +474,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
checkAndUpdateSubConfigs();
}
protected synchronized void doExport(boolean register) {
protected synchronized void doExport(RegisterTypeEnum registerType) {
if (unexported) {
throw new IllegalStateException("The service " + interfaceClass.getName() + " has already unexported!");
}
@ -468,12 +485,12 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
if (StringUtils.isEmpty(path)) {
path = interfaceName;
}
doExportUrls(register);
doExportUrls(registerType);
exported();
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void doExportUrls(boolean register) {
private void doExportUrls(RegisterTypeEnum registerType) {
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
ServiceDescriptor serviceDescriptor;
final boolean serverService = ref instanceof ServerService;
@ -505,10 +522,10 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
.orElse(path), group, version);
// stub service will use generated service name
if (!serverService) {
// In case user specified path, register service one more time to map it to path.
// In case user specified path, registerImmediately service one more time to map it to path.
repository.registerService(pathKey, interfaceClass);
}
doExportUrlsFor1Protocol(protocolConfig, registryURLs, register);
doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType);
}
return null;
}
@ -517,7 +534,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
providerModel.setServiceUrls(urls);
}
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs, boolean register) {
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs, RegisterTypeEnum registerType) {
Map<String, String> map = buildAttributes(protocolConfig);
// remove null key and null value
@ -529,7 +546,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
processServiceExecutor(url);
exportUrl(url, registryURLs, register);
exportUrl(url, registryURLs, registerType);
}
private void processServiceExecutor(URL url) {
@ -711,7 +728,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
return url;
}
private void exportUrl(URL url, List<URL> registryURLs, boolean register) {
private void exportUrl(URL url, List<URL> registryURLs, RegisterTypeEnum registerType) {
String scope = url.getParameter(SCOPE_KEY);
// don't export when none is configured
if (!SCOPE_NONE.equalsIgnoreCase(scope)) {
@ -735,7 +752,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
build();
}
url = exportRemote(url, registryURLs, register);
url = exportRemote(url, registryURLs, registerType);
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
MetadataUtils.publishServiceDefinition(url, providerModel.getServiceModel(), getApplicationModel());
}
@ -750,7 +767,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
URL localUrl = URLBuilder.from(url).
setProtocol(protocol).
build();
localUrl = exportRemote(localUrl, registryURLs, register);
localUrl = exportRemote(localUrl, registryURLs, registerType);
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
MetadataUtils.publishServiceDefinition(localUrl, providerModel.getServiceModel(), getApplicationModel());
}
@ -762,8 +779,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
this.urls.add(url);
}
private URL exportRemote(URL url, List<URL> registryURLs, boolean register) {
if (CollectionUtils.isNotEmpty(registryURLs)) {
private URL exportRemote(URL url, List<URL> registryURLs, RegisterTypeEnum registerType) {
if (CollectionUtils.isNotEmpty(registryURLs) && registerType != RegisterTypeEnum.NEVER_REGISTER) {
for (URL registryURL : registryURLs) {
if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) {
url = url.addParameterIfAbsent(SERVICE_NAME_MAPPING_KEY, "true");
@ -794,7 +811,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
}
}
doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true, register);
doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true, registerType);
}
} else {
@ -803,7 +820,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
}
doExportUrl(url, true, register);
doExportUrl(url, true, registerType);
}
@ -811,16 +828,22 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void doExportUrl(URL url, boolean withMetaData, boolean register) {
if (!register) {
private void doExportUrl(URL url, boolean withMetaData, RegisterTypeEnum registerType) {
if (!url.getParameter(REGISTER_KEY, true)) {
registerType = RegisterTypeEnum.MANUAL_REGISTER;
}
if (registerType == RegisterTypeEnum.NEVER_REGISTER ||
registerType == RegisterTypeEnum.MANUAL_REGISTER ||
registerType == RegisterTypeEnum.AUTO_REGISTER_BY_DEPLOYER) {
url = url.addParameter(REGISTER_KEY, false);
}
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
if (withMetaData) {
invoker = new DelegateProviderMetaDataInvoker(invoker, this);
}
Exporter<?> exporter = protocolSPI.export(invoker);
exporters.add(exporter);
exporters.computeIfAbsent(registerType, k -> new CopyOnWriteArrayList<>()).add(exporter);
}
@ -836,7 +859,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
local = local.setScopeModel(getScopeModel())
.setServiceModel(providerModel);
local = local.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL);
doExportUrl(local, false, true);
doExportUrl(local, false, RegisterTypeEnum.AUTO_REGISTER);
logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry url : " + local);
}

View File

@ -38,6 +38,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
@ -46,7 +47,6 @@ import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.MetricsConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.utils.CompositeReferenceCache;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
@ -60,7 +60,6 @@ import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory;
import org.apache.dubbo.metrics.report.MetricsReporter;
import org.apache.dubbo.metrics.report.MetricsReporterFactory;
import org.apache.dubbo.metrics.service.MetricsServiceExporter;
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
@ -71,8 +70,6 @@ import org.apache.dubbo.rpc.model.ModuleServiceRepository;
import org.apache.dubbo.rpc.model.ProviderModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.tracing.DubboObservationRegistry;
import org.apache.dubbo.tracing.utils.ObservationSupportUtil;
import java.io.IOException;
import java.util.ArrayList;
@ -155,7 +152,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// load spi listener
Set<ApplicationDeployListener> deployListeners = applicationModel.getExtensionLoader(ApplicationDeployListener.class)
.getSupportedExtensionInstances();
.getSupportedExtensionInstances();
for (ApplicationDeployListener listener : deployListeners) {
this.addDeployListener(listener);
}
@ -229,9 +226,6 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
initMetricsService();
// @since 3.2.3
initObservationRegistry();
// @since 2.7.8
startMetadataCenter();
@ -358,17 +352,17 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
if (defaultRegistries.size() > 0) {
defaultRegistries
.stream()
.filter(this::isUsedRegistryAsConfigCenter)
.map(this::registryAsConfigCenter)
.forEach(configCenter -> {
if (configManager.getConfigCenter(configCenter.getId()).isPresent()) {
return;
}
configManager.addConfigCenter(configCenter);
logger.info("use registry as config-center: " + configCenter);
.stream()
.filter(this::isUsedRegistryAsConfigCenter)
.map(this::registryAsConfigCenter)
.forEach(configCenter -> {
if (configManager.getConfigCenter(configCenter.getId()).isPresent()) {
return;
}
configManager.addConfigCenter(configCenter);
logger.info("use registry as config-center: " + configCenter);
});
});
}
}
@ -378,16 +372,16 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
private void initMetricsReporter() {
if (!MetricsSupportUtil.isSupportMetrics()) {
if (!isSupportMetrics()) {
return;
}
DefaultMetricsCollector collector =
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
Optional<MetricsConfig> configOptional = configManager.getMetrics();
//If no specific metrics type is configured and there is no Prometheus dependency in the dependencies.
MetricsConfig metricsConfig = configOptional.orElse(new MetricsConfig(applicationModel));
if (StringUtils.isBlank(metricsConfig.getProtocol())) {
metricsConfig.setProtocol(MetricsSupportUtil.isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
metricsConfig.setProtocol(isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
}
collector.setCollectEnabled(true);
collector.collectApplication();
@ -415,35 +409,26 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
}
/**
* init ObservationRegistry(Micrometer)
*/
private void initObservationRegistry() {
if (!ObservationSupportUtil.isSupportObservation()) {
if (logger.isDebugEnabled()) {
logger.debug("Not found micrometer-observation or plz check the version of micrometer-observation version if already introduced, need > 1.10.0");
}
return;
}
if (!ObservationSupportUtil.isSupportTracing()) {
if (logger.isDebugEnabled()) {
logger.debug("Not found micrometer-tracing dependency, skip init ObservationRegistry.");
}
return;
}
Optional<TracingConfig> configOptional = configManager.getTracing();
if (!configOptional.isPresent() || !configOptional.get().getEnabled()) {
return;
}
public boolean isSupportMetrics() {
return isClassPresent("io.micrometer.core.instrument.MeterRegistry");
}
DubboObservationRegistry dubboObservationRegistry = new DubboObservationRegistry(applicationModel, configOptional.get());
dubboObservationRegistry.initObservationRegistry();
public static boolean isSupportPrometheus() {
return isClassPresent("io.micrometer.prometheus.PrometheusConfig")
&& isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory")
&& isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory")
&& isClassPresent("io.prometheus.client.exporter.PushGateway");
}
private static boolean isClassPresent(String className) {
return ClassUtils.isPresent(className, DefaultApplicationDeployer.class.getClassLoader());
}
private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) {
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsConfigCenter, "config",
DynamicConfigurationFactory.class);
DynamicConfigurationFactory.class);
}
private ConfigCenterConfig registryAsConfigCenter(RegistryConfig registryConfig) {
@ -485,9 +470,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
Collection<MetadataReportConfig> metadataConfigsToOverride = originMetadataConfigs
.stream()
.filter(m -> Objects.isNull(m.getAddress()))
.collect(Collectors.toList());
.stream()
.filter(m -> Objects.isNull(m.getAddress()))
.collect(Collectors.toList());
if (metadataConfigsToOverride.size() > 1) {
return;
@ -498,12 +483,12 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
if (!defaultRegistries.isEmpty()) {
defaultRegistries
.stream()
.filter(this::isUsedRegistryAsMetadataCenter)
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
.forEach(metadataReportConfig -> {
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
});
.stream()
.filter(this::isUsedRegistryAsMetadataCenter)
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
.forEach(metadataReportConfig -> {
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
});
}
}
@ -532,7 +517,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsMetadataCenter, "metadata",
MetadataReportFactory.class);
MetadataReportFactory.class);
}
/**
@ -558,13 +543,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
supported = supportsExtension(extensionClass, protocol);
if (logger.isInfoEnabled()) {
logger.info(format("No value is configured in the registry, the %s extension[name : %s] %s as the %s center"
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
}
}
if (logger.isInfoEnabled()) {
logger.info(format("The registry[%s] will be %s as the %s center", registryConfig,
supported ? "used" : "not used", centerType));
supported ? "used" : "not used", centerType));
}
return supported;
}
@ -587,7 +572,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig, MetadataReportConfig originMetadataReportConfig) {
MetadataReportConfig metadataReportConfig = originMetadataReportConfig == null ?
new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig;
new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig;
if (metadataReportConfig.getId() == null) {
metadataReportConfig.setId(registryConfig.getId());
}
@ -790,13 +775,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private void exportMetricsService() {
boolean exportMetrics = applicationModel.getApplicationConfigManager().getMetrics()
.map(MetricsConfig::getExportMetricsService).orElse(true);
.map(MetricsConfig::getExportMetricsService).orElse(true);
if (exportMetrics) {
try {
metricsServiceExporter.export();
} catch (Exception e) {
logger.error(LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION, "", "",
"exportMetricsService an exception occurred when handle starting event", e);
"exportMetricsService an exception occurred when handle starting event", e);
}
}
}
@ -874,10 +859,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// Add metrics
MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, configCenter.getConfigFile(), configCenter.getGroup(),
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size()));
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size()));
if (isNotEmpty(appGroup)) {
MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, appConfigFile, appGroup,
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size()));
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size()));
}
} catch (IOException e) {
throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
@ -915,10 +900,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
try {
registered = true;
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel),
() -> {
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
return null;
}
() -> {
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
return null;
}
);
} catch (Exception e) {
logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e);
@ -1032,7 +1017,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private void doOffline(ProviderModel.RegisterStatedURL statedURL) {
RegistryFactory registryFactory =
statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
registry.unregister(statedURL.getProviderUrl());
statedURL.setRegistered(false);

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.config.deploy;
import org.apache.dubbo.common.config.ReferenceCache;
import org.apache.dubbo.common.constants.LoggerCodeConstants;
import org.apache.dubbo.common.constants.RegisterTypeEnum;
import org.apache.dubbo.common.deploy.AbstractDeployer;
import org.apache.dubbo.common.deploy.ApplicationDeployer;
import org.apache.dubbo.common.deploy.DeployListener;
@ -427,7 +428,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
asyncExportingFutures.add(future);
} else {
if (!sc.isExported()) {
sc.export(false);
sc.export(RegisterTypeEnum.AUTO_REGISTER_BY_DEPLOYER);
exportedServices.add(sc);
}
}
@ -441,7 +442,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
if (!sc.isExported()) {
return;
}
sc.register();
sc.register(true);
}
private void unexportServices() {

View File

@ -670,8 +670,9 @@ public class ConfigValidationUtils {
if (isNotEmpty(value)) {
String[] values = value.split("\\s*[,]+\\s*");
for (String v : values) {
v = StringUtils.trim(v);
if (v.startsWith(REMOVE_VALUE_PREFIX)) {
v = v.substring(1);
continue;
}
if (DEFAULT_KEY.equals(v)) {
continue;

View File

@ -207,8 +207,25 @@ class AbstractConfigTest {
@Test
void checkMultiExtension2() {
try {
ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world");
} catch (Throwable t) {
Assertions.fail(t);
}
}
@Test
void checkMultiExtension3() {
Assertions.assertThrows(IllegalStateException.class,
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world"));
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , world"));
}
@Test
void checkMultiExtension4() {
try {
ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , -world ");
} catch (Throwable t) {
Assertions.fail(t);
}
}
@Test

View File

@ -18,7 +18,7 @@
package org.apache.dubbo.config.deploy;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Test;
@ -26,7 +26,7 @@ class DefaultApplicationDeployerTest {
@Test
void isSupportPrometheus() {
boolean supportPrometheus = MetricsSupportUtil.isSupportPrometheus();
Assert.assertTrue(supportPrometheus, "MetricsSupportUtil.isSupportPrometheus() should return true");
boolean supportPrometheus = new DefaultApplicationDeployer(ApplicationModel.defaultModel()).isSupportPrometheus();
Assert.assertTrue(supportPrometheus,"DefaultApplicationDeployer.isSupportPrometheus() should return true");
}
}

View File

@ -188,7 +188,7 @@ class MultipleRegistryCenterExportProviderIntegrationTest implements Integration
// 1. InjvmExporter
// 2. DubboExporter with service-discovery-registry protocol
// 3. DubboExporter with registry protocol
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 7);
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 4);
// The exported exporter contains MultipleRegistryCenterExportProviderFilter
Assertions.assertTrue(exporterListener.getFilters().contains(filter));

View File

@ -195,7 +195,7 @@ class SingleRegistryCenterExportProviderIntegrationTest implements IntegrationTe
// 1. InjvmExporter
// 2. DubboExporter with service-discovery-registry protocol
// 3. DubboExporter with registry protocol
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 5);
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 4);
// The exported exporter contains SingleRegistryCenterExportProviderFilter
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
// The consumer can be notified and get provider's metadata through metadata mapping info.

View File

@ -224,7 +224,7 @@
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.22</version>
<version>0.9.23</version>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>

View File

@ -222,7 +222,7 @@
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.22</version>
<version>0.9.23</version>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>

View File

@ -38,7 +38,7 @@
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot.version>2.7.12</spring-boot.version>
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
<micrometer-core.version>1.11.0</micrometer-core.version>
<micrometer-core.version>1.11.1</micrometer-core.version>
</properties>
<dependencyManagement>
<dependencies>

View File

@ -114,7 +114,7 @@
<cxf_version>3.5.5</cxf_version>
<thrift_version>0.18.1</thrift_version>
<hessian_version>4.0.66</hessian_version>
<protobuf-java_version>3.23.2</protobuf-java_version>
<protobuf-java_version>3.23.3</protobuf-java_version>
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
<servlet_version>3.1.0</servlet_version>
<jetty_version>9.4.51.v20230217</jetty_version>
@ -133,14 +133,13 @@
<commons_lang3_version>3.12.0</commons_lang3_version>
<protostuff_version>1.8.0</protostuff_version>
<envoy_api_version>0.1.35</envoy_api_version>
<micrometer.version>1.11.0</micrometer.version>
<opentelemetry.version>1.26.0</opentelemetry.version>
<zipkin-reporter.version>2.16.4</zipkin-reporter.version>
<micrometer-tracing.version>1.1.1</micrometer-tracing.version>
<micrometer.version>1.11.1</micrometer.version>
<micrometer-tracing.version>1.1.2</micrometer-tracing.version>
<t_digest.version>3.3</t_digest.version>
<prometheus_client.version>0.16.0</prometheus_client.version>
<reactive.version>1.0.4</reactive.version>
<reactor.version>3.5.6</reactor.version>
<reactor.version>3.5.7</reactor.version>
<rxjava.version>2.2.21</rxjava.version>
<okhttp_version>3.14.9</okhttp_version>
@ -150,7 +149,7 @@
<tomcat_embed_version>8.5.87</tomcat_embed_version>
<jetcd_version>0.7.5</jetcd_version>
<nacos_version>2.2.3</nacos_version>
<grpc.version>1.55.1</grpc.version>
<grpc.version>1.56.0</grpc.version>
<grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
<jprotoc_version>1.2.2</jprotoc_version>
<!-- Log libs -->
@ -232,20 +231,6 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>${opentelemetry.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-bom</artifactId>
<version>${zipkin-reporter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>

View File

@ -219,15 +219,6 @@
<optional>true</optional>
</dependency>
<!-- tracing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- monitor -->
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -539,7 +530,6 @@
<include>org.apache.dubbo:dubbo-metrics-metadata</include>
<include>org.apache.dubbo:dubbo-metrics-config-center</include>
<include>org.apache.dubbo:dubbo-metrics-prometheus</include>
<include>org.apache.dubbo:dubbo-tracing</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-monitor-default</include>
<include>org.apache.dubbo:dubbo-qos</include>

View File

@ -256,13 +256,6 @@
<version>${project.version}</version>
</dependency>
<!-- tracing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.version}</version>
</dependency>
<!-- monitor -->
<dependency>
<groupId>org.apache.dubbo</groupId>

View File

@ -134,7 +134,6 @@
<include>org.apache.dubbo:dubbo-metadata-api</include>
<include>org.apache.dubbo:dubbo-metrics-api</include>
<include>org.apache.dubbo:dubbo-metrics-default</include>
<include>org.apache.dubbo:dubbo-tracing</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-registry-api</include>
<include>org.apache.dubbo:dubbo-remoting-api</include>

View File

@ -97,4 +97,8 @@ public class MetadataIdentifier extends BaseServiceMetadataIdentifier implements
this.application = application;
}
public String getUniqueServiceName() {
return serviceInterface != null ? URL.buildKey(serviceInterface, getGroup(), getVersion()) : null;
}
}

View File

@ -279,7 +279,7 @@ public abstract class AbstractMetadataReport implements MetadataReport {
private void storeProviderMetadataTask(MetadataIdentifier providerMetadataIdentifier, ServiceDefinition serviceDefinition) {
MetadataEvent metadataEvent = MetadataEvent.toServiceSubscribeEvent(applicationModel, serviceDefinition.getCanonicalName());
MetadataEvent metadataEvent = MetadataEvent.toServiceSubscribeEvent(applicationModel, providerMetadataIdentifier.getUniqueServiceName());
MetricsEventBus.post(metadataEvent, () ->
{
boolean result = true;

View File

@ -49,5 +49,10 @@
<groupId>com.tdunning</groupId>
<artifactId>t-digest</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import io.micrometer.common.KeyValues;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.Nullable;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.support.RpcUtils;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_METHOD;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SERVICE;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SYSTEM;
import io.micrometer.common.KeyValues;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.Nullable;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_METHOD;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SERVICE;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SYSTEM;
class AbstractDefaultDubboObservationConvention {
KeyValues getLowCardinalityKeyValues(Invocation invocation) {

View File

@ -14,20 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcContextAttachment;
import org.apache.dubbo.tracing.context.DubboClientContext;
import io.micrometer.common.KeyValues;
import java.util.List;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT;
/**
* Default implementation of the {@link DubboClientObservationConvention}.

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboServerContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.KeyValues;

View File

@ -14,14 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.context;
package org.apache.dubbo.metrics.observation;
import java.util.Objects;
import io.micrometer.observation.transport.SenderContext;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import io.micrometer.observation.transport.SenderContext;
import java.util.Objects;
/**
* Provider context for RPC.
*/

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboClientContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.NonNullApi;

View File

@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.context;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.transport.ReceiverContext;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import io.micrometer.observation.transport.ReceiverContext;
/**
* Consumer context for RPC.
*/

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboServerContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;

View File

@ -1,38 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.metrics.utils;
import org.apache.dubbo.common.utils.ClassUtils;
public class MetricsSupportUtil {
public static boolean isSupportMetrics() {
return isClassPresent("io.micrometer.core.instrument.MeterRegistry");
}
public static boolean isSupportPrometheus() {
return isClassPresent("io.micrometer.prometheus.PrometheusConfig")
&& isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory")
&& isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory")
&& isClassPresent("io.prometheus.client.exporter.PushGateway");
}
private static boolean isClassPresent(String className) {
return ClassUtils.isPresent(className, MetricsSupportUtil.class.getClassLoader());
}
}

View File

@ -17,9 +17,8 @@
package org.apache.dubbo.metrics.aggregate;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.concurrent.TimeUnit;

View File

@ -14,12 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.tracing.context.DubboClientContext;
import org.apache.dubbo.tracing.utils.ObservationConventionUtils;
import io.micrometer.common.KeyValues;
import org.junit.jupiter.api.Assertions;

View File

@ -14,13 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.tracing.context.DubboClientContext;
import org.apache.dubbo.tracing.context.DubboServerContext;
import org.apache.dubbo.tracing.utils.ObservationConventionUtils;
import io.micrometer.common.KeyValues;
import org.junit.jupiter.api.Assertions;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.utils;
package org.apache.dubbo.metrics.observation.utils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invoker;

View File

@ -41,5 +41,10 @@
<artifactId>micrometer-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.BaseFilter;
@ -25,10 +25,6 @@ import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import org.apache.dubbo.tracing.DefaultDubboServerObservationConvention;
import org.apache.dubbo.tracing.DubboObservationDocumentation;
import org.apache.dubbo.tracing.DubboServerObservationConvention;
import org.apache.dubbo.tracing.context.DubboServerContext;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
@ -38,7 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
/**
* A {@link Filter} that creates an {@link Observation} around the incoming message.
*/
@Activate(group = PROVIDER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry")
@Activate(group = PROVIDER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, ScopeModelAware {
private ObservationRegistry observationRegistry;
@ -46,8 +42,12 @@ public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, S
private DubboServerObservationConvention serverObservationConvention;
public ObservationReceiverFilter(ApplicationModel applicationModel) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class);
applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> {
if (Boolean.TRUE.equals(cfg.getEnabled())) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class);
}
});
}
@Override
@ -70,9 +70,6 @@ public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, S
if (observation == null) {
return;
}
if (appResponse != null && appResponse.hasException()) {
observation.error(appResponse.getException());
}
observation.stop();
}

View File

@ -0,0 +1,2 @@
metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter
observationreceiver=org.apache.dubbo.metrics.observation.ObservationReceiverFilter

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.TracingConfig;
@ -24,7 +24,6 @@ import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.MockInvocation;
import io.micrometer.tracing.test.SampleTestRunner;
import org.junit.jupiter.api.AfterEach;
@ -80,7 +79,7 @@ abstract class AbstractObservationFilterTest extends SampleTestRunner {
private void initParam() {
invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION);
invocation.setMethodName(METHOD_NAME);
invocation.setParameterTypes(new Class[]{String.class});
invocation.setParameterTypes(new Class[] {String.class});
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.rpc.AttachmentsAdapter;
import org.apache.dubbo.rpc.Invoker;
@ -68,11 +68,11 @@ public class MockInvocation extends RpcInvocation {
}
public Class<?>[] getParameterTypes() {
return new Class[]{String.class};
return new Class[] {String.class};
}
public Object[] getArguments() {
return new Object[]{"aa"};
return new Object[] {"aa"};
}
public Map<String, String> getAttachments() {

View File

@ -15,13 +15,8 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.KeyValues;
import io.micrometer.core.tck.MeterRegistryAssert;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.test.simple.SpansAssert;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.AppResponse;
import org.apache.dubbo.rpc.Filter;
@ -32,6 +27,11 @@ import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.micrometer.common.KeyValues;
import io.micrometer.core.tck.MeterRegistryAssert;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.test.simple.SpansAssert;
import org.assertj.core.api.BDDAssertions;
class ObservationReceiverFilterTest extends AbstractObservationFilterTest {

View File

@ -1,111 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-tracing</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The tracing module of dubbo project</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-cluster</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-default</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- micrometer -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
<!-- bridge -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
<optional>true</optional>
</dependency>
<!-- exporter -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,90 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.metrics.MetricsGlobalRegistry;
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.tracer.PropagatorProvider;
import org.apache.dubbo.tracing.tracer.PropagatorProviderFactory;
import org.apache.dubbo.tracing.tracer.TracerProvider;
import org.apache.dubbo.tracing.tracer.TracerProviderFactory;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_NOT_FOUND_TRACER_DEPENDENCY;
public class DubboObservationRegistry {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DubboObservationRegistry.class);
private final ApplicationModel applicationModel;
private final TracingConfig tracingConfig;
public DubboObservationRegistry(ApplicationModel applicationModel, TracingConfig tracingConfig) {
this.applicationModel = applicationModel;
this.tracingConfig = tracingConfig;
}
public void initObservationRegistry() {
// If get ObservationRegistry.class from external(eg Spring.), use external.
io.micrometer.observation.ObservationRegistry externalObservationRegistry = applicationModel.getBeanFactory().getBean(io.micrometer.observation.ObservationRegistry.class);
if (externalObservationRegistry != null) {
if (logger.isDebugEnabled()) {
logger.debug("ObservationRegistry.class from external is existed.");
}
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Tracing config is: " + JsonUtils.toJson(tracingConfig));
}
TracerProvider tracerProvider = TracerProviderFactory.getProvider(applicationModel, tracingConfig);
if (tracerProvider == null) {
logger.warn(COMMON_NOT_FOUND_TRACER_DEPENDENCY, "", "", "Can not found OpenTelemetry/Brave tracer dependencies, skip init ObservationRegistry.");
return;
}
// The real tracer will come from tracer implementation (OTel / Brave)
io.micrometer.tracing.Tracer tracer = tracerProvider.getTracer();
// The real propagator will come from tracer implementation (OTel / Brave)
PropagatorProvider propagatorProvider = PropagatorProviderFactory.getPropagatorProvider();
io.micrometer.tracing.propagation.Propagator propagator = propagatorProvider != null ? propagatorProvider.getPropagator() : io.micrometer.tracing.propagation.Propagator.NOOP;
io.micrometer.observation.ObservationRegistry registry = io.micrometer.observation.ObservationRegistry.create();
registry.observationConfig()
// set up a first matching handler that creates spans - it comes from Micrometer Tracing.
// set up spans for sending and receiving data over the wire and a default one.
.observationHandler(new io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler(
new io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler<>(tracer, propagator),
new io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler<>(tracer, propagator),
new io.micrometer.tracing.handler.DefaultTracingObservationHandler(tracer)));
if (MetricsSupportUtil.isSupportMetrics()) {
io.micrometer.core.instrument.MeterRegistry meterRegistry = MetricsGlobalRegistry.getCompositeRegistry(applicationModel);
registry.observationConfig().observationHandler(new io.micrometer.core.instrument.observation.DefaultMeterObservationHandler(meterRegistry));
}
applicationModel.getBeanFactory().registerBean(registry);
applicationModel.getBeanFactory().registerBean(tracer);
applicationModel.getBeanFactory().registerBean(propagator);
}
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.nested.ExporterConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.exporter.otlp.OTlpExporter;
import org.apache.dubbo.tracing.exporter.zipkin.ZipkinExporter;
import brave.handler.SpanHandler;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.ArrayList;
import java.util.List;
public class TraceExporterFactory {
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(TraceExporterFactory.class);
/**
* for OTel
*/
public static List<SpanExporter> getSpanExporters(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig();
ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig();
List<SpanExporter> res = new ArrayList<>();
if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) {
ZipkinExporter zipkinExporter = new ZipkinExporter(applicationModel, zipkinConfig);
LOGGER.info("Create zipkin span exporter.");
res.add(zipkinExporter.getSpanExporter());
}
if (otlpConfig != null && StringUtils.isNotEmpty(otlpConfig.getEndpoint())) {
OTlpExporter otlpExporter = new OTlpExporter(applicationModel, otlpConfig);
LOGGER.info("Create OTlp span exporter.");
res.add(otlpExporter.getSpanExporter());
}
return res;
}
/**
* for Brave
*/
public static List<SpanHandler> getSpanHandlers(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
List<SpanHandler> res = new ArrayList<>();
// TODO brave SpanHandler impl
return res;
}
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter.otlp;
import org.apache.dubbo.config.nested.ExporterConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.exporter.TraceExporter;
import brave.handler.SpanHandler;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.Map;
public class OTlpExporter implements TraceExporter {
private final ApplicationModel applicationModel;
private final ExporterConfig.OtlpConfig otlpConfig;
public OTlpExporter(ApplicationModel applicationModel, ExporterConfig.OtlpConfig otlpConfig) {
this.applicationModel = applicationModel;
this.otlpConfig = otlpConfig;
}
@Override
public SpanExporter getSpanExporter() {
OtlpGrpcSpanExporter externalOTlpGrpcSpanExporter = applicationModel.getBeanFactory().getBean(OtlpGrpcSpanExporter.class);
if (externalOTlpGrpcSpanExporter != null) {
return externalOTlpGrpcSpanExporter;
}
OtlpHttpSpanExporter externalOtlpHttpSpanExporter = applicationModel.getBeanFactory().getBean(OtlpHttpSpanExporter.class);
if (externalOtlpHttpSpanExporter != null) {
return externalOtlpHttpSpanExporter;
}
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder()
.setEndpoint(otlpConfig.getEndpoint())
.setTimeout(otlpConfig.getTimeout())
.setCompression(otlpConfig.getCompressionMethod());
for (Map.Entry<String, String> entry : otlpConfig.getHeaders().entrySet()) {
builder.addHeader(entry.getKey(), entry.getValue());
}
return builder.build();
}
@Override
public SpanHandler getSpanHandler() {
// OTlp is only belong to OTel.
return null;
}
}

View File

@ -1,60 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter.zipkin;
import org.apache.dubbo.config.nested.ExporterConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.exporter.TraceExporter;
import brave.handler.SpanHandler;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import zipkin2.Span;
import zipkin2.codec.BytesEncoder;
import zipkin2.codec.SpanBytesEncoder;
public class ZipkinExporter implements TraceExporter {
private final ApplicationModel applicationModel;
private final ExporterConfig.ZipkinConfig zipkinConfig;
public ZipkinExporter(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) {
this.applicationModel = applicationModel;
this.zipkinConfig = zipkinConfig;
}
@Override
public SpanExporter getSpanExporter() {
BytesEncoder<Span> encoder = getSpanBytesEncoder();
return ZipkinSpanExporter.builder()
.setEncoder(encoder)
.setEndpoint(zipkinConfig.getEndpoint())
.setReadTimeout(zipkinConfig.getReadTimeout())
.build();
}
@Override
public SpanHandler getSpanHandler() {
// TODO SpanHandler of Brave impl
return null;
}
private BytesEncoder<Span> getSpanBytesEncoder() {
BytesEncoder<Span> encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class);
return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder;
}
}

View File

@ -1,29 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import io.micrometer.tracing.propagation.Propagator;
public interface PropagatorProvider {
/**
* The real propagator will come from tracer implementation (OTel / Brave)
*
* @return Propagator
*/
Propagator getPropagator();
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import org.apache.dubbo.tracing.tracer.brave.BravePropagatorProvider;
import org.apache.dubbo.tracing.tracer.otel.OTelPropagatorProvider;
import org.apache.dubbo.tracing.utils.ObservationSupportUtil;
public class PropagatorProviderFactory {
public static PropagatorProvider getPropagatorProvider() {
// If support OTel firstly, return OTel, then Brave.
if (ObservationSupportUtil.isSupportOTelTracer()) {
return new OTelPropagatorProvider();
}
if (ObservationSupportUtil.isSupportBraveTracer()) {
return new BravePropagatorProvider();
}
return null;
}
}

View File

@ -1,30 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import io.micrometer.tracing.Tracer;
public interface TracerProvider {
/**
* Tracer of Micrometer. The real tracer will come from tracer implementation (OTel / Brave)
*
* @return Tracer
*/
Tracer getTracer();
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.tracer.brave.BraveProvider;
import org.apache.dubbo.tracing.tracer.otel.OpenTelemetryProvider;
import org.apache.dubbo.tracing.utils.ObservationSupportUtil;
public class TracerProviderFactory {
public static TracerProvider getProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) {
// If support OTel firstly, return OTel, then Brave.
if (ObservationSupportUtil.isSupportOTelTracer()) {
return new OpenTelemetryProvider(applicationModel, tracingConfig);
}
if (ObservationSupportUtil.isSupportBraveTracer()) {
return new BraveProvider(applicationModel, tracingConfig);
}
return null;
}
}

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.brave;
import org.apache.dubbo.tracing.tracer.PropagatorProvider;
import io.micrometer.tracing.propagation.Propagator;
public class BravePropagatorProvider implements PropagatorProvider {
@Override
public Propagator getPropagator() {
// TODO impl
return null;
}
}

View File

@ -1,41 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.brave;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.tracer.TracerProvider;
import io.micrometer.tracing.Tracer;
public class BraveProvider implements TracerProvider {
private final ApplicationModel applicationModel;
private final TracingConfig tracingConfig;
public BraveProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) {
this.applicationModel = applicationModel;
this.tracingConfig = tracingConfig;
}
@Override
public Tracer getTracer() {
// TODO impl
return null;
}
}

View File

@ -1,38 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.otel;
import org.apache.dubbo.tracing.tracer.PropagatorProvider;
import io.micrometer.tracing.otel.bridge.OtelPropagator;
import io.micrometer.tracing.propagation.Propagator;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.propagation.ContextPropagators;
public class OTelPropagatorProvider implements PropagatorProvider {
private static Propagator propagator;
@Override
public Propagator getPropagator() {
return propagator;
}
protected static void createMicrometerPropagator(ContextPropagators contextPropagators, Tracer tracer) {
propagator = new OtelPropagator(contextPropagators, tracer);
}
}

View File

@ -1,212 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.otel;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.lang.Nullable;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.nested.BaggageConfig;
import org.apache.dubbo.config.nested.PropagationConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.exporter.TraceExporterFactory;
import org.apache.dubbo.tracing.tracer.TracerProvider;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.otel.bridge.CompositeSpanExporter;
import io.micrometer.tracing.otel.bridge.EventListener;
import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
import io.micrometer.tracing.otel.bridge.OtelTracer;
import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.ContextStorage;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class OpenTelemetryProvider implements TracerProvider {
private static final String DEFAULT_APPLICATION_NAME = "dubbo-application";
private final ApplicationModel applicationModel;
private final TracingConfig tracingConfig;
private OTelEventPublisher publisher;
private OtelCurrentTraceContext otelCurrentTraceContext;
public OpenTelemetryProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) {
this.applicationModel = applicationModel;
this.tracingConfig = tracingConfig;
}
@Override
public Tracer getTracer() {
// [OTel component] SpanExporter is a component that gets called when a span is finished.
List<SpanExporter> spanExporters = TraceExporterFactory.getSpanExporters(applicationModel, tracingConfig.getTracingExporter());
String applicationName = applicationModel.getApplicationConfigManager().getApplication()
.map(ApplicationConfig::getName)
.orElse(DEFAULT_APPLICATION_NAME);
this.publisher = new OTelEventPublisher(getEventListeners());
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel
this.otelCurrentTraceContext = createCurrentTraceContext();
// [OTel component] SdkTracerProvider is an SDK implementation for TracerProvider
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.setSampler(getSampler())
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)))
.addSpanProcessor(BatchSpanProcessor
.builder(new CompositeSpanExporter(spanExporters, null, null, null))
.build())
.build();
ContextPropagators otelContextPropagators = createOtelContextPropagators();
// [OTel component] The SDK implementation of OpenTelemetry
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(otelContextPropagators)
.build();
// [OTel component] Tracer is a component that handles the life-cycle of a span
io.opentelemetry.api.trace.Tracer otelTracer = openTelemetrySdk.getTracerProvider()
.get("org.apache.dubbo", Version.getVersion());
OTelPropagatorProvider.createMicrometerPropagator(otelContextPropagators, otelTracer);
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel's Tracer.
return new OtelTracer(otelTracer, otelCurrentTraceContext, publisher,
new OtelBaggageManager(otelCurrentTraceContext,
tracingConfig.getBaggage().getRemoteFields(),
Collections.emptyList()));
}
/**
* sampler with probability
*
* @return sampler
*/
private Sampler getSampler() {
Sampler rootSampler = Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability());
return Sampler.parentBased(rootSampler);
}
private List<EventListener> getEventListeners() {
List<EventListener> listeners = new ArrayList<>();
// [Micrometer Tracing component] A Micrometer Tracing listener for setting up MDC.
Slf4JEventListener slf4JEventListener = new Slf4JEventListener();
listeners.add(slf4JEventListener);
if (tracingConfig.getBaggage().getEnabled()) {
// [Micrometer Tracing component] A Micrometer Tracing listener for setting Baggage in MDC.
// Customizable with correlation fields.
Slf4JBaggageEventListener slf4JBaggageEventListener = new Slf4JBaggageEventListener(tracingConfig.getBaggage().getCorrelation().getFields());
listeners.add(slf4JBaggageEventListener);
}
return listeners;
}
private OtelCurrentTraceContext createCurrentTraceContext() {
ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher));
return new OtelCurrentTraceContext();
}
private ContextPropagators createOtelContextPropagators() {
return ContextPropagators.create(
TextMapPropagator.composite(
PropagatorFactory.getPropagator(tracingConfig.getPropagation(),
tracingConfig.getBaggage(),
otelCurrentTraceContext
)));
}
static class OTelEventPublisher implements OtelTracer.EventPublisher {
private final List<EventListener> listeners;
OTelEventPublisher(List<EventListener> listeners) {
this.listeners = listeners;
}
@Override
public void publishEvent(Object event) {
for (EventListener listener : this.listeners) {
listener.onEvent(event);
}
}
}
static class PropagatorFactory {
public static TextMapPropagator getPropagator(PropagationConfig propagationConfig,
@Nullable BaggageConfig baggageConfig,
@Nullable OtelCurrentTraceContext currentTraceContext) {
if (baggageConfig == null || !baggageConfig.getEnabled()) {
return getPropagatorWithoutBaggage(propagationConfig);
}
return getPropagatorWithBaggage(propagationConfig, baggageConfig, currentTraceContext);
}
private static TextMapPropagator getPropagatorWithoutBaggage(PropagationConfig propagationConfig) {
String type = propagationConfig.getType();
if ("B3".equals(type)) {
return B3Propagator.injectingSingleHeader();
} else if ("W3C".equals(type)) {
return W3CTraceContextPropagator.getInstance();
}
return TextMapPropagator.noop();
}
private static TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig,
BaggageConfig baggageConfig,
OtelCurrentTraceContext currentTraceContext) {
String type = propagationConfig.getType();
if ("B3".equals(type)) {
List<String> remoteFields = baggageConfig.getRemoteFields();
return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(),
new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
} else if ("W3C".equals(type)) {
List<String> remoteFields = baggageConfig.getRemoteFields();
return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
}
return TextMapPropagator.noop();
}
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.utils;
import org.apache.dubbo.common.utils.ClassUtils;
public class ObservationSupportUtil {
public static boolean isSupportObservation() {
return isClassPresent("io.micrometer.observation.Observation")
&& isClassPresent("io.micrometer.observation.ObservationRegistry")
&& isClassPresent("io.micrometer.observation.ObservationHandler");
}
public static boolean isSupportTracing() {
return isClassPresent("io.micrometer.tracing.Tracer")
&& isClassPresent("io.micrometer.tracing.propagation.Propagator");
}
public static boolean isSupportOTelTracer() {
return isClassPresent("io.micrometer.tracing.otel.bridge.OtelTracer")
&& isClassPresent("io.opentelemetry.sdk.trace.SdkTracerProvider")
&& isClassPresent("io.opentelemetry.api.OpenTelemetry");
}
public static boolean isSupportBraveTracer() {
return isClassPresent("io.micrometer.tracing.Tracer")
&& isClassPresent("io.micrometer.tracing.brave.bridge.BraveTracer")
&& isClassPresent("brave.Tracing");
}
private static boolean isClassPresent(String className) {
return ClassUtils.isPresent(className, ObservationSupportUtil.class.getClassLoader());
}
}

View File

@ -1 +0,0 @@
observationreceiver=org.apache.dubbo.tracing.filter.ObservationReceiverFilter

View File

@ -1 +0,0 @@
observationsender=org.apache.dubbo.tracing.filter.ObservationSenderFilter

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.tracing.tracer.otel.OTelPropagatorProvider;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class PropagatorProviderFactoryTest {
@Test
void testPropagatorProviderFactory() {
PropagatorProvider propagatorProvider = PropagatorProviderFactory.getPropagatorProvider();
Assert.notNull(propagatorProvider, "PropagatorProvider should not be null");
assertEquals(OTelPropagatorProvider.class, propagatorProvider.getClass());
}
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.otel;
import org.apache.dubbo.common.utils.Assert;
import io.micrometer.tracing.propagation.Propagator;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.propagation.ContextPropagators;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
class OTelPropagatorProviderTest {
@Test
void testOTelPropagatorProvider() {
ContextPropagators contextPropagators = mock(ContextPropagators.class);
Tracer tracer = mock(Tracer.class);
OTelPropagatorProvider.createMicrometerPropagator(contextPropagators, tracer);
OTelPropagatorProvider oTelPropagatorProvider = new OTelPropagatorProvider();
Propagator propagator = oTelPropagatorProvider.getPropagator();
Assert.notNull(propagator, "Propagator don't be null.");
}
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer.otel;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.nested.BaggageConfig;
import org.apache.dubbo.config.nested.ExporterConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.tracer.TracerProvider;
import org.apache.dubbo.tracing.tracer.TracerProviderFactory;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.otel.bridge.OtelTracer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class OpenTelemetryProviderTest {
@Test
void testGetTracer() {
TracingConfig tracingConfig = new TracingConfig();
tracingConfig.setEnabled(true);
ExporterConfig exporterConfig = new ExporterConfig();
exporterConfig.setZipkinConfig(new ExporterConfig.ZipkinConfig(""));
tracingConfig.setTracingExporter(exporterConfig);
TracerProvider tracerProvider1 = TracerProviderFactory.getProvider(ApplicationModel.defaultModel(), tracingConfig);
Assert.notNull(tracerProvider1, "TracerProvider should not be null.");
Tracer tracer1 = tracerProvider1.getTracer();
assertEquals(OtelTracer.class, tracer1.getClass());
tracingConfig.setBaggage(new BaggageConfig(false));
TracerProvider tracerProvider2 = TracerProviderFactory.getProvider(ApplicationModel.defaultModel(), tracingConfig);
Assert.notNull(tracerProvider2, "TracerProvider should not be null.");
Tracer tracer2 = tracerProvider2.getTracer();
assertEquals(OtelTracer.class, tracer2.getClass());
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.utils;
import org.apache.dubbo.common.utils.Assert;
import org.junit.jupiter.api.Test;
public class ObservationSupportUtilTest {
@Test
void testIsSupportObservation() {
boolean supportObservation = ObservationSupportUtil.isSupportObservation();
Assert.assertTrue(supportObservation, "ObservationSupportUtil.isSupportObservation() should return true");
}
@Test
void testIsSupportTracing() {
boolean supportTracing = ObservationSupportUtil.isSupportTracing();
Assert.assertTrue(supportTracing, "ObservationSupportUtil.isSupportTracing() should return true");
}
@Test
void testIsSupportOTelTracer() {
boolean supportOTelTracer = ObservationSupportUtil.isSupportOTelTracer();
Assert.assertTrue(supportOTelTracer, "ObservationSupportUtil.isSupportOTelTracer() should return true");
}
@Test
void testIsSupportBraveTracer() {
boolean supportBraveTracer = ObservationSupportUtil.isSupportBraveTracer();
Assert.assertTrue(supportBraveTracer, "ObservationSupportUtil.isSupportOTelTracer() should return true");
}
}

View File

@ -24,7 +24,6 @@
<module>dubbo-metrics-metadata</module>
<module>dubbo-metrics-prometheus</module>
<module>dubbo-metrics-config-center</module>
<module>dubbo-tracing</module>
</modules>
<parent>
<groupId>org.apache.dubbo</groupId>

View File

@ -24,12 +24,16 @@ import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import static org.apache.dubbo.rpc.RpcException.AUTHORIZATION_EXCEPTION;
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
@Activate(group = CommonConstants.PROVIDER, order =Integer.MAX_VALUE,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
@Activate(group = CommonConstants.PROVIDER, order = Integer.MAX_VALUE, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
public class AuthenticationExceptionTranslatorFilter implements Filter, Filter.Listener {

View File

@ -27,13 +27,17 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
import org.apache.dubbo.spring.security.utils.SecurityNames;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
@Activate(group = CommonConstants.CONSUMER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter{
@Activate(group = CommonConstants.CONSUMER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter {
private final ObjectMapperCodec mapper;

View File

@ -27,11 +27,15 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
import org.apache.dubbo.spring.security.utils.SecurityNames;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
@Activate(group = CommonConstants.PROVIDER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
@Activate(group = CommonConstants.PROVIDER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
public class ContextHolderAuthenticationResolverFilter implements Filter {
private final ObjectMapperCodec mapper;

View File

@ -25,10 +25,14 @@ import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer;
import java.util.Set;
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
@Activate(onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
@Activate(onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
public class SecurityScopeModelInitializer implements ScopeModelInitializer {
@Override

View File

@ -22,6 +22,8 @@ final public class SecurityNames {
public static final String SECURITY_AUTHENTICATION_CONTEXT_KEY = "security_authentication_context";
public static final String SECURITY_CONTEXT_HOLDER_CLASS_NAME = "org.springframework.security.core.context.SecurityContextHolder";
public static final String CORE_JACKSON_2_MODULE_CLASS_NAME = "org.springframework.security.jackson2.CoreJackson2Module";
public static final String OBJECT_MAPPER_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper";
private SecurityNames() {}

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.registry;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.registry.integration.ExporterFactory;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
@ -26,7 +27,8 @@ import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class RegistryScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(ExporterFactory.class);
}
@Override

View File

@ -103,6 +103,7 @@ public interface ServiceInstance extends Serializable {
void setApplicationModel(ApplicationModel applicationModel);
@Transient
ApplicationModel getApplicationModel();
@Transient

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.registry.integration;
import org.apache.dubbo.rpc.Exporter;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
public class ExporterFactory {
private final Map<String, ReferenceCountExporter<?>> exporters = new ConcurrentHashMap<>();
protected ReferenceCountExporter<?> createExporter(String providerKey, Callable<Exporter<?>> exporterProducer) {
return exporters.computeIfAbsent(providerKey,
key -> {
try {
return new ReferenceCountExporter<>(exporterProducer.call(), key, this);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
protected void remove(String key, ReferenceCountExporter<?> exporter) {
exporters.remove(key, exporter);
}
}

View File

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.registry.integration;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import java.util.concurrent.atomic.AtomicInteger;
public class ReferenceCountExporter<T> implements Exporter<T> {
private final Exporter<T> exporter;
private final String providerKey;
private final ExporterFactory exporterFactory;
private final AtomicInteger count = new AtomicInteger(0);
public ReferenceCountExporter(Exporter<T> exporter, String providerKey, ExporterFactory exporterFactory) {
this.exporter = exporter;
this.providerKey = providerKey;
this.exporterFactory = exporterFactory;
}
@Override
public Invoker<T> getInvoker() {
return exporter.getInvoker();
}
public void increaseCount() {
count.incrementAndGet();
}
@Override
public void unexport() {
if (count.decrementAndGet() == 0) {
exporter.unexport();
}
exporterFactory.remove(providerKey, this);
}
@Override
public void register() {
}
@Override
public void unregister() {
}
}

View File

@ -171,6 +171,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
private ConcurrentMap<URL, ReExportTask> reExportFailedTasks = new ConcurrentHashMap<>();
private HashedWheelTimer retryTimer = new HashedWheelTimer(new NamedThreadFactory("DubboReexportTimer", true), DEFAULT_REGISTRY_RETRY_PERIOD, TimeUnit.MILLISECONDS, 128);
private FrameworkModel frameworkModel;
private ExporterFactory exporterFactory;
//Filter the parameters that do not need to be output in url(Starting with .)
private static String[] getFilteredKeys(URL url) {
@ -190,6 +191,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
@Override
public void setFrameworkModel(FrameworkModel frameworkModel) {
this.frameworkModel = frameworkModel;
this.exporterFactory = frameworkModel.getBeanFactory().getBean(ExporterFactory.class);
}
public void setProtocol(Protocol protocol) {
@ -312,11 +314,13 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker, URL providerUrl) {
String providerUrlKey = getProviderUrlKey(originInvoker);
String registryUrlKey = getRegistryUrlKey(originInvoker);
Invoker<?> invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl);
ReferenceCountExporter<?> exporter = exporterFactory.createExporter(providerUrlKey, () -> protocol.export(invokerDelegate));
return (ExporterChangeableWrapper<T>) bounds.computeIfAbsent(providerUrlKey, _k -> new ConcurrentHashMap<>())
.computeIfAbsent(registryUrlKey, s ->{
Invoker<?> invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl);
return new ExporterChangeableWrapper<>((Exporter<T>) protocol.export(invokerDelegate), originInvoker);
.computeIfAbsent(registryUrlKey, s -> {
return new ExporterChangeableWrapper<>(
(ReferenceCountExporter<T>) exporter, originInvoker);
});
}
@ -953,8 +957,9 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
private NotifyListener notifyListener;
private final AtomicBoolean registered = new AtomicBoolean(false);
public ExporterChangeableWrapper(Exporter<T> exporter, Invoker<T> originInvoker) {
public ExporterChangeableWrapper(ReferenceCountExporter<T> exporter, Invoker<T> originInvoker) {
this.exporter = exporter;
exporter.increaseCount();
this.originInvoker = originInvoker;
FrameworkExecutorRepository frameworkExecutorRepository = originInvoker.getUrl().getOrDefaultFrameworkModel().getBeanFactory()
.getBean(FrameworkExecutorRepository.class);

View File

@ -61,12 +61,12 @@ import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_NOTIFY_EVENT;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_DESTROY_UNREGISTER_URL;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_READ_WRITE_CACHE_FILE;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_DELETE_LOCKFILE;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_DELETE_LOCKFILE;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_DESTROY_UNREGISTER_URL;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_NOTIFY_EVENT;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_READ_WRITE_CACHE_FILE;
import static org.apache.dubbo.common.constants.RegistryConstants.ACCEPTS_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_KEY;

Some files were not shown because too many files have changed in this diff Show More