Merge branch 'apache-3.2' into apache-3.3
# Conflicts: # dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java # dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java # dubbo-dependencies-bom/pom.xml # dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml # dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml # dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java # dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java # pom.xml
This commit is contained in:
commit
3ed2dacbef
|
|
@ -348,6 +348,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
if (!invokersToReconnect.isEmpty()) {
|
||||
checkConnectivity();
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ public interface CommonConstants {
|
|||
|
||||
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
|
||||
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer"; String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer";
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,17 +40,19 @@ public interface MetricsConstants {
|
|||
String TAG_VERSION_KEY = "version";
|
||||
|
||||
String TAG_APPLICATION_VERSION_KEY = "application.version";
|
||||
|
||||
|
||||
String TAG_KEY_KEY = "key";
|
||||
|
||||
|
||||
String TAG_CONFIG_CENTER = "config.center";
|
||||
|
||||
|
||||
String TAG_CHANGE_TYPE = "change.type";
|
||||
|
||||
String TAG_ERROR_CODE = "error";
|
||||
|
||||
String ENABLE_JVM_METRICS_KEY = "enable.jvm";
|
||||
|
||||
String ENABLE_COLLECTOR_SYNC_KEY = "enable.collector.sync";
|
||||
|
||||
String AGGREGATION_COLLECTOR_KEY = "aggregation";
|
||||
|
||||
String AGGREGATION_ENABLED_KEY = "aggregation.enabled";
|
||||
|
|
|
|||
|
|
@ -17,8 +17,23 @@
|
|||
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
import org.apache.dubbo.common.constants.LoggerCodeConstants;
|
||||
|
||||
/**
|
||||
* Logger interface with the ability of displaying solution of different types of error.
|
||||
*
|
||||
* <p>
|
||||
* This logger will log a message like this:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ... (original logging message) This may be caused by (... cause),
|
||||
* go to https://dubbo.apache.org/faq/[Cat]/[X] to find instructions. (... extendedInformation)
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* Where "[Cat]/[X]" is the error code ("code" in arguments). The link is clickable, leading user to
|
||||
* the "Error code and its corresponding solutions" page.
|
||||
*
|
||||
* @see LoggerCodeConstants Detailed Format of Error Code and Error Code Constants
|
||||
*/
|
||||
public interface ErrorTypeAwareLogger extends Logger {
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,11 @@ public abstract class AbstractConfig implements Serializable {
|
|||
|
||||
protected final AtomicBoolean refreshed = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* Indicate that if current config needs to being refreshed, default is true
|
||||
*/
|
||||
protected transient volatile boolean needRefresh = true;
|
||||
|
||||
/**
|
||||
* Is default config or not
|
||||
*/
|
||||
|
|
@ -679,16 +684,18 @@ public abstract class AbstractConfig implements Serializable {
|
|||
* Dubbo config property override
|
||||
*/
|
||||
public void refresh() {
|
||||
try {
|
||||
// check and init before do refresh
|
||||
preProcessRefresh();
|
||||
refreshWithPrefixes(getPrefixes(), getConfigMode());
|
||||
} catch (Exception e) {
|
||||
logger.error(COMMON_FAILED_OVERRIDE_FIELD, "", "", "Failed to override field value of config bean: " + this, e);
|
||||
throw new IllegalStateException("Failed to override field value of config bean: " + this, e);
|
||||
}
|
||||
if (needRefresh) {
|
||||
try {
|
||||
// check and init before do refresh
|
||||
preProcessRefresh();
|
||||
refreshWithPrefixes(getPrefixes(), getConfigMode());
|
||||
} catch (Exception e) {
|
||||
logger.error(COMMON_FAILED_OVERRIDE_FIELD, "", "", "Failed to override field value of config bean: " + this, e);
|
||||
throw new IllegalStateException("Failed to override field value of config bean: " + this, e);
|
||||
}
|
||||
|
||||
postProcessRefresh();
|
||||
postProcessRefresh();
|
||||
}
|
||||
refreshed.set(true);
|
||||
}
|
||||
|
||||
|
|
@ -949,6 +956,17 @@ public abstract class AbstractConfig implements Serializable {
|
|||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
@Transient
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isNeedRefresh() {
|
||||
return needRefresh;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public void setNeedRefresh(boolean needRefresh) {
|
||||
this.needRefresh = needRefresh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,16 @@ public class MetricsConfig extends AbstractConfig {
|
|||
*/
|
||||
private Boolean enableNetty;
|
||||
|
||||
/**
|
||||
* Enable metrics init.
|
||||
*/
|
||||
private Boolean enableMetricsInit;
|
||||
|
||||
/**
|
||||
* Enable collector sync.
|
||||
*/
|
||||
private Boolean enableCollectorSync;
|
||||
|
||||
/**
|
||||
* @deprecated After metrics config is refactored.
|
||||
* This parameter should no longer use and will be deleted in the future.
|
||||
|
|
@ -213,6 +223,22 @@ public class MetricsConfig extends AbstractConfig {
|
|||
this.enableThreadpool = enableThreadpool;
|
||||
}
|
||||
|
||||
public Boolean getEnableMetricsInit() {
|
||||
return enableMetricsInit;
|
||||
}
|
||||
|
||||
public void setEnableMetricsInit(Boolean enableMetricsInit) {
|
||||
this.enableMetricsInit = enableMetricsInit;
|
||||
}
|
||||
|
||||
public Boolean getEnableCollectorSync() {
|
||||
return enableCollectorSync;
|
||||
}
|
||||
|
||||
public void setEnableCollectorSync(Boolean enableCollectorSync) {
|
||||
this.enableCollectorSync = enableCollectorSync;
|
||||
}
|
||||
|
||||
public Boolean getUseGlobalRegistry() {
|
||||
return useGlobalRegistry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,8 +228,13 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
|
||||
if (ref == null) {
|
||||
// ensure start module, compatible with old api usage
|
||||
getScopeModel().getDeployer().start();
|
||||
if (getScopeModel().isLifeCycleManagedExternally()) {
|
||||
// prepare model for reference
|
||||
getScopeModel().getDeployer().prepare();
|
||||
} else {
|
||||
// ensure start module, compatible with old api usage
|
||||
getScopeModel().getDeployer().start();
|
||||
}
|
||||
|
||||
init(check);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,8 +296,13 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
return;
|
||||
}
|
||||
|
||||
// ensure start module, compatible with old api usage
|
||||
getScopeModel().getDeployer().start();
|
||||
if (getScopeModel().isLifeCycleManagedExternally()) {
|
||||
// prepare model for reference
|
||||
getScopeModel().getDeployer().prepare();
|
||||
} else {
|
||||
// ensure start module, compatible with old api usage
|
||||
getScopeModel().getDeployer().start();
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
if (this.exported) {
|
||||
|
|
|
|||
|
|
@ -391,6 +391,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
collector.setCollectEnabled(true);
|
||||
collector.collectApplication();
|
||||
collector.setThreadpoolCollectEnabled(Optional.ofNullable(metricsConfig.getEnableThreadpool()).orElse(true));
|
||||
collector.setMetricsInitEnabled(Optional.ofNullable(metricsConfig.getEnableMetricsInit()).orElse(true));
|
||||
MetricsReporterFactory metricsReporterFactory = getExtensionLoader(MetricsReporterFactory.class).getAdaptiveExtension();
|
||||
MetricsReporter metricsReporter = null;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.20</version>
|
||||
<version>1.9.20.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.dubbo.common.utils.ClassUtils;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.spring.aot.AotWithSpringDetector;
|
||||
import org.apache.dubbo.config.spring.context.DubboConfigApplicationListener;
|
||||
import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
|
||||
|
|
@ -54,6 +55,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_INITIALIZER;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROXY_FAILED;
|
||||
|
||||
|
||||
|
|
@ -143,6 +145,9 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
//actual reference config
|
||||
private ReferenceConfig referenceConfig;
|
||||
|
||||
// ReferenceBeanManager
|
||||
private ReferenceBeanManager referenceBeanManager;
|
||||
|
||||
// Registration sources of this reference, may be xml file or annotation location
|
||||
private List<Map<String, Object>> sources = new ArrayList<>();
|
||||
|
||||
|
|
@ -256,7 +261,7 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
}
|
||||
Assert.notNull(this.interfaceName, "The interface name of ReferenceBean is not initialized");
|
||||
|
||||
ReferenceBeanManager referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
|
||||
this.referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
|
||||
referenceBeanManager.addReference(this);
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +398,9 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
|
||||
private Object getCallProxy() throws Exception {
|
||||
if (referenceConfig == null) {
|
||||
throw new IllegalStateException("ReferenceBean is not ready yet, please make sure to call reference interface method after dubbo is started.");
|
||||
referenceBeanManager.initReferenceBean(this);
|
||||
applicationContext.getBean(DubboConfigApplicationListener.class.getName(), DubboConfigApplicationListener.class).init();
|
||||
logger.warn(CONFIG_DUBBO_BEAN_INITIALIZER, "", "", "ReferenceBean is not ready yet, please make sure to call reference interface method after dubbo is started.");
|
||||
}
|
||||
//get reference proxy
|
||||
//Subclasses should synchronize on the given Object if they perform any sort of extended singleton creation phase.
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos
|
|||
}
|
||||
} else {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(CONFIG_NO_ANNOTATIONS_FOUND, "No annotations were found on the class", "", "No class annotated by Dubbo @Service was found under package ["
|
||||
logger.warn(CONFIG_NO_ANNOTATIONS_FOUND, "No annotations were found on the class", "", "No class annotated by Dubbo @DubboService or @Service was found under package ["
|
||||
+ packageToScan + "], ignore re-scanned classes: " + scanExcludeFilter.getExcludedCount());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,21 +16,22 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.context;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_NOT_FOUND;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.spring.context.event.DubboConfigInitEvent;
|
||||
import org.apache.dubbo.config.spring.util.DubboBeanUtils;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_NOT_FOUND;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
|
||||
/**
|
||||
* An ApplicationListener to load config beans
|
||||
*/
|
||||
|
|
@ -53,11 +54,15 @@ public class DubboConfigApplicationListener implements ApplicationListener<Dubbo
|
|||
@Override
|
||||
public void onApplicationEvent(DubboConfigInitEvent event) {
|
||||
if (nullSafeEquals(applicationContext, event.getSource())) {
|
||||
// It's expected to be notified at org.springframework.context.support.AbstractApplicationContext.registerListeners(),
|
||||
// before loading non-lazy singleton beans. At this moment, all BeanFactoryPostProcessor have been processed,
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
initDubboConfigBeans();
|
||||
}
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// It's expected to be notified at org.springframework.context.support.AbstractApplicationContext.registerListeners(),
|
||||
// before loading non-lazy singleton beans. At this moment, all BeanFactoryPostProcessor have been processed,
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
initDubboConfigBeans();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public class ReferenceBeanManager implements ApplicationContextAware {
|
|||
* @param referenceBean
|
||||
* @throws Exception
|
||||
*/
|
||||
private synchronized void initReferenceBean(ReferenceBean referenceBean) throws Exception {
|
||||
public synchronized void initReferenceBean(ReferenceBean referenceBean) throws Exception {
|
||||
|
||||
if (referenceBean.getReferenceConfig() != null) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
|
||||
<dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>
|
||||
<dubbo:registry id="registry1" address="zookeeper://127.0.0.1:2181?registry-type=service"/>
|
||||
<dubbo:registry id="registry1" address="zookeeper://127.0.0.1:2181"/>
|
||||
|
||||
<dubbo:protocol name="dubbo" port="-1"/>
|
||||
<dubbo:protocol name="tri" port="-1"/>
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@
|
|||
<httpclient_version>4.5.14</httpclient_version>
|
||||
<httpcore_version>4.4.16</httpcore_version>
|
||||
<fastjson_version>1.2.83</fastjson_version>
|
||||
<fastjson2_version>2.0.39</fastjson2_version>
|
||||
<fastjson2_version>2.0.40</fastjson2_version>
|
||||
<zookeeper_version>3.4.14</zookeeper_version>
|
||||
<curator_version>4.3.0</curator_version>
|
||||
<curator_test_version>2.12.0</curator_test_version>
|
||||
|
|
@ -112,12 +112,12 @@
|
|||
<consul_client_version>1.5.3</consul_client_version>
|
||||
<xmemcached_version>1.4.3</xmemcached_version>
|
||||
<cxf_version>3.5.5</cxf_version>
|
||||
<thrift_version>0.18.1</thrift_version>
|
||||
<thrift_version>0.19.0</thrift_version>
|
||||
<hessian_version>4.0.66</hessian_version>
|
||||
<protobuf-java_version>3.24.2</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>
|
||||
<jetty_version>9.4.52.v20230823</jetty_version>
|
||||
<validation_new_version>3.0.2</validation_new_version>
|
||||
<validation_version>1.1.0.Final</validation_version>
|
||||
<hibernate_validator_version>5.4.3.Final</hibernate_validator_version>
|
||||
|
|
|
|||
|
|
@ -267,10 +267,16 @@ public class AggregateMetricsCollector implements MetricsCollector<RequestEvent>
|
|||
@Override
|
||||
public void initMetrics(MetricsEvent event) {
|
||||
MethodMetric metric = new MethodMetric(applicationModel, event.getAttachmentValue(MetricsConstants.INVOCATION));
|
||||
initMethodMetric(event);
|
||||
initQpsMetric(metric);
|
||||
initRtMetric(metric);
|
||||
initRtAgrMetric(metric);
|
||||
if (enableQps) {
|
||||
initMethodMetric(event);
|
||||
initQpsMetric(metric);
|
||||
}
|
||||
if (enableRt) {
|
||||
initRtMetric(metric);
|
||||
}
|
||||
if (enableRtPxx) {
|
||||
initRtAgrMetric(metric);
|
||||
}
|
||||
}
|
||||
|
||||
public void initMethodMetric(MetricsEvent event){
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
|
||||
private volatile boolean threadpoolCollectEnabled = false;
|
||||
|
||||
private volatile boolean metricsInitEnabled = true;
|
||||
|
||||
private final ThreadPoolMetricsSampler threadPoolSampler = new ThreadPoolMetricsSampler(this);
|
||||
|
||||
private final ErrorCodeSampler errorCodeSampler;
|
||||
|
|
@ -132,6 +134,14 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
this.threadpoolCollectEnabled = threadpoolCollectEnabled;
|
||||
}
|
||||
|
||||
public boolean isMetricsInitEnabled() {
|
||||
return metricsInitEnabled;
|
||||
}
|
||||
|
||||
public void setMetricsInitEnabled(boolean metricsInitEnabled) {
|
||||
this.metricsInitEnabled = metricsInitEnabled;
|
||||
}
|
||||
|
||||
public void collectApplication() {
|
||||
this.setApplicationName(applicationModel.getApplicationName());
|
||||
applicationSampler.inc(applicationName, MetricsEvent.Type.APPLICATION_INFO);
|
||||
|
|
@ -164,6 +174,9 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
@Override
|
||||
public void onEvent(TimeCounterEvent event) {
|
||||
if(event instanceof MetricsInitEvent){
|
||||
if (!metricsInitEnabled) {
|
||||
return;
|
||||
}
|
||||
if(initialized.compareAndSet(false,true)) {
|
||||
collectors.addAll(applicationModel.getBeanFactory().getBeansOfType(MetricsCollector.class));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,26 +17,26 @@
|
|||
|
||||
package org.apache.dubbo.metrics.report;
|
||||
|
||||
import io.micrometer.core.instrument.FunctionCounter;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.metrics.MetricsGlobalRegistry;
|
||||
import org.apache.dubbo.common.utils.NamedThreadFactory;
|
||||
import org.apache.dubbo.metrics.MetricsGlobalRegistry;
|
||||
import org.apache.dubbo.metrics.collector.AggregateMetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.MetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.HistogramMetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.MetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.core.instrument.FunctionCounter;
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
|
||||
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
|
||||
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
|
||||
|
|
@ -53,6 +53,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.ENABLE_COLLECTOR_SYNC_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.ENABLE_JVM_METRICS_KEY;
|
||||
|
||||
/**
|
||||
|
|
@ -140,9 +141,12 @@ public abstract class AbstractMetricsReporter implements MetricsReporter {
|
|||
}
|
||||
|
||||
private void scheduleMetricsCollectorSyncJob() {
|
||||
NamedThreadFactory threadFactory = new NamedThreadFactory("metrics-collector-sync-job", true);
|
||||
collectorSyncJobExecutor = Executors.newScheduledThreadPool(1, threadFactory);
|
||||
collectorSyncJobExecutor.scheduleWithFixedDelay(this::refreshData, DEFAULT_SCHEDULE_INITIAL_DELAY, DEFAULT_SCHEDULE_PERIOD, TimeUnit.SECONDS);
|
||||
boolean enableCollectorSync = url.getParameter(ENABLE_COLLECTOR_SYNC_KEY, true);
|
||||
if (enableCollectorSync) {
|
||||
NamedThreadFactory threadFactory = new NamedThreadFactory("metrics-collector-sync-job", true);
|
||||
collectorSyncJobExecutor = Executors.newScheduledThreadPool(1, threadFactory);
|
||||
collectorSyncJobExecutor.scheduleWithFixedDelay(this::refreshData, DEFAULT_SCHEDULE_INITIAL_DELAY, DEFAULT_SCHEDULE_PERIOD, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
|
|
|
|||
|
|
@ -96,7 +96,9 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware {
|
|||
return protocol.getServers();
|
||||
}
|
||||
|
||||
private void startQosServer(URL url) {
|
||||
private void startQosServer(URL url) throws RpcException {
|
||||
boolean qosCheck = url.getParameter(QOS_CHECK, false);
|
||||
|
||||
try {
|
||||
if (!hasStarted.compareAndSet(false, true)) {
|
||||
return;
|
||||
|
|
@ -132,9 +134,13 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware {
|
|||
|
||||
} catch (Throwable throwable) {
|
||||
logger.warn(QOS_FAILED_START_SERVER, "", "", "Fail to start qos server: ", throwable);
|
||||
boolean qosCheck = url.getParameter(QOS_CHECK, false);
|
||||
try {
|
||||
stopServer();
|
||||
} catch (Throwable stop) {
|
||||
logger.warn(QOS_FAILED_START_SERVER, "", "", "Fail to stop qos server: ", stop);
|
||||
}
|
||||
if (qosCheck) {
|
||||
throw new IllegalStateException("Fail to start qos server: " + throwable.getMessage(), throwable);
|
||||
throw new RpcException(throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.qos.server;
|
||||
|
||||
/**
|
||||
* Indicate that if Qos Start failed
|
||||
*/
|
||||
public class QosBindException extends RuntimeException {
|
||||
public QosBindException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,8 +35,6 @@ import io.netty.util.concurrent.DefaultThreadFactory;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_FAILED_START_SERVER;
|
||||
|
||||
/**
|
||||
* A server serves for both telnet access and http access
|
||||
* <ul>
|
||||
|
|
@ -105,13 +103,13 @@ public class Server {
|
|||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(new QosProcessHandler(frameworkModel,
|
||||
QosConfiguration.builder()
|
||||
.welcome(welcome)
|
||||
.acceptForeignIp(acceptForeignIp)
|
||||
.acceptForeignIpWhitelist(acceptForeignIpWhitelist)
|
||||
.anonymousAccessPermissionLevel(anonymousAccessPermissionLevel)
|
||||
.anonymousAllowCommands(anonymousAllowCommands)
|
||||
.build()
|
||||
QosConfiguration.builder()
|
||||
.welcome(welcome)
|
||||
.acceptForeignIp(acceptForeignIp)
|
||||
.acceptForeignIpWhitelist(acceptForeignIpWhitelist)
|
||||
.anonymousAccessPermissionLevel(anonymousAccessPermissionLevel)
|
||||
.anonymousAllowCommands(anonymousAllowCommands)
|
||||
.build()
|
||||
));
|
||||
}
|
||||
});
|
||||
|
|
@ -124,8 +122,7 @@ public class Server {
|
|||
|
||||
logger.info("qos-server bind localhost:" + port);
|
||||
} catch (Throwable throwable) {
|
||||
logger.error(QOS_FAILED_START_SERVER, "", "", "qos-server can not bind localhost:" + port, throwable);
|
||||
throw throwable;
|
||||
throw new QosBindException("qos-server can not bind localhost:" + port, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +137,7 @@ public class Server {
|
|||
if (worker != null) {
|
||||
worker.shutdownGracefully();
|
||||
}
|
||||
started.set(false);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ public interface Constants {
|
|||
|
||||
String BIND_PORT_KEY = "bind.port";
|
||||
|
||||
String BIND_RETRY_TIMES = "bind.retry.times";
|
||||
|
||||
String BIND_RETRY_INTERVAL = "bind.retry.interval";
|
||||
|
||||
String SENT_KEY = "sent";
|
||||
|
||||
String DISPATCHER_KEY = "dispatcher";
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ public class HttpClientRestClient implements RestClient {
|
|||
future.complete(new RestResult() {
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return response.getFirstHeader("Content-Type").getValue();
|
||||
Header header = response.getFirstHeader("Content-Type");
|
||||
return header == null ? null : header.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -97,14 +97,14 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
|||
}
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
public void bind() throws Throwable {
|
||||
if (channel == null) {
|
||||
doOpen();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doOpen() {
|
||||
public void doOpen() throws Throwable {
|
||||
bootstrap = new ServerBootstrap();
|
||||
|
||||
bossGroup = NettyEventLoopFactory.eventLoopGroup(1, EVENT_LOOP_BOSS_POOL_NAME);
|
||||
|
|
@ -138,9 +138,31 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
|||
bindIp = ANYHOST_VALUE;
|
||||
}
|
||||
InetSocketAddress bindAddress = new InetSocketAddress(bindIp, bindPort);
|
||||
ChannelFuture channelFuture = bootstrap.bind(bindAddress);
|
||||
channelFuture.syncUninterruptibly();
|
||||
channel = channelFuture.channel();
|
||||
try {
|
||||
ChannelFuture channelFuture = bootstrap.bind(bindAddress);
|
||||
channelFuture.syncUninterruptibly();
|
||||
channel = channelFuture.channel();
|
||||
} catch (Throwable t) {
|
||||
closeBootstrap();
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
private void closeBootstrap() {
|
||||
try {
|
||||
if (bootstrap != null) {
|
||||
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
||||
long quietPeriod = Math.min(2000L, timeout);
|
||||
Future<?> bossGroupShutdownFuture = bossGroup.shutdownGracefully(quietPeriod,
|
||||
timeout, MILLISECONDS);
|
||||
Future<?> workerGroupShutdownFuture = workerGroup.shutdownGracefully(quietPeriod,
|
||||
timeout, MILLISECONDS);
|
||||
bossGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||
workerGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -176,20 +198,7 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
|||
protocol.close();
|
||||
}
|
||||
|
||||
try {
|
||||
if (bootstrap != null) {
|
||||
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
||||
long quietPeriod = Math.min(2000L, timeout);
|
||||
Future<?> bossGroupShutdownFuture = bossGroup.shutdownGracefully(quietPeriod,
|
||||
timeout, MILLISECONDS);
|
||||
Future<?> workerGroupShutdownFuture = workerGroup.shutdownGracefully(quietPeriod,
|
||||
timeout, MILLISECONDS);
|
||||
bossGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||
workerGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
closeBootstrap();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -111,9 +111,14 @@ public class NettyServer extends AbstractServer {
|
|||
initServerBootstrap(nettyServerHandler);
|
||||
|
||||
// bind
|
||||
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
|
||||
channelFuture.syncUninterruptibly();
|
||||
channel = channelFuture.channel();
|
||||
try {
|
||||
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
|
||||
channelFuture.syncUninterruptibly();
|
||||
channel = channelFuture.channel();
|
||||
} catch (Throwable t) {
|
||||
closeBootstrap();
|
||||
throw t;
|
||||
}
|
||||
|
||||
// metrics
|
||||
if (isSupportMetrics()) {
|
||||
|
|
@ -198,6 +203,17 @@ public class NettyServer extends AbstractServer {
|
|||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
closeBootstrap();
|
||||
try {
|
||||
if (channels != null) {
|
||||
channels.clear();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeBootstrap() {
|
||||
try {
|
||||
if (bootstrap != null) {
|
||||
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
||||
|
|
@ -210,13 +226,6 @@ public class NettyServer extends AbstractServer {
|
|||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
try {
|
||||
if (channels != null) {
|
||||
channels.clear();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
|||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
||||
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
||||
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -50,7 +50,7 @@ public class ConnectionTest {
|
|||
private static ConnectionManager connectionManager;
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws RemotingException {
|
||||
public static void init() throws Throwable {
|
||||
int port = NetUtils.getAvailablePort();
|
||||
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
|
|
@ -123,7 +123,7 @@ public class ConnectionTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void connectSyncTest() throws RemotingException {
|
||||
void connectSyncTest() throws Throwable {
|
||||
int port = NetUtils.getAvailablePort();
|
||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||
NettyPortUnificationServer nettyPortUnificationServer = new NettyPortUnificationServer(url, new DefaultPuHandler());
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
|||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -34,7 +33,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEM
|
|||
class PortUnificationServerTest {
|
||||
|
||||
@Test
|
||||
void testBind() throws RemotingException {
|
||||
void testBind() throws Throwable {
|
||||
int port = NetUtils.getAvailablePort();
|
||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
|
|
|
|||
|
|
@ -21,15 +21,14 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
||||
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
||||
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -52,7 +51,7 @@ public class MultiplexProtocolConnectionManagerTest {
|
|||
private static ConnectionManager connectionManager;
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws RemotingException {
|
||||
public static void init() throws Throwable {
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
|
||||
applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_DEFAULT);
|
||||
|
|
@ -95,7 +94,7 @@ public class MultiplexProtocolConnectionManagerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testForEachConnection() throws RemotingException {
|
||||
public void testForEachConnection() throws Throwable {
|
||||
DefaultPuHandler handler = new DefaultPuHandler();
|
||||
|
||||
NettyPortUnificationServer server2 = new NettyPortUnificationServer(url2, handler);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.remoting.transport.netty4.NettyConnectionClient;
|
|||
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -51,7 +52,7 @@ public class SingleProtocolConnectionManagerTest {
|
|||
private static ConnectionManager connectionManager;
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws RemotingException {
|
||||
public static void init() throws Throwable {
|
||||
int port = NetUtils.getAvailablePort();
|
||||
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
|
|
|
|||
|
|
@ -160,9 +160,9 @@ public interface ResteasyContext {
|
|||
}
|
||||
}
|
||||
|
||||
default DubboContainerResponseContextImpl createContainerResponseContext(RequestFacade request, HttpResponse httpResponse, BuiltResponse jaxrsResponse, ContainerResponseFilter[] responseFilters) {
|
||||
default DubboContainerResponseContextImpl createContainerResponseContext(Object originRequest, RequestFacade request, HttpResponse httpResponse, BuiltResponse jaxrsResponse, ContainerResponseFilter[] responseFilters) {
|
||||
|
||||
NettyHttpRequest nettyHttpRequest = createNettyHttpRequest(request);
|
||||
NettyHttpRequest nettyHttpRequest = originRequest == null ? createNettyHttpRequest(request) : (NettyHttpRequest) originRequest;
|
||||
|
||||
ResponseContainerRequestContext requestContext = new ResponseContainerRequestContext(nettyHttpRequest);
|
||||
DubboContainerResponseContextImpl responseContext = new DubboContainerResponseContextImpl(nettyHttpRequest, httpResponse, jaxrsResponse,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.protocol.rest.extension.resteasy.filter;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.protocol.rest.deploy.ServiceDeployer;
|
||||
import org.apache.dubbo.rpc.protocol.rest.extension.resteasy.ResteasyContext;
|
||||
import org.apache.dubbo.rpc.protocol.rest.filter.RestRequestFilter;
|
||||
|
|
@ -30,7 +29,6 @@ import org.jboss.resteasy.specimpl.BuiltResponse;
|
|||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY;
|
||||
|
||||
|
||||
@Activate(value = "resteasy", onClass = {"javax.ws.rs.container.ContainerRequestFilter", "org.jboss.resteasy.plugins.server.netty.NettyHttpRequest", "org.jboss.resteasy.plugins.server.netty.NettyHttpResponse"}, order = Integer.MAX_VALUE - 1)
|
||||
|
|
@ -55,7 +53,8 @@ public class ResteasyRequestContainerFilterAdapter implements RestRequestFilter,
|
|||
|
||||
DubboPreMatchContainerRequestContext containerRequestContext = convertHttpRequestToContainerRequestContext(requestFacade, containerRequestFilters.toArray(new ContainerRequestFilter[0]));
|
||||
|
||||
RpcContext.getServiceContext().setObjectAttachment(RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY, containerRequestContext.getHttpRequest());
|
||||
// set resteasy request for save user`s custom request attribute
|
||||
restFilterContext.setOriginRequest(containerRequestContext.getHttpRequest());
|
||||
|
||||
try {
|
||||
BuiltResponse restResponse = containerRequestContext.filter();
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class ResteasyResponseContainerFilterAdapter implements RestResponseFilte
|
|||
DubboBuiltResponse dubboBuiltResponse = new DubboBuiltResponse(response.getResponseBody(), response.getStatus(), response.getEntityClass());
|
||||
// NettyHttpResponse wrapper
|
||||
HttpResponse httpResponse = new ResteasyNettyHttpResponse(response);
|
||||
DubboContainerResponseContextImpl containerResponseContext = createContainerResponseContext(requestFacade, httpResponse, dubboBuiltResponse, containerRequestFilters.toArray(new ContainerResponseFilter[0]));
|
||||
DubboContainerResponseContextImpl containerResponseContext = createContainerResponseContext(restFilterContext.getOriginRequest(),requestFacade, httpResponse, dubboBuiltResponse, containerRequestFilters.toArray(new ContainerResponseFilter[0]));
|
||||
containerResponseContext.filter();
|
||||
|
||||
// user reset entity
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.protocol.rest.extension.resteasy.intercept;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.protocol.rest.RestHeaderEnum;
|
||||
import org.apache.dubbo.rpc.protocol.rest.deploy.ServiceDeployer;
|
||||
|
|
@ -41,8 +40,6 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY;
|
||||
|
||||
@Activate(value = "resteasy", onClass = {"javax.ws.rs.ext.WriterInterceptorContext", "org.jboss.resteasy.plugins.server.netty.NettyHttpRequest", "org.jboss.resteasy.plugins.server.netty.NettyHttpResponse"})
|
||||
public class ResteasyWriterInterceptorAdapter implements RestResponseInterceptor, ResteasyContext {
|
||||
|
||||
|
|
@ -67,7 +64,7 @@ public class ResteasyWriterInterceptorAdapter implements RestResponseInterceptor
|
|||
return;
|
||||
}
|
||||
|
||||
NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) RpcContext.getServiceContext().getObjectAttachment(RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY);
|
||||
NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) restResponseInterceptor.getOriginRequest();
|
||||
|
||||
HttpRequest restRequest = nettyHttpRequest == null ? createNettyHttpRequest(request) : nettyHttpRequest;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,12 @@ public class ServiceInvokeRestFilter implements RestRequestFilter {
|
|||
|
||||
FullHttpRequest nettyHttpRequest = nettyRequestFacade.getRequest();
|
||||
|
||||
doHandler(nettyHttpRequest, restFilterContext.getResponse(), restFilterContext.getRequestFacade(), restFilterContext.getUrl(), restFilterContext.getServiceDeployer());
|
||||
doHandler(nettyHttpRequest,
|
||||
restFilterContext.getResponse(),
|
||||
restFilterContext.getRequestFacade(),
|
||||
restFilterContext.getUrl(),
|
||||
restFilterContext.getOriginRequest(),
|
||||
restFilterContext.getServiceDeployer());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -72,6 +77,7 @@ public class ServiceInvokeRestFilter implements RestRequestFilter {
|
|||
NettyHttpResponse nettyHttpResponse,
|
||||
RequestFacade request,
|
||||
URL url,
|
||||
Object originRequest,// resteasy request
|
||||
ServiceDeployer serviceDeployer) throws Exception {
|
||||
PathMatcher pathMatcher = RestRPCInvocationUtil.createPathMatcher(request);
|
||||
|
||||
|
|
@ -130,8 +136,12 @@ public class ServiceInvokeRestFilter implements RestRequestFilter {
|
|||
}
|
||||
|
||||
try {
|
||||
RestInterceptContext restFilterContext = new RestInterceptContext(url, request, nettyHttpResponse, serviceDeployer, result.getValue(), rpcInvocation);
|
||||
// set filter request
|
||||
restFilterContext.setOriginRequest(originRequest);
|
||||
|
||||
// invoke the intercept chain before Result write to response
|
||||
executeResponseIntercepts(url, request, nettyHttpResponse, result.getValue(), rpcInvocation, serviceDeployer);
|
||||
executeResponseIntercepts(restFilterContext);
|
||||
} catch (Exception exception) {
|
||||
logger.error("", exception.getMessage(), "", "dubbo rest protocol execute ResponseIntercepts error", exception);
|
||||
throw exception;
|
||||
|
|
@ -215,17 +225,11 @@ public class ServiceInvokeRestFilter implements RestRequestFilter {
|
|||
/**
|
||||
* execute response Intercepts
|
||||
*
|
||||
* @param url
|
||||
* @param request
|
||||
* @param nettyHttpResponse
|
||||
* @param result
|
||||
* @param rpcInvocation
|
||||
* @param serviceDeployer
|
||||
* @param restFilterContext
|
||||
* @throws Exception
|
||||
*/
|
||||
public void executeResponseIntercepts(URL url, RequestFacade request, NettyHttpResponse nettyHttpResponse, Object result, RpcInvocation rpcInvocation, ServiceDeployer serviceDeployer) throws Exception {
|
||||
public void executeResponseIntercepts(RestInterceptContext restFilterContext) throws Exception {
|
||||
|
||||
RestInterceptContext restFilterContext = new RestInterceptContext(url, request, nettyHttpResponse, serviceDeployer, result, rpcInvocation);
|
||||
|
||||
for (RestResponseInterceptor restResponseInterceptor : restResponseInterceptors) {
|
||||
|
||||
|
|
|
|||
|
|
@ -35,4 +35,8 @@ public interface FilterContext {
|
|||
boolean complete();
|
||||
|
||||
void setComplete(boolean complete);
|
||||
|
||||
Object getOriginRequest();
|
||||
|
||||
Object getOriginResponse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ public class RestFilterContext implements FilterContext {
|
|||
protected NettyHttpResponse response;
|
||||
protected ServiceDeployer serviceDeployer;
|
||||
protected boolean completed;
|
||||
protected Object originRequest;
|
||||
protected Object originResponse;
|
||||
|
||||
public RestFilterContext(URL url, RequestFacade requestFacade, NettyHttpResponse response, ServiceDeployer serviceDeployer) {
|
||||
this.url = url;
|
||||
|
|
@ -64,4 +66,25 @@ public class RestFilterContext implements FilterContext {
|
|||
public void setComplete(boolean complete) {
|
||||
this.completed = complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOriginRequest() {
|
||||
return originRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOriginResponse() {
|
||||
return originResponse;
|
||||
}
|
||||
|
||||
public void setOriginRequest(Object originRequest) {
|
||||
if (this.originRequest != null) {
|
||||
return;
|
||||
}
|
||||
this.originRequest = originRequest;
|
||||
}
|
||||
|
||||
public void setOriginResponse(Object originResponse) {
|
||||
this.originResponse = originResponse;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import org.apache.dubbo.rpc.protocol.rest.filter.ServiceInvokeRestFilter;
|
|||
import org.apache.dubbo.rpc.protocol.rest.filter.context.RestFilterContext;
|
||||
import org.apache.dubbo.rpc.protocol.rest.netty.NettyHttpResponse;
|
||||
import org.apache.dubbo.rpc.protocol.rest.request.NettyRequestFacade;
|
||||
import org.apache.dubbo.rpc.protocol.rest.request.RequestFacade;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -74,11 +73,12 @@ public class NettyHttpHandler implements HttpHandler<NettyRequestFacade, NettyHt
|
|||
|
||||
Object nettyHttpRequest = requestFacade.getRequest();
|
||||
|
||||
RestFilterContext restFilterContext = new RestFilterContext(url, requestFacade, nettyHttpResponse, serviceDeployer);
|
||||
|
||||
try {
|
||||
|
||||
// first request filter
|
||||
executeFilters(url, requestFacade, nettyHttpResponse, serviceDeployer, restRequestFilters);
|
||||
executeFilters(restFilterContext, restRequestFilters);
|
||||
|
||||
} catch (PathNoFoundException pathNoFoundException) {
|
||||
logger.error("", pathNoFoundException.getMessage(), "", "dubbo rest protocol provider path no found ,raw request is :" + nettyHttpRequest, pathNoFoundException);
|
||||
|
|
@ -97,7 +97,7 @@ public class NettyHttpHandler implements HttpHandler<NettyRequestFacade, NettyHt
|
|||
|
||||
// second response filter
|
||||
try {
|
||||
executeFilters(url, requestFacade, nettyHttpResponse, serviceDeployer, restResponseFilters);
|
||||
executeFilters(restFilterContext, restResponseFilters);
|
||||
} catch (Throwable throwable) {
|
||||
logger.error("", throwable.getMessage(), "", "dubbo rest protocol provider error ,and raw request is " + nettyHttpRequest, throwable);
|
||||
nettyHttpResponse.sendError(500, "dubbo rest invoke Internal error, message is " + throwable.getMessage() + " ,and exception type is : " + throwable.getClass()
|
||||
|
|
@ -110,13 +110,11 @@ public class NettyHttpHandler implements HttpHandler<NettyRequestFacade, NettyHt
|
|||
/**
|
||||
* execute rest filters
|
||||
*
|
||||
* @param url
|
||||
* @param requestFacade
|
||||
* @param nettyHttpResponse
|
||||
* @param restFilterContext
|
||||
* @param restFilters
|
||||
* @throws Exception
|
||||
*/
|
||||
public void executeFilters(URL url, RequestFacade requestFacade, NettyHttpResponse nettyHttpResponse, ServiceDeployer serviceDeployer, List<RestFilter> restFilters) throws Exception {
|
||||
RestFilterContext restFilterContext = new RestFilterContext(url, requestFacade, nettyHttpResponse, serviceDeployer);
|
||||
public void executeFilters(RestFilterContext restFilterContext, List<RestFilter> restFilters) throws Exception {
|
||||
|
||||
for (RestFilter restFilter : restFilters) {
|
||||
restFilter.filter(restFilterContext);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import org.apache.dubbo.rpc.protocol.rest.exception.ResteasyExceptionMapper;
|
|||
import org.apache.dubbo.rpc.protocol.rest.exception.mapper.ExceptionHandler;
|
||||
import org.apache.dubbo.rpc.protocol.rest.exception.mapper.ExceptionMapper;
|
||||
|
||||
import org.apache.dubbo.rpc.protocol.rest.filter.TraceRequestAndResponseFilter;
|
||||
import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestService;
|
||||
import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestServiceImpl;
|
||||
import org.apache.dubbo.rpc.protocol.rest.rest.HttpMethodService;
|
||||
|
|
@ -755,7 +756,7 @@ class JaxrsRestProtocolTest {
|
|||
|
||||
URL url = this.registerProvider(exportUrl, server, DemoService.class);
|
||||
|
||||
URL nettyUrl = url.addParameter(org.apache.dubbo.remoting.Constants.PAYLOAD_KEY, 1024);
|
||||
URL nettyUrl = url.addParameter(org.apache.dubbo.remoting.Constants.PAYLOAD_KEY, 1024);
|
||||
|
||||
Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
|
||||
|
||||
|
|
@ -775,6 +776,26 @@ class JaxrsRestProtocolTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testRequestAndResponseFilter() {
|
||||
DemoService server = new DemoServiceImpl();
|
||||
|
||||
URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService&extension="
|
||||
+ TraceRequestAndResponseFilter.class.getName());
|
||||
|
||||
URL nettyUrl = this.registerProvider(exportUrl, server, DemoService.class);
|
||||
|
||||
Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl));
|
||||
|
||||
DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl));
|
||||
|
||||
|
||||
Assertions.assertEquals("header-result", demoService.sayHello("hello"));
|
||||
exporter.unexport();
|
||||
}
|
||||
|
||||
|
||||
private URL registerProvider(URL url, Object impl, Class<?> interfaceClass) {
|
||||
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
|
||||
ProviderModel providerModel = new ProviderModel(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
*
|
||||
* 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.protocol.rest.filter;
|
||||
|
||||
import javax.annotation.Priority;
|
||||
import javax.ws.rs.Priorities;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.container.ContainerResponseContext;
|
||||
import javax.ws.rs.container.ContainerResponseFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
@Priority(Priorities.USER)
|
||||
public class TraceRequestAndResponseFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
|
||||
requestContext.getHeaders().add("test-response","header-result");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws
|
||||
|
||||
IOException {
|
||||
|
||||
String headerString = containerRequestContext.getHeaderString("test-response");
|
||||
containerResponseContext.setEntity(headerString);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +67,6 @@ import java.util.Set;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PACKABLE_METHOD_FACTORY;
|
||||
|
|
@ -249,7 +248,7 @@ public class TripleInvoker<T> extends AbstractInvoker<T> {
|
|||
if (methodDescriptor.isGeneric()) {
|
||||
Object[] args = new Object[3];
|
||||
args[0] = RpcUtils.getMethodName(invocation);
|
||||
args[1] = Arrays.stream(RpcUtils.getParameterTypes(invocation)).map(Class::getName).collect(Collectors.toList());
|
||||
args[1] = Arrays.stream(RpcUtils.getParameterTypes(invocation)).map(Class::getName).toArray(String[]::new);
|
||||
args[2] = RpcUtils.getArguments(invocation);
|
||||
pureArgument = args;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<!-- Fix the bug of log4j refer:https://github.com/apache/logging-log4j2/pull/608 -->
|
||||
<log4j2_version>2.20.0</log4j2_version>
|
||||
<!-- Spring boot buddy is lower than the delivery dependency package version and can only show the defined dependency version -->
|
||||
<byte-buddy.version>1.14.5</byte-buddy.version>
|
||||
<byte-buddy.version>1.14.7</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -119,7 +119,7 @@
|
|||
<maven_compiler_version>3.11.0</maven_compiler_version>
|
||||
<maven_source_version>3.2.1</maven_source_version>
|
||||
<maven_javadoc_version>3.5.0</maven_javadoc_version>
|
||||
<maven_jetty_version>9.4.51.v20230217</maven_jetty_version>
|
||||
<maven_jetty_version>9.4.52.v20230823</maven_jetty_version>
|
||||
<maven_checkstyle_version>3.2.1</maven_checkstyle_version>
|
||||
<maven_jacoco_version>0.8.10</maven_jacoco_version>
|
||||
<maven_flatten_version>1.5.0</maven_flatten_version>
|
||||
|
|
|
|||
Loading…
Reference in New Issue