Merge branch 'apache-3.2' into apache-3.3
# Conflicts: # dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java # dubbo-dependencies-bom/pom.xml # dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml # dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
This commit is contained in:
commit
fe55491d4a
|
|
@ -0,0 +1,107 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
# Please add new modules to the end of the list.
|
||||
|
||||
dubbo
|
||||
dubbo-auth
|
||||
dubbo-apache-release
|
||||
dubbo-bom
|
||||
dubbo-build-tools
|
||||
dubbo-cluster
|
||||
dubbo-common
|
||||
dubbo-compatible
|
||||
dubbo-compiler
|
||||
dubbo-config
|
||||
dubbo-config-api
|
||||
dubbo-config-spring
|
||||
dubbo-configcenter
|
||||
dubbo-configcenter-apollo
|
||||
dubbo-configcenter-nacos
|
||||
dubbo-configcenter-zookeeper
|
||||
dubbo-container
|
||||
dubbo-container-api
|
||||
dubbo-container-spring
|
||||
dubbo-core-spi
|
||||
dubbo-dependencies
|
||||
dubbo-dependencies-all
|
||||
dubbo-dependencies-bom
|
||||
dubbo-dependencies-zookeeper
|
||||
dubbo-dependencies-zookeeper-curator5
|
||||
dubbo-distribution
|
||||
dubbo-filter
|
||||
dubbo-filter-cache
|
||||
dubbo-filter-validation
|
||||
dubbo-kubernetes
|
||||
dubbo-maven-plugin
|
||||
dubbo-metadata
|
||||
dubbo-metadata-api
|
||||
dubbo-metadata-definition-protobuf
|
||||
dubbo-metadata-processor
|
||||
dubbo-metadata-report-nacos
|
||||
dubbo-metadata-report-redis
|
||||
dubbo-metadata-report-zookeeper
|
||||
dubbo-metrics
|
||||
dubbo-metrics-api
|
||||
dubbo-metrics-default
|
||||
dubbo-metrics-metadata
|
||||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-default
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
dubbo-qos-api
|
||||
dubbo-reactive
|
||||
dubbo-registry
|
||||
dubbo-registry-api
|
||||
dubbo-registry-multicast
|
||||
dubbo-registry-multiple
|
||||
dubbo-registry-nacos
|
||||
dubbo-registry-zookeeper
|
||||
dubbo-remoting
|
||||
dubbo-remoting-api
|
||||
dubbo-remoting-http
|
||||
dubbo-remoting-netty
|
||||
dubbo-remoting-netty4
|
||||
dubbo-remoting-zookeeper
|
||||
dubbo-remoting-zookeeper-curator5
|
||||
dubbo-rpc
|
||||
dubbo-rpc-api
|
||||
dubbo-rpc-dubbo
|
||||
dubbo-rpc-injvm
|
||||
dubbo-rpc-rest
|
||||
dubbo-rpc-triple
|
||||
dubbo-security
|
||||
dubbo-serialization
|
||||
dubbo-serialization-api
|
||||
dubbo-serialization-fastjson2
|
||||
dubbo-serialization-hessian2
|
||||
dubbo-serialization-jdk
|
||||
dubbo-spring-boot
|
||||
dubbo-spring-boot-actuator
|
||||
dubbo-spring-boot-actuator-compatible
|
||||
dubbo-spring-boot-autoconfigure
|
||||
dubbo-spring-boot-autoconfigure-compatible
|
||||
dubbo-spring-boot-compatible
|
||||
dubbo-spring-boot-observability-starter
|
||||
dubbo-spring-boot-starter
|
||||
dubbo-spring-security
|
||||
dubbo-xds
|
||||
|
|
@ -73,7 +73,9 @@ jobs:
|
|||
cd ./dubbo
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Pack class result"
|
||||
run: 7z a ${{ github.workspace }}/class.zip */target/classes/* -r
|
||||
run: |
|
||||
shopt -s globstar
|
||||
zip ${{ github.workspace }}/class.zip **/target/classes/* -r
|
||||
- name: "Upload class result"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
|
@ -81,7 +83,7 @@ jobs:
|
|||
path: ${{ github.workspace }}/class.zip
|
||||
- name: "Pack checkstyle file if failure"
|
||||
if: failure()
|
||||
run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
|
||||
run: zip ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
|
||||
- name: "Upload checkstyle file if failure"
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ jobs:
|
|||
run: |
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
nohup ./target/dubbo-demo-native-provider &
|
||||
nohup ./target/demo-native-provider &
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
./target/dubbo-demo-native-consumer
|
||||
./target/demo-native-consumer
|
||||
|
|
|
|||
|
|
@ -80,5 +80,16 @@
|
|||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-metrics-default</artifactId>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfigItem;
|
||||
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig;
|
||||
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ public class ConfigParser {
|
|||
private static List<URL> parseJsonArray(String rawConfig) {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
try {
|
||||
List<String> list = JsonUtils.getJson().toJavaList(rawConfig, String.class);
|
||||
List<String> list = JsonUtils.toJavaList(rawConfig, String.class);
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
list.forEach(u -> urls.add(URL.valueOf(u)));
|
||||
}
|
||||
|
|
@ -79,7 +80,7 @@ public class ConfigParser {
|
|||
}
|
||||
|
||||
private static ConfiguratorConfig parseObject(String rawConfig) {
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Map<String, Object> map = yaml.load(rawConfig);
|
||||
return ConfiguratorConfig.parseFromMap(map);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
|||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsEvent;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
import org.apache.dubbo.metrics.registry.event.type.ServiceType;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
|
|
@ -45,6 +45,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -131,8 +132,6 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
*/
|
||||
private final int reconnectTaskPeriod;
|
||||
|
||||
private final GlobalMetricsEventMulticaster eventMulticaster;
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
public AbstractDirectory(URL url) {
|
||||
|
|
@ -187,7 +186,6 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
this.reconnectTaskPeriod = configuration.getInt(RECONNECT_TASK_PERIOD, DEFAULT_RECONNECT_TASK_PERIOD);
|
||||
setRouterChain(routerChain);
|
||||
|
||||
eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -354,6 +352,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -367,6 +366,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
if (invokersInitialized) {
|
||||
refreshInvokerInternal();
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
}
|
||||
|
||||
private synchronized void refreshInvokerInternal() {
|
||||
|
|
@ -388,25 +388,18 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
invokersToRemove.removeAll(needToRemove);
|
||||
}
|
||||
|
||||
private void publishMetricsEvent(MetricsEvent event) {
|
||||
if (eventMulticaster != null) {
|
||||
eventMulticaster.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDisabledInvoker(Invoker<T> invoker) {
|
||||
publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_DISABLE));
|
||||
if (invokers.contains(invoker)) {
|
||||
disabledInvokers.add(invoker);
|
||||
removeValidInvoker(invoker);
|
||||
logger.info("Disable service address: " + invoker.getUrl() + ".");
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recoverDisabledInvoker(Invoker<T> invoker) {
|
||||
publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_RECOVER_DISABLE));
|
||||
if (disabledInvokers.remove(invoker)) {
|
||||
try {
|
||||
addValidInvoker(invoker);
|
||||
|
|
@ -415,6 +408,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
}
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
}
|
||||
|
||||
protected final void refreshRouter(BitList<Invoker<T>> newlyInvokers, Runnable switchAction) {
|
||||
|
|
@ -470,7 +464,8 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
this.invokers = invokers;
|
||||
refreshInvokerInternal();
|
||||
this.invokersInitialized = true;
|
||||
publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_CURRENT, invokers.size()));
|
||||
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
}
|
||||
|
||||
protected void destroyInvokers() {
|
||||
|
|
@ -481,14 +476,12 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
|
||||
private boolean addValidInvoker(Invoker<T> invoker) {
|
||||
publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_VALID));
|
||||
synchronized (this.validInvokers) {
|
||||
return this.validInvokers.add(invoker);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean removeValidInvoker(Invoker<T> invoker) {
|
||||
publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_UN_VALID));
|
||||
synchronized (this.validInvokers) {
|
||||
return this.validInvokers.remove(invoker);
|
||||
}
|
||||
|
|
@ -508,4 +501,29 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
private Map<ServiceType, Map<String, Integer>> getSummary() {
|
||||
Map<ServiceType, Map<String, Integer>> summaryMap = new HashMap<>();
|
||||
|
||||
summaryMap.put(ServiceType.D_VALID, groupByServiceKey(getValidInvokers()));
|
||||
summaryMap.put(ServiceType.D_DISABLE, groupByServiceKey(getDisabledInvokers()));
|
||||
summaryMap.put(ServiceType.D_TO_RECONNECT, groupByServiceKey(getInvokersToReconnect()));
|
||||
summaryMap.put(ServiceType.D_ALL, groupByServiceKey(getInvokers()));
|
||||
return summaryMap;
|
||||
}
|
||||
|
||||
private Map<String, Integer> groupByServiceKey(Collection<Invoker<T>> invokers) {
|
||||
|
||||
Map<String, Integer> serviceNumMap = new HashMap<>();
|
||||
for (Invoker<T> invoker : invokers) {
|
||||
if (invoker.getClass().getSimpleName().contains("Mockito")) {
|
||||
return serviceNumMap;
|
||||
}
|
||||
}
|
||||
if (invokers.size() > 0) {
|
||||
serviceNumMap = invokers.stream().filter(invoker -> invoker.getInterface() != null).collect(Collectors.groupingBy(invoker -> invoker.getInterface().getName(), Collectors.reducing(0, e -> 1, Integer::sum)));
|
||||
}
|
||||
|
||||
return serviceNumMap;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster.directory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -29,6 +27,8 @@ import org.apache.dubbo.rpc.cluster.RouterChain;
|
|||
import org.apache.dubbo.rpc.cluster.SingleRouterChain;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION;
|
||||
|
||||
/**
|
||||
|
|
@ -75,6 +75,8 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
|
|||
for (Invoker<T> invoker : getValidInvokers()) {
|
||||
if (invoker.isAvailable()) {
|
||||
return true;
|
||||
} else {
|
||||
addInvalidateInvoker(invoker);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.metrics.filter;
|
||||
package org.apache.dubbo.rpc.cluster.filter.support;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
|
|
@ -29,12 +30,13 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
|
||||
|
||||
@Activate(group = CONSUMER)
|
||||
@Activate(group = CONSUMER,onClass = "org.apache.dubbo.metrics.collector.DefaultMetricsCollector")
|
||||
public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
|
||||
|
||||
private DefaultMetricsCollector collector;
|
||||
|
|
@ -14,12 +14,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
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;
|
||||
|
|
@ -30,6 +31,9 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
||||
|
||||
/**
|
||||
|
|
@ -38,13 +42,17 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
|||
@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
|
||||
public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
|
||||
|
||||
private final ObservationRegistry observationRegistry;
|
||||
private ObservationRegistry observationRegistry;
|
||||
|
||||
private final DubboClientObservationConvention clientObservationConvention;
|
||||
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
|
||||
|
|
@ -52,15 +60,18 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
|
|||
if (observationRegistry == null) {
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
DubboClientContext senderContext = new DubboClientContext(invoker, invocation);
|
||||
Observation observation = DubboObservation.CLIENT.observation(this.clientObservationConvention, DefaultDubboClientObservationConvention.INSTANCE, () -> senderContext, observationRegistry);
|
||||
final DubboClientContext senderContext = new DubboClientContext(invoker, invocation);
|
||||
final Observation observation = DubboObservationDocumentation.CLIENT.observation(
|
||||
this.clientObservationConvention,
|
||||
DefaultDubboClientObservationConvention.getInstance(),
|
||||
() -> senderContext, observationRegistry);
|
||||
invocation.put(Observation.class, observation.start());
|
||||
return observation.scoped(() -> invoker.invoke(invocation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
|
||||
Observation observation = (Observation) invocation.get(Observation.class);
|
||||
final Observation observation = getObservation(invocation);
|
||||
if (observation == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -69,11 +80,15 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
|
|||
|
||||
@Override
|
||||
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
|
||||
Observation observation = (Observation) invocation.get(Observation.class);
|
||||
final Observation observation = getObservation(invocation);
|
||||
if (observation == null) {
|
||||
return;
|
||||
}
|
||||
observation.error(t);
|
||||
observation.stop();
|
||||
}
|
||||
|
||||
private Observation getObservation(Invocation invocation) {
|
||||
return (Observation) invocation.get(Observation.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.Invocation;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
|
|
@ -79,10 +80,23 @@ public class RandomLoadBalance extends AbstractLoadBalance {
|
|||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
|
||||
int offset = ThreadLocalRandom.current().nextInt(totalWeight);
|
||||
// Return an invoker based on the random value.
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (offset < weights[i]) {
|
||||
return invokers.get(i);
|
||||
if (length <= 4) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (offset < weights[i]) {
|
||||
return invokers.get(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i = Arrays.binarySearch(weights, offset);
|
||||
if (i < 0) {
|
||||
i = -i - 1;
|
||||
} else {
|
||||
while (weights[i+1] == offset) {
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return invokers.get(i);
|
||||
}
|
||||
}
|
||||
// If all invokers have the same weight value or totalWeight=0, return evenly.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.router.condition.config.model;
|
|||
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ import java.util.Map;
|
|||
public class ConditionRuleParser {
|
||||
|
||||
public static ConditionRouterRule parse(String rawRule) {
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Map<String, Object> map = yaml.load(rawRule);
|
||||
ConditionRouterRule rule = ConditionRouterRule.parseFromMap(map);
|
||||
rule.setRawRule(rawRule);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import org.apache.dubbo.common.utils.CollectionUtils;
|
|||
import org.apache.dubbo.rpc.cluster.router.mesh.util.MeshRuleDispatcher;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.util.MeshRuleListener;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
|
@ -66,9 +68,9 @@ public class MeshAppRuleListener implements ConfigurationListener {
|
|||
try {
|
||||
Map<String, List<Map<String, Object>>> groupMap = new HashMap<>();
|
||||
|
||||
Representer representer = new Representer();
|
||||
Representer representer = new Representer(new DumperOptions());
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
Yaml yaml = new Yaml(new SafeConstructor(), representer);
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()), representer);
|
||||
Iterable<Object> yamlIterator = yaml.loadAll(configInfo);
|
||||
|
||||
for (Object obj : yamlIterator) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.router.script.config.model;
|
|||
|
||||
import org.apache.dubbo.rpc.cluster.router.AbstractRouterRule;
|
||||
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ public class ScriptRule extends AbstractRouterRule {
|
|||
private String script;
|
||||
|
||||
public static ScriptRule parse(String rawRule) {
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Map<String, Object> map = yaml.load(rawRule);
|
||||
|
||||
ScriptRule rule = new ScriptRule();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.router.tag.model;
|
|||
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ import java.util.Map;
|
|||
public class TagRuleParser {
|
||||
|
||||
public static TagRouterRule parse(String rawRule) {
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Map<String, Object> map = yaml.load(rawRule);
|
||||
TagRouterRule rule = TagRouterRule.parseFromMap(map);
|
||||
rule.setRawRule(rawRule);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import java.util.List;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
|
||||
|
|
@ -47,24 +46,23 @@ import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
|||
import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
|
||||
|
||||
/**
|
||||
* A ClusterInvoker that selects between local and remote invokers at runtime.
|
||||
* ScopeClusterInvoker is a cluster invoker which handles the invocation logic of a single service in a specific scope.
|
||||
* <p>
|
||||
* It selects between local and remote invoker at runtime.
|
||||
*
|
||||
* @param <T> the type of service interface
|
||||
*/
|
||||
public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
|
||||
|
||||
private final Object createLock = new Object();
|
||||
private Protocol protocolSPI;
|
||||
private final Directory<T> directory;
|
||||
private final Invoker<T> invoker;
|
||||
private final AtomicBoolean isExported;
|
||||
private volatile Invoker<T> injvmInvoker;
|
||||
private volatile InjvmExporterListener injvmExporterListener;
|
||||
|
||||
private boolean peerFlag;
|
||||
|
||||
private boolean injvmFlag;
|
||||
|
||||
private final Object createLock = new Object();
|
||||
|
||||
|
||||
public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
|
||||
this.directory = directory;
|
||||
this.invoker = invoker;
|
||||
|
|
@ -72,30 +70,6 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
|
||||
String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
|
||||
if (peer != null && peer) {
|
||||
peerFlag = true;
|
||||
return;
|
||||
}
|
||||
if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
|
||||
injvmInvoker = invoker;
|
||||
isExported.compareAndSet(false, true);
|
||||
injvmFlag = true;
|
||||
return;
|
||||
}
|
||||
if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
|
||||
injvmFlag = true;
|
||||
} else if (isInjvm == null) {
|
||||
injvmFlag = isNotRemoteOrGeneric();
|
||||
}
|
||||
|
||||
protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
|
||||
injvmExporterListener = getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class);
|
||||
injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
return directory.getConsumerUrl();
|
||||
|
|
@ -135,62 +109,28 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
return directory.getInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current ScopeClusterInvoker is exported to the local JVM and invokes the corresponding Invoker.
|
||||
* If it's not exported locally, then it delegates the invocation to the original Invoker.
|
||||
*
|
||||
* @param invocation the invocation to be performed
|
||||
* @return the result of the invocation
|
||||
* @throws RpcException if there was an error during the invocation
|
||||
*/
|
||||
@Override
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
if (peerFlag) {
|
||||
// If it's a point-to-point direct connection, invoke the original Invoker
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
if (isInjvmExported()) {
|
||||
// If it's exported to the local JVM, invoke the corresponding Invoker
|
||||
return injvmInvoker.invoke(invocation);
|
||||
}
|
||||
// Otherwise, delegate the invocation to the original Invoker
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
|
||||
private boolean isNotRemoteOrGeneric() {
|
||||
return !SCOPE_REMOTE.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) &&
|
||||
!getUrl().getParameter(GENERIC_KEY, false);
|
||||
}
|
||||
|
||||
private boolean isInjvmExported() {
|
||||
Boolean localInvoke = RpcContext.getServiceContext().getLocalInvoke();
|
||||
boolean isExportedValue = isExported.get();
|
||||
boolean local = (localInvoke != null && localInvoke);
|
||||
// Determine whether this call is local
|
||||
if (isExportedValue && local) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine whether this call is remote
|
||||
if (localInvoke != null && !localInvoke) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When calling locally, determine whether it does not meet the requirements
|
||||
if (!isExportedValue && (SCOPE_LOCAL.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) ||
|
||||
Boolean.TRUE.toString().equalsIgnoreCase(getUrl().getParameter(LOCAL_PROTOCOL))|| local)) {
|
||||
throw new RpcException("Local service has not been exposed yet!");
|
||||
}
|
||||
|
||||
return isExportedValue && injvmFlag;
|
||||
}
|
||||
|
||||
|
||||
private void createInjvmInvoker() {
|
||||
if (injvmInvoker == null) {
|
||||
synchronized (createLock) {
|
||||
if (injvmInvoker == null) {
|
||||
URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
|
||||
url = url.setScopeModel(getUrl().getScopeModel());
|
||||
url = url.setServiceModel(getUrl().getServiceModel());
|
||||
Invoker<?> invoker = protocolSPI.refer(getInterface(), url);
|
||||
List<Invoker<?>> invokers = new ArrayList<>();
|
||||
invokers.add(invoker);
|
||||
injvmInvoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT, false).join(new StaticDirectory(url, invokers), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExporterChangeExport(Exporter<?> exporter) {
|
||||
if (isExported.get()) {
|
||||
|
|
@ -212,6 +152,103 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
}
|
||||
}
|
||||
|
||||
public Invoker<?> getInvoker() {
|
||||
return invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the ScopeClusterInvoker instance.
|
||||
*/
|
||||
private void init() {
|
||||
Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
|
||||
String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
|
||||
// When the point-to-point direct connection is directly connected,
|
||||
// the initialization is directly ended
|
||||
if (peer != null && peer) {
|
||||
peerFlag = true;
|
||||
return;
|
||||
}
|
||||
// Check if the service has been exported through Injvm protocol
|
||||
if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
|
||||
injvmInvoker = invoker;
|
||||
isExported.compareAndSet(false, true);
|
||||
injvmFlag = true;
|
||||
return;
|
||||
}
|
||||
// Check if the service has been exported through Injvm protocol or the SCOPE_LOCAL parameter is set
|
||||
if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || SCOPE_LOCAL.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
|
||||
injvmFlag = true;
|
||||
} else if (isInjvm == null) {
|
||||
injvmFlag = isNotRemoteOrGeneric();
|
||||
}
|
||||
|
||||
protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
|
||||
injvmExporterListener = getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class);
|
||||
injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the service is a generalized call or the SCOPE_REMOTE parameter is set
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean isNotRemoteOrGeneric() {
|
||||
return !SCOPE_REMOTE.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) &&
|
||||
!getUrl().getParameter(GENERIC_KEY, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current ScopeClusterInvoker is exported to the local JVM and returns a boolean value.
|
||||
*
|
||||
* @return true if the ScopeClusterInvoker is exported to the local JVM, false otherwise
|
||||
* @throws RpcException if there was an error during the invocation
|
||||
*/
|
||||
private boolean isInjvmExported() {
|
||||
Boolean localInvoke = RpcContext.getServiceContext().getLocalInvoke();
|
||||
boolean isExportedValue = isExported.get();
|
||||
boolean local = (localInvoke != null && localInvoke);
|
||||
// Determine whether this call is local
|
||||
if (isExportedValue && local) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine whether this call is remote
|
||||
if (localInvoke != null && !localInvoke) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When calling locally, determine whether it does not meet the requirements
|
||||
if (!isExportedValue && (SCOPE_LOCAL.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) ||
|
||||
Boolean.TRUE.toString().equalsIgnoreCase(getUrl().getParameter(LOCAL_PROTOCOL)) || local)) {
|
||||
// If it's supposed to be exported to the local JVM ,but it's not, throw an exception
|
||||
throw new RpcException("Local service for " + getUrl().getServiceInterface() + " has not been exposed yet!");
|
||||
}
|
||||
|
||||
return isExportedValue && injvmFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Invoker for the current ScopeClusterInvoker and exports it to the local JVM.
|
||||
*/
|
||||
private void createInjvmInvoker() {
|
||||
if (injvmInvoker == null) {
|
||||
synchronized (createLock) {
|
||||
if (injvmInvoker == null) {
|
||||
URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
|
||||
url = url.setScopeModel(getUrl().getScopeModel());
|
||||
url = url.setServiceModel(getUrl().getServiceModel());
|
||||
Invoker<?> invoker = protocolSPI.refer(getInterface(), url);
|
||||
List<Invoker<?>> invokers = new ArrayList<>();
|
||||
invokers.add(invoker);
|
||||
injvmInvoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT, false).join(new StaticDirectory(url, invokers), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the existing InjvmInvoker.
|
||||
*/
|
||||
private void destroyInjvmInvoker() {
|
||||
if (injvmInvoker != null) {
|
||||
injvmInvoker.destroy();
|
||||
|
|
@ -219,7 +256,4 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
}
|
||||
}
|
||||
|
||||
public Invoker<?> getInvoker() {
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ forking=org.apache.dubbo.rpc.cluster.support.ForkingCluster
|
|||
available=org.apache.dubbo.rpc.cluster.support.AvailableCluster
|
||||
mergeable=org.apache.dubbo.rpc.cluster.support.MergeableCluster
|
||||
broadcast=org.apache.dubbo.rpc.cluster.support.BroadcastCluster
|
||||
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
|
||||
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
|
||||
|
|
@ -1,3 +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
|
||||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig
|
|||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ class ConfigParserTest {
|
|||
@Test
|
||||
void snakeYamlBasicTest() throws IOException {
|
||||
try (InputStream yamlStream = this.getClass().getResourceAsStream("/ServiceNoApp.yml")) {
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Map<String, Object> map = yaml.load(yamlStream);
|
||||
ConfiguratorConfig config = ConfiguratorConfig.parseFromMap(map);
|
||||
Assertions.assertNotNull(config);
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ package org.apache.dubbo.rpc.cluster.directory;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.Holder;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.router.MockInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.ConditionStateRouterFactory;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -52,9 +52,9 @@ class StaticDirectoryTest {
|
|||
List<StateRouter> routers = new ArrayList<StateRouter>();
|
||||
routers.add(router);
|
||||
List<Invoker<String>> originInvokers = new ArrayList<Invoker<String>>();
|
||||
Invoker<String> invoker1 = new MockInvoker<String>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService"));
|
||||
Invoker<String> invoker2 = new MockInvoker<String>(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/com.foo.BarService"));
|
||||
Invoker<String> invoker3 = new MockInvoker<String>(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/com.foo.BarService"));
|
||||
Invoker<String> invoker1 = new MockInvoker<String>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService"), true);
|
||||
Invoker<String> invoker2 = new MockInvoker<String>(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/com.foo.BarService"), true);
|
||||
Invoker<String> invoker3 = new MockInvoker<String>(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/com.foo.BarService"), true);
|
||||
originInvokers.add(invoker1);
|
||||
originInvokers.add(invoker2);
|
||||
originInvokers.add(invoker3);
|
||||
|
|
@ -62,10 +62,10 @@ class StaticDirectoryTest {
|
|||
|
||||
|
||||
List<Invoker<String>> filteredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
StaticDirectory<String> staticDirectory = new StaticDirectory<>(filteredInvokers);
|
||||
boolean isAvailable = staticDirectory.isAvailable();
|
||||
Assertions.assertTrue(!isAvailable);
|
||||
Assertions.assertTrue(isAvailable);
|
||||
List<Invoker<String>> newInvokers = staticDirectory.list(new MockDirInvocation());
|
||||
Assertions.assertTrue(newInvokers.size() > 0);
|
||||
staticDirectory.destroy();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 io.micrometer.tracing.test.SampleTestRunner;
|
||||
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 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});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -49,7 +49,6 @@ class DefaultFilterChainBuilderTest {
|
|||
};
|
||||
|
||||
Invoker<?> invokerAfterBuild = defaultFilterChainBuilder.buildInvokerChain(invokerWithoutFilter, REFERENCE_FILTER_KEY, CONSUMER);
|
||||
Assertions.assertTrue(invokerAfterBuild instanceof AbstractInvoker);
|
||||
|
||||
// verify that if LogFilter is configured, LogFilter should exist in the filter chain
|
||||
URL urlWithFilter = URL.valueOf("injvm://127.0.0.1/DemoService")
|
||||
|
|
@ -64,8 +63,6 @@ class DefaultFilterChainBuilderTest {
|
|||
};
|
||||
invokerAfterBuild = defaultFilterChainBuilder.buildInvokerChain(invokerWithFilter, REFERENCE_FILTER_KEY, CONSUMER);
|
||||
Assertions.assertTrue(invokerAfterBuild instanceof FilterChainBuilder.CallbackRegistrationInvoker);
|
||||
Assertions.assertEquals(1, ((FilterChainBuilder.CallbackRegistrationInvoker<?, ?>) invokerAfterBuild).filters.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -84,7 +81,7 @@ class DefaultFilterChainBuilderTest {
|
|||
};
|
||||
|
||||
Invoker<?> invokerAfterBuild = defaultFilterChainBuilder.buildInvokerChain(invokerWithoutFilter, REFERENCE_FILTER_KEY, CONSUMER);
|
||||
Assertions.assertTrue(invokerAfterBuild instanceof AbstractInvoker);
|
||||
// Assertions.assertTrue(invokerAfterBuild instanceof AbstractInvoker);
|
||||
|
||||
// verify that if LogFilter is configured, LogFilter should exist in the filter chain
|
||||
URL urlWithFilter = URL.valueOf("dubbo://127.0.0.1:20880/DemoService")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* 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.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.filter.MetricsFilter;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
class MetricsClusterFilterTest {
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
private MetricsFilter filter;
|
||||
private MetricsClusterFilter metricsClusterFilter;
|
||||
private DefaultMetricsCollector collector;
|
||||
private RpcInvocation invocation;
|
||||
private final Invoker<?> invoker = mock(Invoker.class);
|
||||
|
||||
private static final String INTERFACE_NAME = "org.apache.dubbo.MockInterface";
|
||||
private static final String METHOD_NAME = "mockMethod";
|
||||
private static final String GROUP = "mockGroup";
|
||||
private static final String VERSION = "1.0.0";
|
||||
private String side;
|
||||
|
||||
private AtomicBoolean initApplication = new AtomicBoolean(false);
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
config.setName("MockMetrics");
|
||||
//RpcContext.getContext().setAttachment("MockMetrics","MockMetrics");
|
||||
|
||||
applicationModel = ApplicationModel.defaultModel();
|
||||
applicationModel.getApplicationConfigManager().setApplication(config);
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
filter = new MetricsFilter();
|
||||
|
||||
collector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class);
|
||||
if(!initApplication.get()) {
|
||||
collector.collectApplication(applicationModel);
|
||||
initApplication.set(true);
|
||||
}
|
||||
filter.setApplicationModel(applicationModel);
|
||||
side = CommonConstants.CONSUMER;
|
||||
invocation.setInvoker(new TestMetricsInvoker(side));
|
||||
RpcContext.getServiceContext().setUrl(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side=" + side));
|
||||
|
||||
metricsClusterFilter = new MetricsClusterFilter();
|
||||
metricsClusterFilter.setApplicationModel(applicationModel);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
applicationModel.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoProvider(){
|
||||
testClusterFilterError(RpcException.FORBIDDEN_EXCEPTION,
|
||||
MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED.getNameByType(CommonConstants.CONSUMER));
|
||||
}
|
||||
|
||||
private void testClusterFilterError(int errorCode,String name){
|
||||
collector.setCollectEnabled(true);
|
||||
given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode));
|
||||
initParam();
|
||||
|
||||
Long count = 1L;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
try {
|
||||
metricsClusterFilter.invoke(invoker, invocation);
|
||||
} catch (Exception e) {
|
||||
Assertions.assertTrue(e instanceof RpcException);
|
||||
metricsClusterFilter.onError(e, invoker, invocation);
|
||||
}
|
||||
}
|
||||
Map<String, MetricSample> metricsMap = getMetricsMap();
|
||||
Assertions.assertTrue(metricsMap.containsKey(name));
|
||||
|
||||
MetricSample sample = metricsMap.get(name);
|
||||
|
||||
Assertions.assertSame(((CounterMetricSample) sample).getValue().longValue(), count);
|
||||
teardown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initParam() {
|
||||
invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION);
|
||||
invocation.setMethodName(METHOD_NAME);
|
||||
invocation.setParameterTypes(new Class[]{String.class});
|
||||
}
|
||||
|
||||
private Map<String, MetricSample> getMetricsMap() {
|
||||
List<MetricSample> samples = collector.collect();
|
||||
List<MetricSample> samples1 = new ArrayList<>();
|
||||
for (MetricSample sample : samples) {
|
||||
if (sample.getName().contains("dubbo.thread.pool")) {
|
||||
continue;
|
||||
}
|
||||
samples1.add(sample);
|
||||
}
|
||||
return samples1.stream().collect(Collectors.toMap(MetricSample::getName, Function.identity()));
|
||||
}
|
||||
|
||||
public class TestMetricsInvoker implements Invoker {
|
||||
|
||||
private String side;
|
||||
|
||||
public TestMetricsInvoker(String side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
return URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side="+side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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.rpc.AttachmentsAdapter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
|
||||
|
||||
/**
|
||||
* MockInvocation.java
|
||||
*/
|
||||
public class MockInvocation extends RpcInvocation {
|
||||
|
||||
private Map<String, Object> attachments;
|
||||
|
||||
public MockInvocation() {
|
||||
attachments = new HashMap<>();
|
||||
attachments.put(PATH_KEY, "dubbo");
|
||||
attachments.put(GROUP_KEY, "dubbo");
|
||||
attachments.put(VERSION_KEY, "1.0.0");
|
||||
attachments.put(DUBBO_VERSION_KEY, "1.0.0");
|
||||
attachments.put(TOKEN_KEY, "sfag");
|
||||
attachments.put(TIMEOUT_KEY, "1000");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetServiceUniqueName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolServiceKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return "echo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return "DemoService";
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return new Class[] {String.class};
|
||||
}
|
||||
|
||||
public Object[] getArguments() {
|
||||
return new Object[] {"aa"};
|
||||
}
|
||||
|
||||
public Map<String, String> getAttachments() {
|
||||
return new AttachmentsAdapter.ObjectToStringMap(attachments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getObjectAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachment(String key, String value) {
|
||||
setObjectAttachment(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachment(String key, Object value) {
|
||||
setObjectAttachment(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectAttachment(String key, Object value) {
|
||||
attachments.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachmentIfAbsent(String key, String value) {
|
||||
setObjectAttachmentIfAbsent(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachmentIfAbsent(String key, Object value) {
|
||||
setObjectAttachmentIfAbsent(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectAttachmentIfAbsent(String key, Object value) {
|
||||
attachments.put(key, value);
|
||||
}
|
||||
|
||||
public Invoker<?> getInvoker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceModel(ServiceModel serviceModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceModel getServiceModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> getAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getAttachment(String key) {
|
||||
return (String) getObjectAttachments().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObjectAttachment(String key) {
|
||||
return attachments.get(key);
|
||||
}
|
||||
|
||||
public String getAttachment(String key, String defaultValue) {
|
||||
return (String) getObjectAttachments().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObjectAttachment(String key, Object defaultValue) {
|
||||
Object result = attachments.get(key);
|
||||
if (result == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -15,21 +15,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
package org.apache.dubbo.rpc.cluster.filter;
|
||||
|
||||
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.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 org.assertj.core.api.BDDAssertions;
|
||||
|
||||
class ObservationSenderFilterTest extends AbstractObservationFilterTest {
|
||||
|
||||
@Override
|
||||
public SampleTestRunnerConsumer yourCode() {
|
||||
public SampleTestRunner.SampleTestRunnerConsumer yourCode() {
|
||||
return (buildingBlocks, meterRegistry) -> {
|
||||
setupConfig();
|
||||
setupAttachments();
|
||||
|
|
@ -224,7 +224,7 @@ class LoadBalanceBaseTest {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonUtils.getJson().toJson(this);
|
||||
return JsonUtils.toJson(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.apache.dubbo.rpc.cluster.router.file;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
|
@ -61,7 +61,7 @@ class FileRouterEngineTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
System.setProperty(ENABLE_CONNECTIVITY_VALIDATION, "false");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.junit.jupiter.api.Assertions;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -132,7 +133,7 @@ class MeshAppRuleListenerTest {
|
|||
|
||||
List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
|
||||
assertEquals(2, rulesReceived.size());
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));
|
||||
|
||||
|
|
@ -163,7 +164,7 @@ class MeshAppRuleListenerTest {
|
|||
|
||||
List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
|
||||
assertEquals(2, rulesReceived.size());
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));
|
||||
|
||||
|
|
@ -219,7 +220,7 @@ class MeshAppRuleListenerTest {
|
|||
|
||||
List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
|
||||
assertEquals(2, rulesReceived.size());
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));
|
||||
|
||||
|
|
@ -258,7 +259,7 @@ class MeshAppRuleListenerTest {
|
|||
|
||||
List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
|
||||
assertEquals(1, rulesReceived.size());
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));
|
||||
|
||||
meshAppRuleListener.receiveConfigInfo(rule1 + "---\n" + rule4);
|
||||
|
|
@ -282,7 +283,7 @@ class MeshAppRuleListenerTest {
|
|||
@Override
|
||||
public void onRuleChange(String appName, List<Map<String, Object>> rules) {
|
||||
Assertions.assertEquals("demo-route", appName);
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rules.contains(yaml.load(rule5)));
|
||||
Assertions.assertTrue(rules.contains(yaml.load(rule6)));
|
||||
count.incrementAndGet();
|
||||
|
|
@ -303,7 +304,7 @@ class MeshAppRuleListenerTest {
|
|||
@Override
|
||||
public void onRuleChange(String appName, List<Map<String, Object>> rules) {
|
||||
Assertions.assertEquals("demo-route", appName);
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rules.contains(yaml.load(rule7)));
|
||||
Assertions.assertTrue(rules.contains(yaml.load(rule8)));
|
||||
count.incrementAndGet();
|
||||
|
|
@ -353,7 +354,7 @@ class MeshAppRuleListenerTest {
|
|||
|
||||
List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
|
||||
assertEquals(2, rulesReceived.size());
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
|
||||
Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ class MeshRuleManagerTest {
|
|||
@Override
|
||||
public void onRuleChange(String appName, List<Map<String, Object>> rules) {
|
||||
assertEquals("dubbo-demo", appName);
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
assertTrue(rules.contains(yaml.load(rule1)));
|
||||
assertTrue(rules.contains(yaml.load(rule2)));
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
|
|
@ -239,7 +240,7 @@ class MeshRuleRouterTest {
|
|||
void testRuleChange() {
|
||||
StandardMeshRuleRouter<Object> meshRuleRouter = new StandardMeshRuleRouter<>(url);
|
||||
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
List<Map<String, Object>> rules = new LinkedList<>();
|
||||
rules.add(yaml.load(rule1));
|
||||
|
||||
|
|
@ -275,7 +276,7 @@ class MeshRuleRouterTest {
|
|||
void testRoute2() {
|
||||
StandardMeshRuleRouter<Object> meshRuleRouter = new StandardMeshRuleRouter<>(url);
|
||||
|
||||
Yaml yaml = new Yaml(new SafeConstructor());
|
||||
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
|
||||
List<Map<String, Object>> rules = new LinkedList<>();
|
||||
rules.add(yaml.load(rule1));
|
||||
rules.add(yaml.load(rule2));
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
|
|
@ -107,7 +107,7 @@ class AbstractClusterInvokerTest {
|
|||
@SuppressWarnings({"unchecked"})
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("application", "abstractClusterInvokerTest");
|
||||
url = url.putAttribute(REFER_KEY, attributes);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package org.apache.dubbo.rpc.cluster.support;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
|
|
@ -72,7 +72,7 @@ class ConnectivityValidationTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
invoker1 = Mockito.mock(Invoker.class);
|
||||
invoker2 = Mockito.mock(Invoker.class);
|
||||
invoker3 = Mockito.mock(Invoker.class);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
|
|
@ -67,7 +67,7 @@ class FailoverClusterInvokerTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
dic = mock(Directory.class);
|
||||
|
||||
given(dic.getUrl()).willReturn(url);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
|
|
@ -51,7 +51,7 @@ class MockClusterInvokerTest {
|
|||
|
||||
@BeforeEach
|
||||
public void beforeMethod() {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
invokers.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
|
|
@ -48,7 +48,7 @@ class MockProviderRpcExceptionTest {
|
|||
|
||||
@BeforeEach
|
||||
public void beforeMethod() {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
invokers.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
|
||||
import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
|
|
@ -41,7 +42,9 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY;
|
||||
|
|
@ -50,6 +53,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.SCOPE_KEY;
|
||||
|
||||
|
|
@ -64,7 +68,7 @@ class ScopeClusterInvokerTest {
|
|||
|
||||
@BeforeEach
|
||||
void beforeMonth() {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class);
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -75,6 +79,9 @@ class ScopeClusterInvokerTest {
|
|||
exporters.clear();
|
||||
for (Invoker<DemoService> invoker : invokers) {
|
||||
invoker.destroy();
|
||||
if (invoker instanceof ScopeClusterInvoker) {
|
||||
Assertions.assertTrue(((ScopeClusterInvoker) invoker).isDestroyed());
|
||||
}
|
||||
}
|
||||
invokers.clear();
|
||||
}
|
||||
|
|
@ -104,7 +111,7 @@ class ScopeClusterInvokerTest {
|
|||
url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
|
||||
URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService")
|
||||
.addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()) ;
|
||||
.addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
Exporter<?> exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl));
|
||||
exporters.add(exporter);
|
||||
|
||||
|
|
@ -152,12 +159,6 @@ class ScopeClusterInvokerTest {
|
|||
url = url.addParameter(SCOPE_KEY, SCOPE_LOCAL);
|
||||
url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
|
||||
URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService")
|
||||
.addParameter(INTERFACE_KEY, DemoService.class.getName());
|
||||
injvmUrl = injvmUrl.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL).setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
Exporter<?> exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl));
|
||||
exporters.add(exporter);
|
||||
|
||||
Invoker<DemoService> cluster = getClusterInvoker(url);
|
||||
invokers.add(cluster);
|
||||
|
||||
|
|
@ -165,8 +166,22 @@ class ScopeClusterInvokerTest {
|
|||
invocation.setMethodName("doSomething4");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Assertions.assertTrue(cluster.isAvailable(), "");
|
||||
Result ret = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething4", ret.getValue());
|
||||
RpcInvocation finalInvocation = invocation;
|
||||
Assertions.assertThrows(RpcException.class, () -> cluster.invoke(finalInvocation));
|
||||
|
||||
URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService")
|
||||
.addParameter(INTERFACE_KEY, DemoService.class.getName());
|
||||
injvmUrl = injvmUrl.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL).setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
Exporter<?> exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl));
|
||||
exporters.add(exporter);
|
||||
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething4");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Assertions.assertTrue(cluster.isAvailable(), "");
|
||||
Result ret2 = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething4", ret2.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -184,13 +199,12 @@ class ScopeClusterInvokerTest {
|
|||
Invoker<DemoService> cluster = getClusterInvoker(url);
|
||||
invokers.add(cluster);
|
||||
|
||||
//Configured with mock
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething4");
|
||||
invocation.setMethodName("doSomething5");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Assertions.assertTrue(cluster.isAvailable(), "");
|
||||
Result ret = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething4", ret.getValue());
|
||||
Assertions.assertEquals("doSomething5", ret.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -221,6 +235,91 @@ class ScopeClusterInvokerTest {
|
|||
Assertions.assertFalse(((AtomicBoolean) isExported.get(cluster)).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPeerInvoke() {
|
||||
URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName());
|
||||
url = url.addParameter(REFER_KEY,
|
||||
URL.encode(PATH_KEY + "=" + DemoService.class.getName()));
|
||||
Map<String, Object> peer = new HashMap<>();
|
||||
peer.put(PEER_KEY, true);
|
||||
url = url.addAttributes(peer);
|
||||
url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
|
||||
Invoker<DemoService> cluster = getClusterInvoker(url);
|
||||
invokers.add(cluster);
|
||||
|
||||
//Configured with mock
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething6");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Result ret = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething6", ret.getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjvmUrlInvoke() {
|
||||
URL url = URL.valueOf("injvm://1.2.3.4/" + DemoService.class.getName());
|
||||
url = url.addParameter(REFER_KEY,
|
||||
URL.encode(PATH_KEY + "=" + DemoService.class.getName()));
|
||||
url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
|
||||
Invoker<DemoService> cluster = getClusterInvoker(url);
|
||||
invokers.add(cluster);
|
||||
|
||||
//Configured with mock
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething7");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Result ret = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething7", ret.getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDynamicInvoke() {
|
||||
URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName());
|
||||
url = url.addParameter(REFER_KEY,
|
||||
URL.encode(PATH_KEY + "=" + DemoService.class.getName()));
|
||||
url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
|
||||
Invoker<DemoService> cluster = getClusterInvoker(url);
|
||||
invokers.add(cluster);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething8");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Result ret1 = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething8", ret1.getValue());
|
||||
|
||||
RpcContext.getServiceContext().setLocalInvoke(true);
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething8");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
RpcInvocation finalInvocation = invocation;
|
||||
Assertions.assertThrows(RpcException.class, () -> cluster.invoke(finalInvocation));
|
||||
|
||||
URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService")
|
||||
.addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule());
|
||||
Exporter<?> exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl));
|
||||
exporters.add(exporter);
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething8");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Result ret2 = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething8", ret2.getValue());
|
||||
|
||||
RpcContext.getServiceContext().setLocalInvoke(false);
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
invocation.setMethodName("doSomething8");
|
||||
invocation.setParameterTypes(new Class[]{});
|
||||
Result ret3 = cluster.invoke(invocation);
|
||||
Assertions.assertEquals("doSomething8", ret3.getValue());
|
||||
}
|
||||
|
||||
private Invoker<DemoService> getClusterInvoker(URL url) {
|
||||
final URL durl = url.addParameter("proxy", "jdk");
|
||||
invokers.clear();
|
||||
|
|
@ -241,7 +340,10 @@ class ScopeClusterInvokerTest {
|
|||
}
|
||||
}
|
||||
};
|
||||
return new ScopeClusterInvoker<>(dic, cluster);
|
||||
ScopeClusterInvoker<DemoService> demoServiceScopeClusterInvoker = new ScopeClusterInvoker<>(dic, cluster);
|
||||
Assertions.assertNotNull(demoServiceScopeClusterInvoker.getDirectory());
|
||||
Assertions.assertNotNull(demoServiceScopeClusterInvoker.getInvoker());
|
||||
return demoServiceScopeClusterInvoker;
|
||||
}
|
||||
|
||||
public static interface DemoService {
|
||||
|
|
@ -252,6 +354,14 @@ class ScopeClusterInvokerTest {
|
|||
String doSomething3();
|
||||
|
||||
String doSomething4();
|
||||
|
||||
String doSomething5();
|
||||
|
||||
String doSomething6();
|
||||
|
||||
String doSomething7();
|
||||
|
||||
String doSomething8();
|
||||
}
|
||||
|
||||
public static class DemoServiceImpl implements DemoService {
|
||||
|
|
@ -276,6 +386,26 @@ class ScopeClusterInvokerTest {
|
|||
public String doSomething4() {
|
||||
return "doSomething4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doSomething5() {
|
||||
return "doSomething5";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doSomething6() {
|
||||
return "doSomething6";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doSomething7() {
|
||||
return "doSomething7";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doSomething8() {
|
||||
return "doSomething8";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,37 +101,4 @@
|
|||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>get-version-infos</id>
|
||||
<phase>compile</phase>
|
||||
<configuration>
|
||||
<failOnError>true</failOnError>
|
||||
<target>
|
||||
<property name="version_file"
|
||||
value="${project.build.outputDirectory}/META-INF/version"/>
|
||||
<!-- get the current version of dubbo -->
|
||||
<echo message="revision=${revision}${line.separator}" file="${version_file}"/>
|
||||
<echo message="git.commit.id=" file="${version_file}" append="true"/>
|
||||
<!-- get the latest commit id -->
|
||||
<exec executable="git" output="${version_file}" error=".git.exec.error" append="true"
|
||||
timeout="3000" failifexecutionfails="false">
|
||||
<arg line="rev-parse HEAD"/>
|
||||
</exec>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class BatchExecutorQueue<T> {
|
|||
boolean flushedOnce = false;
|
||||
while ((item = snapshot.poll()) != null) {
|
||||
if (snapshot.size() == 0) {
|
||||
i = 0;
|
||||
flushedOnce = false;
|
||||
break;
|
||||
}
|
||||
if (i == chunkSize) {
|
||||
|
|
@ -74,7 +74,7 @@ public class BatchExecutorQueue<T> {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
if ((i != 0 || !flushedOnce) && item != null) {
|
||||
if (!flushedOnce && item != null) {
|
||||
flush(item);
|
||||
}
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -18,20 +18,18 @@ package org.apache.dubbo.common;
|
|||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.CodeSource;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
|
@ -64,25 +62,38 @@ public final class Version {
|
|||
private static final Map<String, Integer> VERSION2INT = new HashMap<String, Integer>();
|
||||
|
||||
static {
|
||||
// check if there's duplicated jar
|
||||
Version.checkDuplicate(Version.class);
|
||||
|
||||
// get dubbo version and last commit id
|
||||
try {
|
||||
Properties properties =
|
||||
ConfigUtils.loadProperties(Collections.emptySet(), "META-INF/version");
|
||||
|
||||
VERSION = Optional.ofNullable(properties.getProperty("revision"))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.orElseGet(() -> getVersion(Version.class, ""));
|
||||
LATEST_COMMIT_ID = Optional.ofNullable(properties.getProperty("git.commit.id")).orElse("");
|
||||
tryLoadVersionFromResource();
|
||||
checkDuplicate();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "continue the old logic, ignore exception " + e.getMessage(), e);
|
||||
}
|
||||
if (StringUtils.isEmpty(VERSION)) {
|
||||
VERSION = getVersion(Version.class, "");
|
||||
}
|
||||
if (StringUtils.isEmpty(LATEST_COMMIT_ID)) {
|
||||
LATEST_COMMIT_ID = "";
|
||||
}
|
||||
}
|
||||
|
||||
private static void tryLoadVersionFromResource() throws IOException {
|
||||
Enumeration<URL> configLoader = Version.class.getClassLoader().getResources("META-INF/versions/dubbo-common");
|
||||
if (configLoader.hasMoreElements()) {
|
||||
URL url = configLoader.nextElement();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("revision=")) {
|
||||
VERSION = line.substring("revision=".length());
|
||||
} else if (line.startsWith("git.commit.id=")) {
|
||||
LATEST_COMMIT_ID = line.substring("git.commit.id=".length());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Version() {
|
||||
}
|
||||
|
||||
|
|
@ -266,48 +277,75 @@ public final class Version {
|
|||
return file;
|
||||
}
|
||||
|
||||
public static void checkDuplicate(Class<?> cls, boolean failOnError) {
|
||||
checkDuplicate(cls.getName().replace('.', '/') + ".class", failOnError);
|
||||
}
|
||||
|
||||
public static void checkDuplicate(Class<?> cls) {
|
||||
checkDuplicate(cls, false);
|
||||
}
|
||||
|
||||
public static void checkDuplicate(String path, boolean failOnError) {
|
||||
private static void checkDuplicate() {
|
||||
try {
|
||||
// search in caller's classloader
|
||||
Set<String> files = getResources(path);
|
||||
// duplicated jar is found
|
||||
if (files.size() > 1) {
|
||||
String error = "Duplicate class " + path + " in " + files.size() + " jar " + files;
|
||||
if (failOnError) {
|
||||
throw new IllegalStateException(error);
|
||||
} else {
|
||||
logger.error(COMMON_UNEXPECTED_EXCEPTION, "", "", error);
|
||||
}
|
||||
}
|
||||
checkArtifacts(loadArtifactIds());
|
||||
} catch (Throwable e) {
|
||||
logger.error(COMMON_UNEXPECTED_EXCEPTION, "", "", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* search resources in caller's classloader
|
||||
*/
|
||||
private static Set<String> getResources(String path) throws IOException {
|
||||
Enumeration<URL> urls = ClassUtils.getCallerClassLoader(Version.class).getResources(path);
|
||||
Set<String> files = new HashSet<String>();
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
if (url != null) {
|
||||
String file = url.getFile();
|
||||
if (StringUtils.isNotEmpty(file)) {
|
||||
files.add(file);
|
||||
private static void checkArtifacts(Set<String> artifactIds) throws IOException {
|
||||
if (!artifactIds.isEmpty()) {
|
||||
for (String artifactId : artifactIds) {
|
||||
checkArtifact(artifactId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkArtifact(String artifactId) throws IOException {
|
||||
Enumeration<URL> artifactEnumeration = Version.class.getClassLoader().getResources("META-INF/versions/" + artifactId);
|
||||
while (artifactEnumeration.hasMoreElements()) {
|
||||
URL url = artifactEnumeration.nextElement();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
String[] artifactInfo = line.split("=");
|
||||
if (artifactInfo.length == 2) {
|
||||
String key = artifactInfo[0];
|
||||
String value = artifactInfo[1];
|
||||
checkVersion(artifactId, url, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private static void checkVersion(String artifactId, URL url, String key, String value) {
|
||||
if ("revision".equals(key) && !value.equals(VERSION)) {
|
||||
String error = "Inconsistent version " + value + " found in " + artifactId + " from " + url.getPath() + ", " +
|
||||
"expected dubbo-common version is " + VERSION;
|
||||
logger.error(COMMON_UNEXPECTED_EXCEPTION, "", "", error);
|
||||
}
|
||||
if ("git.commit.id".equals(key) && !value.equals(LATEST_COMMIT_ID)) {
|
||||
String error = "Inconsistent git build commit id " + value + " found in " + artifactId + " from " + url.getPath() + ", " +
|
||||
"expected dubbo-common version is " + LATEST_COMMIT_ID;
|
||||
logger.error(COMMON_UNEXPECTED_EXCEPTION, "", "", error);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> loadArtifactIds() throws IOException {
|
||||
Enumeration<URL> artifactsEnumeration = Version.class.getClassLoader().getResources("META-INF/versions/.artifacts");
|
||||
Set<String> artifactIds = new HashSet<>();
|
||||
while (artifactsEnumeration.hasMoreElements()) {
|
||||
URL url = artifactsEnumeration.nextElement();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isEmpty(line)) {
|
||||
continue;
|
||||
}
|
||||
artifactIds.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
return artifactIds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,10 @@ public class ScopeBeanFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isDestroyed() {
|
||||
return destroyed.get();
|
||||
}
|
||||
|
||||
private void checkDestroyed() {
|
||||
if (destroyed.get()) {
|
||||
throw new IllegalStateException("ScopeBeanFactory is destroyed");
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ public interface CommonConstants {
|
|||
|
||||
String CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY = "CONSUMER_SHARED_SERVICE_EXECUTOR";
|
||||
|
||||
String INTERNAL_EXECUTOR_SERVICE_COMPONENT_KEY = "INTERNAL_SERVICE_EXECUTOR";
|
||||
|
||||
String THREADPOOL_KEY = "threadpool";
|
||||
|
||||
String THREAD_NAME_KEY = "threadname";
|
||||
|
|
@ -620,5 +618,14 @@ public interface CommonConstants {
|
|||
String ENCODE_IN_IO_THREAD_KEY = "encode.in.io";
|
||||
boolean DEFAULT_ENCODE_IN_IO_THREAD = false;
|
||||
|
||||
/**
|
||||
* @since 3.2.0
|
||||
*/
|
||||
String BYTE_ACCESSOR_KEY = "byte.accessor";
|
||||
|
||||
String PAYLOAD = "payload";
|
||||
|
||||
String DUBBO_METRICS_CONFIGCENTER_ENABLE = "dubbo.metrics.configcenter.enable";
|
||||
|
||||
Integer TRI_EXCEPTION_CODE_NOT_EXISTS = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,8 @@ public interface LoggerCodeConstants {
|
|||
|
||||
String REGISTRY_ISTIO_EXCEPTION = "1-41";
|
||||
|
||||
String REGISTRY_NACOS_SUB_LEGACY = "1-42";
|
||||
|
||||
// Cluster module 2-x
|
||||
String CLUSTER_FAILED_SITE_SELECTION = "2-1";
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,14 @@ 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 ENABLE_JVM_METRICS_KEY = "enable.jvm.metrics";
|
||||
String ENABLE_JVM_METRICS_KEY = "enable.jvm";
|
||||
|
||||
String AGGREGATION_COLLECTOR_KEY = "aggregation";
|
||||
|
||||
|
|
@ -48,6 +54,8 @@ public interface MetricsConstants {
|
|||
|
||||
String AGGREGATION_TIME_WINDOW_SECONDS_KEY = "aggregation.time.window.seconds";
|
||||
|
||||
String HISTOGRAM_ENABLED_KEY = "histogram.enabled";
|
||||
|
||||
String PROMETHEUS_EXPORTER_ENABLED_KEY = "prometheus.exporter.enabled";
|
||||
|
||||
String PROMETHEUS_EXPORTER_ENABLE_HTTP_SERVICE_DISCOVERY_KEY = "prometheus.exporter.enable.http.service.discovery";
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
*/
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface ApplicationDeployListener extends DeployListener<ApplicationModel> {
|
||||
|
||||
default void onModuleStarted(ApplicationModel applicationModel) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ package org.apache.dubbo.common.deploy;
|
|||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
public interface DeployListener<E extends ScopeModel> {
|
||||
/**
|
||||
* Useful to inject some configuration like MetricsConfig, RegistryConfig, etc.
|
||||
*/
|
||||
void onInitialize(E scopeModel);
|
||||
|
||||
void onStarting(E scopeModel);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ package org.apache.dubbo.common.deploy;
|
|||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
public class DeployListenerAdapter<E extends ScopeModel> implements DeployListener<E>{
|
||||
@Override
|
||||
public void onInitialize(E scopeModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStarting(E scopeModel) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import java.lang.reflect.Type;
|
|||
import java.util.List;
|
||||
|
||||
public class JacksonImpl extends AbstractJSONImpl {
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private volatile Object jacksonCache = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class FrameworkStatusReportService implements ScopeModelAware {
|
|||
HashMap<String, String> registration = new HashMap<>();
|
||||
registration.put("application", applicationModel.getApplicationName());
|
||||
registration.put("status", status);
|
||||
return JsonUtils.getJson().toJson(registration);
|
||||
return JsonUtils.toJson(registration);
|
||||
}
|
||||
|
||||
public String createConsumptionReport(String interfaceName, String version, String group, String status) {
|
||||
|
|
@ -86,7 +86,7 @@ public class FrameworkStatusReportService implements ScopeModelAware {
|
|||
migrationStatus.put("version", version);
|
||||
migrationStatus.put("group", group);
|
||||
migrationStatus.put("status", status);
|
||||
return JsonUtils.getJson().toJson(migrationStatus);
|
||||
return JsonUtils.toJson(migrationStatus);
|
||||
}
|
||||
|
||||
public String createMigrationStepReport(String interfaceName, String version, String group, String originStep, String newStep, String success) {
|
||||
|
|
@ -99,6 +99,6 @@ public class FrameworkStatusReportService implements ScopeModelAware {
|
|||
migrationStatus.put("originStep", originStep);
|
||||
migrationStatus.put("newStep", newStep);
|
||||
migrationStatus.put("success", success);
|
||||
return JsonUtils.getJson().toJson(migrationStatus);
|
||||
return JsonUtils.toJson(migrationStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,12 @@ import org.apache.dubbo.common.logger.LoggerFactory;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.AbstractExecutorService;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
/**
|
||||
* The most important difference between this Executor and other normal Executor is that this one doesn't manage
|
||||
|
|
@ -38,78 +39,42 @@ import java.util.concurrent.TimeUnit;
|
|||
public class ThreadlessExecutor extends AbstractExecutorService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ThreadlessExecutor.class.getName());
|
||||
|
||||
private final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
|
||||
private static final Object SHUTDOWN = new Object();
|
||||
|
||||
private CompletableFuture<?> waitingFuture;
|
||||
private final Queue<Runnable> queue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private boolean finished = false;
|
||||
|
||||
private volatile boolean waiting = true;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
public CompletableFuture<?> getWaitingFuture() {
|
||||
return waitingFuture;
|
||||
}
|
||||
|
||||
public void setWaitingFuture(CompletableFuture<?> waitingFuture) {
|
||||
this.waitingFuture = waitingFuture;
|
||||
}
|
||||
|
||||
private boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
private void setFinished(boolean finished) {
|
||||
this.finished = finished;
|
||||
}
|
||||
|
||||
public boolean isWaiting() {
|
||||
return waiting;
|
||||
}
|
||||
|
||||
private void setWaiting(boolean waiting) {
|
||||
this.waiting = waiting;
|
||||
}
|
||||
/**
|
||||
* Wait thread. It must be visible to other threads and does not need to be thread-safe
|
||||
*/
|
||||
private volatile Object waiter;
|
||||
|
||||
/**
|
||||
* Waits until there is a task, executes the task and all queued tasks (if there're any). The task is either a normal
|
||||
* response or a timeout response.
|
||||
*/
|
||||
public void waitAndDrain() throws InterruptedException {
|
||||
/**
|
||||
* Usually, {@link #waitAndDrain()} will only get called once. It blocks for the response for the first time,
|
||||
* once the response (the task) reached and being executed waitAndDrain will return, the whole request process
|
||||
* then finishes. Subsequent calls on {@link #waitAndDrain()} (if there're any) should return immediately.
|
||||
*
|
||||
* There's no need to worry that {@link #finished} is not thread-safe. Checking and updating of
|
||||
* 'finished' only appear in waitAndDrain, since waitAndDrain is binding to one RPC call (one thread), the call
|
||||
* of it is totally sequential.
|
||||
*/
|
||||
if (isFinished()) {
|
||||
return;
|
||||
throwIfInterrupted();
|
||||
Runnable runnable = queue.poll();
|
||||
if (runnable == null) {
|
||||
waiter = Thread.currentThread();
|
||||
try {
|
||||
while ((runnable = queue.poll()) == null) {
|
||||
LockSupport.park(this);
|
||||
throwIfInterrupted();
|
||||
}
|
||||
} finally {
|
||||
waiter = null;
|
||||
}
|
||||
}
|
||||
|
||||
Runnable runnable;
|
||||
try {
|
||||
runnable = queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
setWaiting(false);
|
||||
throw e;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
setWaiting(false);
|
||||
do {
|
||||
runnable.run();
|
||||
}
|
||||
} while ((runnable = queue.poll()) != null);
|
||||
}
|
||||
|
||||
runnable = queue.poll();
|
||||
while (runnable != null) {
|
||||
runnable.run();
|
||||
runnable = queue.poll();
|
||||
private static void throwIfInterrupted() throws InterruptedException {
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
// mark the status of ThreadlessExecutor as finished.
|
||||
setFinished(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -120,26 +85,15 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
*/
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
runnable = new RunnableWrapper(runnable);
|
||||
synchronized (lock) {
|
||||
if (!isWaiting()) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
queue.add(runnable);
|
||||
RunnableWrapper run = new RunnableWrapper(runnable);
|
||||
queue.add(run);
|
||||
if (waiter != SHUTDOWN) {
|
||||
LockSupport.unpark((Thread) waiter);
|
||||
} else if (queue.remove(run)) {
|
||||
throw new RejectedExecutionException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tells the thread blocking on {@link #waitAndDrain()} to return, despite of the current status, to avoid endless waiting.
|
||||
*/
|
||||
public void notifyReturn(Throwable t) {
|
||||
// an empty runnable task.
|
||||
execute(() -> {
|
||||
waitingFuture.completeExceptionally(t);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The following methods are still not supported
|
||||
*/
|
||||
|
|
@ -151,23 +105,26 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
|
||||
@Override
|
||||
public List<Runnable> shutdownNow() {
|
||||
notifyReturn(new IllegalStateException("Consumer is shutting down and this call is going to be stopped without " +
|
||||
"receiving any result, usually this is called by a slow provider instance or bad service implementation."));
|
||||
waiter = SHUTDOWN;
|
||||
Runnable runnable;
|
||||
while ((runnable = queue.poll()) != null) {
|
||||
runnable.run();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShutdown() {
|
||||
return false;
|
||||
return waiter == SHUTDOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTerminated() {
|
||||
return false;
|
||||
return isShutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
|
||||
public boolean awaitTermination(long timeout, TimeUnit unit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,11 +30,13 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceDescriptor;
|
||||
import org.apache.dubbo.rpc.executor.DefaultExecutorSupport;
|
||||
import org.apache.dubbo.rpc.executor.ExecutorSupport;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -50,7 +52,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_EXPORT_T
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_REFER_THREAD_NUM;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERNAL_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;
|
||||
|
|
@ -64,6 +65,8 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXP
|
|||
public class DefaultExecutorRepository implements ExecutorRepository, ExtensionAccessorAware {
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DefaultExecutorRepository.class);
|
||||
|
||||
private static final String MAX_KEY = String.valueOf(Integer.MAX_VALUE);
|
||||
|
||||
private volatile ScheduledExecutorService serviceExportExecutor;
|
||||
|
||||
private volatile ExecutorService serviceReferExecutor;
|
||||
|
|
@ -131,16 +134,34 @@ public class DefaultExecutorRepository implements ExecutorRepository, ExtensionA
|
|||
}
|
||||
}
|
||||
|
||||
private String getExecutorSecondKey(ServiceModel serviceModel, URL url) {
|
||||
if (serviceModel instanceof ConsumerModel) {
|
||||
return getConsumerKey(serviceModel);
|
||||
} else {
|
||||
return getProviderKey((ProviderModel) serviceModel, url);
|
||||
}
|
||||
}
|
||||
|
||||
private String getConsumerKey(URL url) {
|
||||
// Consumer's executor is sharing globally, key=Integer.MAX_VALUE
|
||||
return String.valueOf(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private String getConsumerKey(ServiceModel serviceModel) {
|
||||
// Consumer's executor is sharing globally, key=Integer.MAX_VALUE
|
||||
return MAX_KEY;
|
||||
}
|
||||
|
||||
protected String getProviderKey(URL url) {
|
||||
// Provider's executor is sharing by protocol.
|
||||
return String.valueOf(url.getPort());
|
||||
}
|
||||
|
||||
protected String getProviderKey(ProviderModel providerModel, URL url) {
|
||||
// Provider's executor is sharing by protocol.
|
||||
return String.valueOf(url.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the executor key based on the type (internal or biz) of the current service.
|
||||
*
|
||||
|
|
@ -148,18 +169,18 @@ public class DefaultExecutorRepository implements ExecutorRepository, ExtensionA
|
|||
* @return
|
||||
*/
|
||||
private String getExecutorKey(URL url) {
|
||||
String executorKey = INTERNAL_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
ServiceDescriptor serviceDescriptor = applicationModel.getInternalModule().getServiceRepository().lookupService(url.getServiceInterface());
|
||||
// if not found in internal service repository, then it's biz service defined by user.
|
||||
if (serviceDescriptor == null) {
|
||||
executorKey = EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
|
||||
}
|
||||
|
||||
if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) {
|
||||
executorKey = CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
return CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
}
|
||||
return EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
}
|
||||
|
||||
private String getExecutorKey(ServiceModel serviceModel) {
|
||||
if (serviceModel instanceof ProviderModel) {
|
||||
return EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
} else {
|
||||
return CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
}
|
||||
return executorKey;
|
||||
}
|
||||
|
||||
protected ExecutorService createExecutor(URL url) {
|
||||
|
|
@ -197,6 +218,37 @@ public class DefaultExecutorRepository implements ExecutorRepository, ExtensionA
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutorService getExecutor(ServiceModel serviceModel, URL url) {
|
||||
Map<String, ExecutorService> executors = data.get(getExecutorKey(serviceModel));
|
||||
|
||||
/*
|
||||
* It's guaranteed that this method is called after {@link #createExecutorIfAbsent(URL)}, so data should already
|
||||
* have Executor instances generated and stored.
|
||||
*/
|
||||
if (executors == null) {
|
||||
logger.warn(COMMON_EXECUTORS_NO_FOUND, "", "", "No available executors, this is not expected, framework should call createExecutorIfAbsent first" +
|
||||
"before coming to here.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Consumer's executor is sharing globally, key=Integer.MAX_VALUE. Provider's executor is sharing by protocol.
|
||||
String executorCacheKey = getExecutorSecondKey(serviceModel, url);
|
||||
ExecutorService executor = executors.get(executorCacheKey);
|
||||
if (executor != null && (executor.isShutdown() || executor.isTerminated())) {
|
||||
executors.remove(executorCacheKey);
|
||||
// Does not re-create a shutdown executor, use SHARED_EXECUTOR for downgrade.
|
||||
executor = null;
|
||||
logger.info("Executor for " + url + " is shutdown.");
|
||||
}
|
||||
if (executor == null) {
|
||||
return frameworkExecutorRepository.getSharedExecutor();
|
||||
} else {
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateThreadpool(URL url, ExecutorService executor) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -22,19 +22,20 @@ import org.apache.dubbo.common.extension.ExtensionScope;
|
|||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.executor.ExecutorSupport;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_DEFAULT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SPI(value = "default", scope = ExtensionScope.APPLICATION)
|
||||
@SPI(value = "isolation", scope = ExtensionScope.APPLICATION)
|
||||
public interface ExecutorRepository {
|
||||
|
||||
/**
|
||||
|
|
@ -54,6 +55,8 @@ public interface ExecutorRepository {
|
|||
*/
|
||||
ExecutorService getExecutor(URL url);
|
||||
|
||||
ExecutorService getExecutor(ServiceModel serviceModel, URL url);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -187,7 +190,7 @@ public interface ExecutorRepository {
|
|||
|
||||
static String getMode(ApplicationModel applicationModel) {
|
||||
Optional<ApplicationConfig> optional = applicationModel.getApplicationConfigManager().getApplication();
|
||||
return optional.map(ApplicationConfig::getExecutorManagementMode).orElse(EXECUTOR_MANAGEMENT_MODE_DEFAULT);
|
||||
return optional.map(ApplicationConfig::getExecutorManagementMode).orElse(EXECUTOR_MANAGEMENT_MODE_ISOLATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
|
@ -56,6 +57,8 @@ public class FrameworkExecutorRepository implements Disposable {
|
|||
|
||||
private final Ring<ExecutorService> executorServiceRing = new Ring<>();
|
||||
|
||||
private final ExecutorService internalServiceExecutor;
|
||||
|
||||
public FrameworkExecutorRepository() {
|
||||
sharedExecutor = Executors.newCachedThreadPool(new NamedThreadFactory("Dubbo-framework-shared-handler", true));
|
||||
sharedScheduledExecutor = Executors.newScheduledThreadPool(8, new NamedThreadFactory("Dubbo-framework-shared-scheduler", true));
|
||||
|
|
@ -89,6 +92,9 @@ public class FrameworkExecutorRepository implements Disposable {
|
|||
}
|
||||
|
||||
metadataRetryExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-framework-metadata-retry"));
|
||||
internalServiceExecutor = new ThreadPoolExecutor(0, 100, 60L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<>(), new NamedInternalThreadFactory("Dubbo-internal-service", true),
|
||||
new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -122,6 +128,10 @@ public class FrameworkExecutorRepository implements Disposable {
|
|||
return metadataRetryExecutor;
|
||||
}
|
||||
|
||||
public ExecutorService getInternalServiceExecutor() {
|
||||
return internalServiceExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default shared thread pool.
|
||||
*
|
||||
|
|
@ -177,6 +187,7 @@ public class FrameworkExecutorRepository implements Disposable {
|
|||
logger.info("destroying framework executor repository ..");
|
||||
shutdownExecutorService(poolRouterExecutor, "poolRouterExecutor");
|
||||
shutdownExecutorService(metadataRetryExecutor, "metadataRetryExecutor");
|
||||
shutdownExecutorService(internalServiceExecutor, "internalServiceExecutor");
|
||||
|
||||
// scheduledExecutors
|
||||
shutdownExecutorServices(scheduledExecutors.listItems(), "scheduledExecutors");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.rpc.executor.ExecutorSupport;
|
||||
import org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
|
@ -52,6 +53,15 @@ public class IsolationExecutorRepository extends DefaultExecutorRepository {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProviderKey(ProviderModel providerModel, URL url) {
|
||||
if (url.getAttributes().containsKey(SERVICE_EXECUTOR)) {
|
||||
return providerModel.getServiceKey();
|
||||
} else {
|
||||
return super.getProviderKey(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExecutorService createExecutor(URL url) {
|
||||
Object executor = url.getAttributes().get(SERVICE_EXECUTOR);
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ public class HashedWheelTimer implements Timer {
|
|||
private static void reportTooManyInstances() {
|
||||
String resourceType = ClassUtils.simpleClassName(HashedWheelTimer.class);
|
||||
logger.error(COMMON_ERROR_TOO_MANY_INSTANCES, "", "", "You are creating too many " + resourceType + " instances. " +
|
||||
resourceType + " is a shared resource that must be reused across the JVM," +
|
||||
resourceType + " is a shared resource that must be reused across the JVM, " +
|
||||
"so that only a few instances are created.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -994,7 +994,13 @@ public class URLParam {
|
|||
Map<String, Map<String, String>> methodParameters = new HashMap<>(capacity);
|
||||
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParameter(keyBit, valueMap, extraParam, methodParameters, entry.getKey(), entry.getValue(), false);
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
addParameter(keyBit, valueMap, extraParam, methodParameters, key, value, false);
|
||||
// compatible with lower versions registering "default." keys
|
||||
if (key.startsWith(DEFAULT_KEY_PREFIX)) {
|
||||
addParameter(keyBit, valueMap, extraParam, methodParameters, key.substring(DEFAULT_KEY_PREFIX.length()), value, true);
|
||||
}
|
||||
}
|
||||
return new URLParam(keyBit, valueMap, extraParam, methodParameters, rawParam);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -74,20 +74,20 @@ public class ClassUtils {
|
|||
* @since 2.7.6
|
||||
*/
|
||||
public static final Set<Class<?>> SIMPLE_TYPES = ofSet(
|
||||
Void.class,
|
||||
Boolean.class,
|
||||
Character.class,
|
||||
Byte.class,
|
||||
Short.class,
|
||||
Integer.class,
|
||||
Long.class,
|
||||
Float.class,
|
||||
Double.class,
|
||||
String.class,
|
||||
BigDecimal.class,
|
||||
BigInteger.class,
|
||||
Date.class,
|
||||
Object.class
|
||||
Void.class,
|
||||
Boolean.class,
|
||||
Character.class,
|
||||
Byte.class,
|
||||
Short.class,
|
||||
Integer.class,
|
||||
Long.class,
|
||||
Float.class,
|
||||
Double.class,
|
||||
String.class,
|
||||
BigDecimal.class,
|
||||
BigInteger.class,
|
||||
Date.class,
|
||||
Object.class
|
||||
);
|
||||
/**
|
||||
* Prefix for internal array class names: "[L"
|
||||
|
|
@ -118,8 +118,8 @@ public class ClassUtils {
|
|||
Set<Class<?>> primitiveTypeNames = new HashSet<>(32);
|
||||
primitiveTypeNames.addAll(PRIMITIVE_WRAPPER_TYPE_MAP.values());
|
||||
primitiveTypeNames.addAll(Arrays
|
||||
.asList(boolean[].class, byte[].class, char[].class, double[].class,
|
||||
float[].class, int[].class, long[].class, short[].class));
|
||||
.asList(boolean[].class, byte[].class, char[].class, double[].class,
|
||||
float[].class, int[].class, long[].class, short[].class));
|
||||
for (Class<?> primitiveTypeName : primitiveTypeNames) {
|
||||
PRIMITIVE_TYPE_NAME_MAP.put(primitiveTypeName.getName(), primitiveTypeName);
|
||||
}
|
||||
|
|
@ -137,12 +137,12 @@ public class ClassUtils {
|
|||
private static final char PACKAGE_SEPARATOR_CHAR = '.';
|
||||
|
||||
public static Class<?> forNameWithThreadContextClassLoader(String name)
|
||||
throws ClassNotFoundException {
|
||||
throws ClassNotFoundException {
|
||||
return forName(name, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
public static Class<?> forNameWithCallerClassLoader(String name, Class<?> caller)
|
||||
throws ClassNotFoundException {
|
||||
throws ClassNotFoundException {
|
||||
return forName(name, caller.getClassLoader());
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ public class ClassUtils {
|
|||
* @see Class#forName(String, boolean, ClassLoader)
|
||||
*/
|
||||
public static Class<?> forName(String name, ClassLoader classLoader)
|
||||
throws ClassNotFoundException, LinkageError {
|
||||
throws ClassNotFoundException, LinkageError {
|
||||
|
||||
Class<?> clazz = resolvePrimitiveClassName(name);
|
||||
if (clazz != null) {
|
||||
|
|
@ -244,7 +244,7 @@ public class ClassUtils {
|
|||
String elementClassName = null;
|
||||
if (internalArrayMarker == 0) {
|
||||
elementClassName = name
|
||||
.substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 1);
|
||||
.substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 1);
|
||||
} else if (name.startsWith("[")) {
|
||||
elementClassName = name.substring(1);
|
||||
}
|
||||
|
|
@ -354,7 +354,7 @@ public class ClassUtils {
|
|||
*/
|
||||
public static boolean isTypeMatch(Class<?> type, String value) {
|
||||
if ((type == boolean.class || type == Boolean.class)
|
||||
&& !("true".equals(value) || "false".equals(value))) {
|
||||
&& !("true".equals(value) || "false".equals(value))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -408,18 +408,18 @@ public class ClassUtils {
|
|||
if (isNotEmpty(interfaces)) {
|
||||
// add current interfaces
|
||||
Arrays.stream(interfaces)
|
||||
.filter(resolved::add)
|
||||
.forEach(cls -> {
|
||||
allInterfaces.add(cls);
|
||||
waitResolve.add(cls);
|
||||
});
|
||||
.filter(resolved::add)
|
||||
.forEach(cls -> {
|
||||
allInterfaces.add(cls);
|
||||
waitResolve.add(cls);
|
||||
});
|
||||
}
|
||||
|
||||
// add all super classes to waitResolve
|
||||
getAllSuperClasses(clazz)
|
||||
.stream()
|
||||
.filter(resolved::add)
|
||||
.forEach(waitResolve::add);
|
||||
.stream()
|
||||
.filter(resolved::add)
|
||||
.forEach(waitResolve::add);
|
||||
|
||||
clazz = waitResolve.poll();
|
||||
}
|
||||
|
|
@ -535,7 +535,7 @@ public class ClassUtils {
|
|||
}
|
||||
Method[] methods = Arrays.stream(tClass.getMethods())
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new Method[] {});
|
||||
.toArray(new Method[]{});
|
||||
List<String> mns = new ArrayList<>(); // method names.
|
||||
boolean hasMethod = hasMethods(methods);
|
||||
if (hasMethod) {
|
||||
|
|
@ -551,6 +551,44 @@ public class ClassUtils {
|
|||
return mns.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static boolean isMatch(Class<?> from, Class<?> to) {
|
||||
if (from == to) {
|
||||
return true;
|
||||
}
|
||||
boolean isMatch;
|
||||
if (from.isPrimitive()) {
|
||||
isMatch = matchPrimitive(from, to);
|
||||
} else if (to.isPrimitive()) {
|
||||
isMatch = matchPrimitive(to, from);
|
||||
} else {
|
||||
isMatch = to.isAssignableFrom(from);
|
||||
}
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
private static boolean matchPrimitive(Class<?> from, Class<?> to) {
|
||||
if (from == boolean.class) {
|
||||
return to == Boolean.class;
|
||||
} else if (from == byte.class) {
|
||||
return to == Byte.class;
|
||||
} else if (from == char.class) {
|
||||
return to == Character.class;
|
||||
} else if (from == short.class) {
|
||||
return to == Short.class;
|
||||
} else if (from == int.class) {
|
||||
return to == Integer.class;
|
||||
} else if (from == long.class) {
|
||||
return to == Long.class;
|
||||
} else if (from == float.class) {
|
||||
return to == Float.class;
|
||||
} else if (from == double.class) {
|
||||
return to == Double.class;
|
||||
} else if (from == void.class) {
|
||||
return to == Void.class;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get method name array.
|
||||
*
|
||||
|
|
@ -562,7 +600,7 @@ public class ClassUtils {
|
|||
}
|
||||
Method[] methods = Arrays.stream(tClass.getMethods())
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new Method[] {});
|
||||
.toArray(new Method[]{});
|
||||
List<String> dmns = new ArrayList<>(); // method names.
|
||||
boolean hasMethod = hasMethods(methods);
|
||||
if (hasMethod) {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public enum JRE {
|
|||
return OTHER;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug("can't determine current JRE version, if JRE version is 8 but java.version is null", e);
|
||||
logger.debug("Can't determine current JRE version (maybe java.version is null), assuming that JRE version is 8.", e);
|
||||
}
|
||||
// default java 8
|
||||
return JAVA_8;
|
||||
|
|
|
|||
|
|
@ -23,13 +23,16 @@ import org.apache.dubbo.common.json.impl.FastJsonImpl;
|
|||
import org.apache.dubbo.common.json.impl.GsonImpl;
|
||||
import org.apache.dubbo.common.json.impl.JacksonImpl;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonUtils {
|
||||
|
||||
private static volatile JSON json;
|
||||
|
||||
public static JSON getJson() {
|
||||
protected static JSON getJson() {
|
||||
if (json == null) {
|
||||
synchronized (JsonUtils.class) {
|
||||
if (json == null) {
|
||||
|
|
@ -86,4 +89,76 @@ public class JsonUtils {
|
|||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated for uts only
|
||||
*/
|
||||
@Deprecated
|
||||
protected static void setJson(JSON json) {
|
||||
JsonUtils.json = json;
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(String json, Type type) {
|
||||
return getJson().toJavaObject(json, type);
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> toJavaList(String json, Class<T> clazz) {
|
||||
return getJson().toJavaList(json, clazz);
|
||||
}
|
||||
|
||||
|
||||
public static String toJson(Object obj) {
|
||||
return getJson().toJson(obj);
|
||||
}
|
||||
|
||||
|
||||
public static List<?> getList(Map<String, ?> obj, String key) {
|
||||
return getJson().getList(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static List<Map<String, ?>> getListOfObjects(Map<String, ?> obj, String key) {
|
||||
return getJson().getListOfObjects(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static List<String> getListOfStrings(Map<String, ?> obj, String key) {
|
||||
return getJson().getListOfStrings(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, ?> getObject(Map<String, ?> obj, String key) {
|
||||
return getJson().getObject(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static Double getNumberAsDouble(Map<String, ?> obj, String key) {
|
||||
return getJson().getNumberAsDouble(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static Integer getNumberAsInteger(Map<String, ?> obj, String key) {
|
||||
return getJson().getNumberAsInteger(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static Long getNumberAsLong(Map<String, ?> obj, String key) {
|
||||
return getJson().getNumberAsLong(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static String getString(Map<String, ?> obj, String key) {
|
||||
return getJson().getString(obj, key);
|
||||
}
|
||||
|
||||
|
||||
public static List<Map<String, ?>> checkObjectList(List<?> rawList) {
|
||||
return getJson().checkObjectList(rawList);
|
||||
}
|
||||
|
||||
|
||||
public static List<String> checkStringList(List<?> rawList) {
|
||||
return getJson().checkStringList(rawList);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.logger.support.FailsafeLogger;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
|
|
@ -251,6 +250,8 @@ public final class NetUtils {
|
|||
|
||||
private static volatile String HOST_ADDRESS;
|
||||
|
||||
private static volatile String HOST_NAME;
|
||||
|
||||
private static volatile String HOST_ADDRESS_V6;
|
||||
|
||||
public static String getLocalHost() {
|
||||
|
|
@ -585,11 +586,15 @@ public final class NetUtils {
|
|||
}
|
||||
|
||||
public static String getLocalHostName() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
return getLocalAddress().getHostName();
|
||||
if (HOST_NAME != null) {
|
||||
return HOST_NAME;
|
||||
}
|
||||
try {
|
||||
HOST_NAME= InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
HOST_NAME= Optional.ofNullable(getLocalAddress()).map(k->k.getHostName()).orElse(null);
|
||||
}
|
||||
return HOST_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ public interface PathUtils {
|
|||
paths.addAll(asList(subPaths));
|
||||
|
||||
return normalize(paths.stream()
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.collect(Collectors.joining(SLASH)));
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.collect(Collectors.joining(SLASH)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -67,7 +67,6 @@ public interface PathUtils {
|
|||
while (normalizedPath.contains("//")) {
|
||||
normalizedPath = replace(normalizedPath, "//", "/");
|
||||
}
|
||||
|
||||
return normalizedPath;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
|
@ -53,11 +59,6 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_REFLECTIVE_OPERATION_FAILED;
|
||||
import static org.apache.dubbo.common.utils.ClassUtils.isAssignableFrom;
|
||||
|
||||
|
|
@ -78,13 +79,15 @@ import static org.apache.dubbo.common.utils.ClassUtils.isAssignableFrom;
|
|||
public class PojoUtils {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(PojoUtils.class);
|
||||
private static final ConcurrentMap<String, Method> NAME_METHODS_CACHE = new ConcurrentHashMap<String, Method>();
|
||||
private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<Class<?>, ConcurrentMap<String, Field>>();
|
||||
private static final ConcurrentMap<String, Method> NAME_METHODS_CACHE = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private static final ConcurrentMap<String, Object> CLASS_NOT_FOUND_CACHE = new ConcurrentHashMap<String, Object>();
|
||||
private static final ConcurrentMap<String, Object> CLASS_NOT_FOUND_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Object NOT_FOUND_VALUE = new Object();
|
||||
private static final boolean GENERIC_WITH_CLZ = Boolean.parseBoolean(ConfigurationUtils.getProperty(CommonConstants.GENERIC_WITH_CLZ_KEY, "true"));
|
||||
private static final boolean GENERIC_WITH_CLZ = Boolean.parseBoolean(
|
||||
ConfigurationUtils.getProperty(ApplicationModel.defaultModel(), CommonConstants.GENERIC_WITH_CLZ_KEY, "true"));
|
||||
|
||||
private static final List<Class<?>> CLASS_CAN_BE_STRING = Arrays.asList(Byte.class, Short.class, Integer.class,
|
||||
Long.class, Float.class, Double.class, Boolean.class, Character.class);
|
||||
|
||||
|
|
@ -121,7 +124,7 @@ public class PojoUtils {
|
|||
}
|
||||
|
||||
public static Object generalize(Object pojo) {
|
||||
return generalize(pojo, new IdentityHashMap<Object, Object>());
|
||||
return generalize(pojo, new IdentityHashMap<>());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
@ -173,7 +176,7 @@ public class PojoUtils {
|
|||
if (pojo instanceof Collection<?>) {
|
||||
Collection<Object> src = (Collection<Object>) pojo;
|
||||
int len = src.size();
|
||||
Collection<Object> dest = (pojo instanceof List<?>) ? new ArrayList<Object>(len) : new HashSet<Object>(len);
|
||||
Collection<Object> dest = (pojo instanceof List<?>) ? new ArrayList<>(len) : new HashSet<>(len);
|
||||
history.put(pojo, dest);
|
||||
for (Object obj : src) {
|
||||
dest.add(generalize(obj, history));
|
||||
|
|
@ -189,7 +192,7 @@ public class PojoUtils {
|
|||
}
|
||||
return dest;
|
||||
}
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
history.put(pojo, map);
|
||||
if (GENERIC_WITH_CLZ) {
|
||||
map.put("class", pojo.getClass().getName());
|
||||
|
|
@ -228,16 +231,16 @@ public class PojoUtils {
|
|||
}
|
||||
|
||||
public static Object realize(Object pojo, Class<?> type) {
|
||||
return realize0(pojo, type, null, new IdentityHashMap<Object, Object>());
|
||||
return realize0(pojo, type, null, new IdentityHashMap<>());
|
||||
}
|
||||
|
||||
public static Object realize(Object pojo, Class<?> type, Type genericType) {
|
||||
return realize0(pojo, type, genericType, new IdentityHashMap<Object, Object>());
|
||||
return realize0(pojo, type, genericType, new IdentityHashMap<>());
|
||||
}
|
||||
|
||||
private static class PojoInvocationHandler implements InvocationHandler {
|
||||
|
||||
private Map<Object, Object> map;
|
||||
private final Map<Object, Object> map;
|
||||
|
||||
public PojoInvocationHandler(Map<Object, Object> map) {
|
||||
this.map = map;
|
||||
|
|
@ -259,7 +262,7 @@ public class PojoUtils {
|
|||
value = map.get(methodName.substring(0, 1).toLowerCase() + methodName.substring(1));
|
||||
}
|
||||
if (value instanceof Map<?, ?> && !Map.class.isAssignableFrom(method.getReturnType())) {
|
||||
value = realize0((Map<String, Object>) value, method.getReturnType(), null, new IdentityHashMap<Object, Object>());
|
||||
value = realize0(value, method.getReturnType(), null, new IdentityHashMap<>());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
@ -268,10 +271,10 @@ public class PojoUtils {
|
|||
@SuppressWarnings("unchecked")
|
||||
private static Collection<Object> createCollection(Class<?> type, int len) {
|
||||
if (type.isAssignableFrom(ArrayList.class)) {
|
||||
return new ArrayList<Object>(len);
|
||||
return new ArrayList<>(len);
|
||||
}
|
||||
if (type.isAssignableFrom(HashSet.class)) {
|
||||
return new HashSet<Object>(len);
|
||||
return new HashSet<>(len);
|
||||
}
|
||||
if (!type.isInterface() && !Modifier.isAbstract(type.getModifiers())) {
|
||||
try {
|
||||
|
|
@ -280,7 +283,7 @@ public class PojoUtils {
|
|||
// ignore
|
||||
}
|
||||
}
|
||||
return new ArrayList<Object>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private static Map createMap(Map src) {
|
||||
|
|
@ -318,7 +321,7 @@ public class PojoUtils {
|
|||
}
|
||||
|
||||
if (result == null) {
|
||||
result = new HashMap<Object, Object>();
|
||||
result = new HashMap<>();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -326,6 +329,10 @@ public class PojoUtils {
|
|||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static Object realize0(Object pojo, Class<?> type, Type genericType, final Map<Object, Object> history) {
|
||||
return realize1(pojo, type, genericType, new HashMap<>(8), history);
|
||||
}
|
||||
|
||||
private static Object realize1(Object pojo, Class<?> type, Type genericType, final Map<String, Type> mapParent, final Map<Object, Object> history) {
|
||||
if (pojo == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -349,6 +356,19 @@ public class PojoUtils {
|
|||
|
||||
history.put(pojo, pojo);
|
||||
|
||||
Map<String, Type> mapGeneric = new HashMap<>(8);
|
||||
mapGeneric.putAll(mapParent);
|
||||
TypeVariable<? extends Class<?>>[] typeParameters = type.getTypeParameters();
|
||||
if(genericType instanceof ParameterizedType && typeParameters.length > 0) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType)genericType;
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
if(!(actualTypeArguments[i] instanceof TypeVariable)) {
|
||||
mapGeneric.put(typeParameters[i].getTypeName(), actualTypeArguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pojo.getClass().isArray()) {
|
||||
if (Collection.class.isAssignableFrom(type)) {
|
||||
Class<?> ctype = pojo.getClass().getComponentType();
|
||||
|
|
@ -357,7 +377,7 @@ public class PojoUtils {
|
|||
history.put(pojo, dest);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object obj = Array.get(pojo, i);
|
||||
Object value = realize0(obj, ctype, null, history);
|
||||
Object value = realize1(obj, ctype, null, mapGeneric, history);
|
||||
dest.add(value);
|
||||
}
|
||||
return dest;
|
||||
|
|
@ -368,7 +388,7 @@ public class PojoUtils {
|
|||
history.put(pojo, dest);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object obj = Array.get(pojo, i);
|
||||
Object value = realize0(obj, ctype, null, history);
|
||||
Object value = realize1(obj, ctype, null, mapGeneric, history);
|
||||
Array.set(dest, i, value);
|
||||
}
|
||||
return dest;
|
||||
|
|
@ -384,7 +404,7 @@ public class PojoUtils {
|
|||
history.put(pojo, dest);
|
||||
int i = 0;
|
||||
for (Object obj : src) {
|
||||
Object value = realize0(obj, ctype, null, history);
|
||||
Object value = realize1(obj, ctype, null, mapGeneric, history);
|
||||
Array.set(dest, i, value);
|
||||
i++;
|
||||
}
|
||||
|
|
@ -400,7 +420,7 @@ public class PojoUtils {
|
|||
if (keyType instanceof Class) {
|
||||
keyClazz = (Class<?>) keyType;
|
||||
}
|
||||
Object value = realize0(obj, keyClazz, keyType, history);
|
||||
Object value = realize1(obj, keyClazz, keyType, mapGeneric, history);
|
||||
dest.add(value);
|
||||
}
|
||||
return dest;
|
||||
|
|
@ -483,8 +503,8 @@ public class PojoUtils {
|
|||
valueClazz = entry.getValue() == null ? null : entry.getValue().getClass();
|
||||
}
|
||||
|
||||
Object key = keyClazz == null ? entry.getKey() : realize0(entry.getKey(), keyClazz, keyType, history);
|
||||
Object value = valueClazz == null ? entry.getValue() : realize0(entry.getValue(), valueClazz, valueType, history);
|
||||
Object key = keyClazz == null ? entry.getKey() : realize1(entry.getKey(), keyClazz, keyType, mapGeneric, history);
|
||||
Object value = valueClazz == null ? entry.getValue() : realize1(entry.getValue(), valueClazz, valueType, mapGeneric, history);
|
||||
result.put(key, value);
|
||||
}
|
||||
return result;
|
||||
|
|
@ -506,6 +526,7 @@ public class PojoUtils {
|
|||
}
|
||||
|
||||
history.put(pojo, dest);
|
||||
|
||||
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
if (key instanceof String) {
|
||||
|
|
@ -518,8 +539,24 @@ public class PojoUtils {
|
|||
if (!method.isAccessible()) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
Type ptype = method.getGenericParameterTypes()[0];
|
||||
value = realize0(value, method.getParameterTypes()[0], ptype, history);
|
||||
Type containType = mapGeneric.get(field.getGenericType().getTypeName());
|
||||
if(containType != null) {
|
||||
//is generic
|
||||
if(containType instanceof ParameterizedType) {
|
||||
value = realize1(value, (Class<?>) ((ParameterizedType)containType).getRawType(), containType, mapGeneric, history);
|
||||
}
|
||||
else if (containType instanceof Class){
|
||||
value = realize1(value, (Class<?>) containType, containType, mapGeneric, history);
|
||||
}
|
||||
else {
|
||||
Type ptype = method.getGenericParameterTypes()[0];
|
||||
value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Type ptype = method.getGenericParameterTypes()[0];
|
||||
value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history);
|
||||
}
|
||||
try {
|
||||
method.invoke(dest, value);
|
||||
} catch (Exception e) {
|
||||
|
|
@ -529,7 +566,7 @@ public class PojoUtils {
|
|||
throw new RuntimeException(exceptionDescription, e);
|
||||
}
|
||||
} else if (field != null) {
|
||||
value = realize0(value, field.getType(), field.getGenericType(), history);
|
||||
value = realize1(value, field.getType(), field.getGenericType(), mapGeneric, history);
|
||||
try {
|
||||
field.set(dest, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
|
|
@ -672,10 +709,16 @@ public class PojoUtils {
|
|||
if (CLASS_FIELD_CACHE.containsKey(cls) && CLASS_FIELD_CACHE.get(cls).containsKey(fieldName)) {
|
||||
return CLASS_FIELD_CACHE.get(cls).get(fieldName);
|
||||
}
|
||||
try {
|
||||
result = cls.getDeclaredField(fieldName);
|
||||
result.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
for(Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
|
||||
try {
|
||||
result = acls.getDeclaredField(fieldName);
|
||||
if (!Modifier.isPublic(result.getModifiers())) {
|
||||
result.setAccessible(true);
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
}
|
||||
}
|
||||
if(result == null) {
|
||||
for (Field field : cls.getFields()) {
|
||||
if (fieldName.equals(field.getName()) && ReflectUtils.isPublicInstanceField(field)) {
|
||||
result = field;
|
||||
|
|
@ -683,6 +726,7 @@ public class PojoUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
ConcurrentMap<String, Field> fields = CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>());
|
||||
fields.putIfAbsent(fieldName, result);
|
||||
|
|
|
|||
|
|
@ -872,7 +872,7 @@ public final class ReflectUtils {
|
|||
return EMPTY_CLASS_ARRAY;
|
||||
}
|
||||
|
||||
List<Class<?>> cs = new ArrayList<Class<?>>();
|
||||
List<Class<?>> cs = new ArrayList<>();
|
||||
Matcher m = DESC_PATTERN.matcher(desc);
|
||||
while (m.find()) {
|
||||
cs.add(desc2class(cl, m.group()));
|
||||
|
|
@ -900,7 +900,7 @@ public final class ReflectUtils {
|
|||
}
|
||||
Method method;
|
||||
if (parameterTypes == null) {
|
||||
List<Method> finded = new ArrayList<Method>();
|
||||
List<Method> finded = new ArrayList<>();
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(methodName)) {
|
||||
finded.add(m);
|
||||
|
|
@ -1140,7 +1140,7 @@ public final class ReflectUtils {
|
|||
}
|
||||
|
||||
public static Map<String, Field> getBeanPropertyFields(Class cl) {
|
||||
Map<String, Field> properties = new HashMap<String, Field>();
|
||||
Map<String, Field> properties = new HashMap<>();
|
||||
for (; cl != null; cl = cl.getSuperclass()) {
|
||||
Field[] fields = cl.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
|
|
@ -1159,7 +1159,7 @@ public final class ReflectUtils {
|
|||
}
|
||||
|
||||
public static Map<String, Method> getBeanPropertyReadMethods(Class cl) {
|
||||
Map<String, Method> properties = new HashMap<String, Method>();
|
||||
Map<String, Method> properties = new HashMap<>();
|
||||
for (; cl != null; cl = cl.getSuperclass()) {
|
||||
Method[] methods = cl.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class SerializeSecurityConfigurator implements ScopeClassLoaderListener<M
|
|||
|
||||
private volatile boolean autoTrustSerializeClass = true;
|
||||
|
||||
private volatile int trustSerializeClassLevel = 3;
|
||||
private volatile int trustSerializeClassLevel = Integer.MAX_VALUE;
|
||||
|
||||
public SerializeSecurityConfigurator(ModuleModel moduleModel) {
|
||||
this.moduleModel = moduleModel;
|
||||
|
|
|
|||
|
|
@ -1030,7 +1030,7 @@ public final class StringUtils {
|
|||
buf.append(arg);
|
||||
} else {
|
||||
try {
|
||||
buf.append(JsonUtils.getJson().toJson(arg));
|
||||
buf.append(JsonUtils.toJson(arg));
|
||||
} catch (Exception e) {
|
||||
logger.warn(COMMON_JSON_CONVERT_EXCEPTION, "", "", e.getMessage(), e);
|
||||
buf.append(arg);
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
|
||||
}
|
||||
|
||||
private boolean verifyMethodConfig(MethodConfig methodConfig, Class<?> interfaceClass, boolean ignoreInvalidMethodConfig) {
|
||||
protected boolean verifyMethodConfig(MethodConfig methodConfig, Class<?> interfaceClass, boolean ignoreInvalidMethodConfig) {
|
||||
String methodName = methodConfig.getName();
|
||||
if (StringUtils.isEmpty(methodName)) {
|
||||
String msg = "<dubbo:method> name attribute is required! Please check: " +
|
||||
|
|
@ -396,7 +396,12 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
|
||||
return false;
|
||||
} else {
|
||||
throw new IllegalStateException(msg);
|
||||
if (!isNeedCheckMethod()) {
|
||||
msg = "Generic call: " + msg;
|
||||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
|
||||
} else {
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -413,6 +418,11 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Transient
|
||||
protected boolean isNeedCheckMethod() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasArgumentConfigProps(Map<String, String> configProperties, String methodName, int argIndex) {
|
||||
String argPrefix = methodName + "." + argIndex + ".";
|
||||
return ConfigurationUtils.hasSubProperties(configProperties, argPrefix);
|
||||
|
|
|
|||
|
|
@ -183,6 +183,11 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNeedCheckMethod() {
|
||||
return StringUtils.isEmpty(getGeneric());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @deprecated instead, use the parameter <b>scope</> to judge if it's in jvm, scope=local
|
||||
|
|
|
|||
|
|
@ -16,14 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
|
||||
import org.apache.dubbo.common.infra.InfraAdapter;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
|
|
@ -33,6 +25,14 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
|
||||
|
|
@ -40,7 +40,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUMP_ENABLE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_DEFAULT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
|
||||
|
|
@ -274,7 +274,7 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
}
|
||||
}
|
||||
if (executorManagementMode == null) {
|
||||
executorManagementMode = EXECUTOR_MANAGEMENT_MODE_DEFAULT;
|
||||
executorManagementMode = EXECUTOR_MANAGEMENT_MODE_ISOLATION;
|
||||
}
|
||||
if (enableFileCache == null) {
|
||||
enableFileCache = Boolean.TRUE;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.config.nested.AggregationConfig;
|
||||
import org.apache.dubbo.config.nested.PrometheusConfig;
|
||||
import org.apache.dubbo.config.nested.HistogramConfig;
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
|
|
@ -38,17 +39,22 @@ public class MetricsConfig extends AbstractConfig {
|
|||
/**
|
||||
* Enable jvm metrics when collecting.
|
||||
*/
|
||||
private Boolean enableJvmMetrics;
|
||||
private Boolean enableJvm;
|
||||
|
||||
/**
|
||||
* Enable threadpool metrics when collecting.
|
||||
*/
|
||||
private Boolean enableThreadpool;
|
||||
|
||||
/**
|
||||
* Enable registry metrics.
|
||||
*/
|
||||
private Boolean enableRegistryMetrics;
|
||||
private Boolean enableRegistry;
|
||||
|
||||
/**
|
||||
* Enable metadata metrics.
|
||||
*/
|
||||
private Boolean enableMetadataMetrics;
|
||||
private Boolean enableMetadata;
|
||||
|
||||
/**
|
||||
* @deprecated After metrics config is refactored.
|
||||
|
|
@ -69,6 +75,9 @@ public class MetricsConfig extends AbstractConfig {
|
|||
@Nested
|
||||
private AggregationConfig aggregation;
|
||||
|
||||
@Nested
|
||||
private HistogramConfig histogram;
|
||||
|
||||
private String exportServiceProtocol;
|
||||
|
||||
private Integer exportServicePort;
|
||||
|
|
@ -100,20 +109,20 @@ public class MetricsConfig extends AbstractConfig {
|
|||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public Boolean getEnableJvmMetrics() {
|
||||
return enableJvmMetrics;
|
||||
public Boolean getEnableJvm() {
|
||||
return enableJvm;
|
||||
}
|
||||
|
||||
public void setEnableJvmMetrics(Boolean enableJvmMetrics) {
|
||||
this.enableJvmMetrics = enableJvmMetrics;
|
||||
public void setEnableJvm(Boolean enableJvm) {
|
||||
this.enableJvm = enableJvm;
|
||||
}
|
||||
|
||||
public Boolean getEnableRegistryMetrics() {
|
||||
return enableRegistryMetrics;
|
||||
public Boolean getEnableRegistry() {
|
||||
return enableRegistry;
|
||||
}
|
||||
|
||||
public void setEnableRegistryMetrics(Boolean enableRegistryMetrics) {
|
||||
this.enableRegistryMetrics = enableRegistryMetrics;
|
||||
public void setEnableRegistry(Boolean enableRegistry) {
|
||||
this.enableRegistry = enableRegistry;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
|
|
@ -140,6 +149,14 @@ public class MetricsConfig extends AbstractConfig {
|
|||
this.aggregation = aggregation;
|
||||
}
|
||||
|
||||
public HistogramConfig getHistogram() {
|
||||
return histogram;
|
||||
}
|
||||
|
||||
public void setHistogram(HistogramConfig histogram) {
|
||||
this.histogram = histogram;
|
||||
}
|
||||
|
||||
public String getExportServiceProtocol() {
|
||||
return exportServiceProtocol;
|
||||
}
|
||||
|
|
@ -156,12 +173,19 @@ public class MetricsConfig extends AbstractConfig {
|
|||
this.exportServicePort = exportServicePort;
|
||||
}
|
||||
|
||||
public Boolean getEnableMetadataMetrics() {
|
||||
return enableMetadataMetrics;
|
||||
public Boolean getEnableMetadata() {
|
||||
return enableMetadata;
|
||||
}
|
||||
|
||||
public void setEnableMetadataMetrics(Boolean enableMetadataMetrics) {
|
||||
this.enableMetadataMetrics = enableMetadataMetrics;
|
||||
public void setEnableMetadata(Boolean enableMetadata) {
|
||||
this.enableMetadata = enableMetadata;
|
||||
}
|
||||
|
||||
public Boolean getEnableThreadpool() {
|
||||
return enableThreadpool;
|
||||
}
|
||||
|
||||
public void setEnableThreadpool(Boolean enableThreadpool) {
|
||||
this.enableThreadpool = enableThreadpool;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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.config;
|
||||
|
||||
import org.apache.dubbo.config.nested.BaggageConfig;
|
||||
import org.apache.dubbo.config.nested.PropagationConfig;
|
||||
import org.apache.dubbo.config.nested.SamplingConfig;
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
/**
|
||||
* TracingConfig
|
||||
*/
|
||||
public class TracingConfig extends AbstractConfig {
|
||||
|
||||
private static final long serialVersionUID = -9089919311611546383L;
|
||||
|
||||
private Boolean enabled = false;
|
||||
|
||||
/**
|
||||
* Sampling configuration.
|
||||
*/
|
||||
@Nested
|
||||
private SamplingConfig sampling = new SamplingConfig();
|
||||
|
||||
/**
|
||||
* Baggage configuration.
|
||||
*/
|
||||
@Nested
|
||||
private BaggageConfig baggage = new BaggageConfig();
|
||||
|
||||
/**
|
||||
* Propagation configuration.
|
||||
*/
|
||||
@Nested
|
||||
private PropagationConfig propagation = new PropagationConfig();
|
||||
|
||||
public TracingConfig() {
|
||||
}
|
||||
|
||||
public TracingConfig(ApplicationModel applicationModel) {
|
||||
super(applicationModel);
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public SamplingConfig getSampling() {
|
||||
return sampling;
|
||||
}
|
||||
|
||||
public void setSampling(SamplingConfig sampling) {
|
||||
this.sampling = sampling;
|
||||
}
|
||||
|
||||
public BaggageConfig getBaggage() {
|
||||
return baggage;
|
||||
}
|
||||
|
||||
public void setBaggage(BaggageConfig baggage) {
|
||||
this.baggage = baggage;
|
||||
}
|
||||
|
||||
public PropagationConfig getPropagation() {
|
||||
return propagation;
|
||||
}
|
||||
|
||||
public void setPropagation(PropagationConfig propagation) {
|
||||
this.propagation = propagation;
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ import org.apache.dubbo.config.ReferenceConfigBase;
|
|||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
|
@ -92,6 +93,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
uniqueConfigTypes.add(ApplicationConfig.class);
|
||||
uniqueConfigTypes.add(MonitorConfig.class);
|
||||
uniqueConfigTypes.add(MetricsConfig.class);
|
||||
uniqueConfigTypes.add(TracingConfig.class);
|
||||
uniqueConfigTypes.add(SslConfig.class);
|
||||
|
||||
// unique config in each module
|
||||
|
|
@ -127,7 +129,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
|
||||
// dubbo.config.ignore-duplicated-interface
|
||||
String ignoreDuplicatedInterfaceStr = (String) configuration
|
||||
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE);
|
||||
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE);
|
||||
if (ignoreDuplicatedInterfaceStr != null) {
|
||||
this.ignoreDuplicatedInterface = Boolean.parseBoolean(ignoreDuplicatedInterfaceStr);
|
||||
}
|
||||
|
|
@ -192,7 +194,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
* @throws IllegalStateException
|
||||
*/
|
||||
private <C extends AbstractConfig> C addIfAbsent(C config, Map<String, C> configsMap)
|
||||
throws IllegalStateException {
|
||||
throws IllegalStateException {
|
||||
|
||||
if (config == null || configsMap == null) {
|
||||
return config;
|
||||
|
|
@ -216,8 +218,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
if (existedConfig != null && !isEquals(existedConfig, config)) {
|
||||
String type = config.getClass().getSimpleName();
|
||||
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
|
||||
"you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
|
||||
type, type, type, type, key, existedConfig, config));
|
||||
"you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
|
||||
type, type, type, type, key, existedConfig, config));
|
||||
}
|
||||
|
||||
// override existed config if any
|
||||
|
|
@ -252,7 +254,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
return null;
|
||||
} else if (size > 1) {
|
||||
throw new IllegalStateException("Expected single instance of " + configType + ", but found " + size +
|
||||
" instances, please remove redundant configs. instances: " + configsMap.values());
|
||||
" instances, please remove redundant configs. instances: " + configsMap.values());
|
||||
}
|
||||
return (C) configsMap.values().iterator().next();
|
||||
}
|
||||
|
|
@ -335,11 +337,11 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
// try to find config by name
|
||||
if (ReflectUtils.hasMethod(cls, CONFIG_NAME_READ_METHOD)) {
|
||||
List<C> list = configsMap.values().stream()
|
||||
.filter(cfg -> name.equals(getConfigName(cfg)))
|
||||
.collect(Collectors.toList());
|
||||
.filter(cfg -> name.equals(getConfigName(cfg)))
|
||||
.collect(Collectors.toList());
|
||||
if (list.size() > 1) {
|
||||
throw new IllegalStateException("Found more than one config by name: " + name +
|
||||
", instances: " + list + ". Please remove redundant configs or get config by id.");
|
||||
", instances: " + list + ". Please remove redundant configs or get config by id.");
|
||||
} else if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
}
|
||||
|
|
@ -364,8 +366,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
|
||||
// 2. find equal config
|
||||
prevConfig = values.stream()
|
||||
.filter(val -> isEquals(val, config))
|
||||
.findFirst();
|
||||
.filter(val -> isEquals(val, config))
|
||||
.findFirst();
|
||||
return prevConfig;
|
||||
}
|
||||
|
||||
|
|
@ -408,18 +410,18 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
static <C extends AbstractConfig> List<C> getDefaultConfigs(Map<String, C> configsMap) {
|
||||
// find isDefault() == true
|
||||
List<C> list = configsMap.values()
|
||||
.stream()
|
||||
.filter(c -> TRUE.equals(AbstractConfigManager.isDefaultConfig(c)))
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.filter(c -> TRUE.equals(AbstractConfigManager.isDefaultConfig(c)))
|
||||
.collect(Collectors.toList());
|
||||
if (list.size() > 0) {
|
||||
return list;
|
||||
}
|
||||
|
||||
// find isDefault() == null
|
||||
list = configsMap.values()
|
||||
.stream()
|
||||
.filter(c -> AbstractConfigManager.isDefaultConfig(c) == null)
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.filter(c -> AbstractConfigManager.isDefaultConfig(c) == null)
|
||||
.collect(Collectors.toList());
|
||||
return list;
|
||||
|
||||
// exclude isDefault() == false
|
||||
|
|
@ -430,7 +432,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
C oldOne = configsMap.values().iterator().next();
|
||||
String configName = oldOne.getClass().getSimpleName();
|
||||
String msgPrefix = "Duplicate Configs found for " + configName + ", only one unique " + configName +
|
||||
" is allowed for one application. previous: " + oldOne + ", later: " + config + ". According to config mode [" + configMode + "], ";
|
||||
" is allowed for one application. previous: " + oldOne + ", later: " + config + ". According to config mode [" + configMode + "], ";
|
||||
switch (configMode) {
|
||||
case STRICT: {
|
||||
if (!isEquals(oldOne, config)) {
|
||||
|
|
@ -625,9 +627,10 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
*/
|
||||
protected <T extends AbstractConfig> boolean isRequired(Class<T> clazz) {
|
||||
if (clazz == RegistryConfig.class ||
|
||||
clazz == MetadataReportConfig.class ||
|
||||
clazz == MonitorConfig.class ||
|
||||
clazz == MetricsConfig.class) {
|
||||
clazz == MetadataReportConfig.class ||
|
||||
clazz == MonitorConfig.class ||
|
||||
clazz == MetricsConfig.class ||
|
||||
clazz == TracingConfig.class) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.dubbo.config.MonitorConfig;
|
|||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
|
@ -59,8 +60,8 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
|
||||
public ConfigManager(ApplicationModel applicationModel) {
|
||||
super(applicationModel, Arrays.asList(ApplicationConfig.class, MonitorConfig.class,
|
||||
MetricsConfig.class, SslConfig.class, ProtocolConfig.class, RegistryConfig.class, ConfigCenterConfig.class,
|
||||
MetadataReportConfig.class));
|
||||
MetricsConfig.class, SslConfig.class, ProtocolConfig.class, RegistryConfig.class, ConfigCenterConfig.class,
|
||||
MetadataReportConfig.class, TracingConfig.class));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -105,6 +106,15 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
return ofNullable(getSingleConfig(getTagName(MetricsConfig.class)));
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setTracing(TracingConfig tracing) {
|
||||
addConfig(tracing);
|
||||
}
|
||||
|
||||
public Optional<TracingConfig> getTracing() {
|
||||
return ofNullable(getSingleConfig(getTagName(TracingConfig.class)));
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setSsl(SslConfig sslConfig) {
|
||||
addConfig(sslConfig);
|
||||
|
|
@ -223,6 +233,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
getApplication().ifPresent(ApplicationConfig::refresh);
|
||||
getMonitor().ifPresent(MonitorConfig::refresh);
|
||||
getMetrics().ifPresent(MetricsConfig::refresh);
|
||||
getTracing().ifPresent(TracingConfig::refresh);
|
||||
getSsl().ifPresent(SslConfig::refresh);
|
||||
|
||||
getProtocols().forEach(ProtocolConfig::refresh);
|
||||
|
|
@ -243,6 +254,8 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
// load dubbo.metrics.xxx
|
||||
loadConfigsOfTypeFromProps(MetricsConfig.class);
|
||||
|
||||
loadConfigsOfTypeFromProps(TracingConfig.class);
|
||||
|
||||
// load multiple config types:
|
||||
// load dubbo.protocols.xxx
|
||||
loadConfigsOfTypeFromProps(ProtocolConfig.class);
|
||||
|
|
@ -269,12 +282,13 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
private void checkConfigs() {
|
||||
// check config types (ignore metadata-center)
|
||||
List<Class<? extends AbstractConfig>> multipleConfigTypes = Arrays.asList(
|
||||
ApplicationConfig.class,
|
||||
ProtocolConfig.class,
|
||||
RegistryConfig.class,
|
||||
MonitorConfig.class,
|
||||
MetricsConfig.class,
|
||||
SslConfig.class);
|
||||
ApplicationConfig.class,
|
||||
ProtocolConfig.class,
|
||||
RegistryConfig.class,
|
||||
MonitorConfig.class,
|
||||
MetricsConfig.class,
|
||||
TracingConfig.class,
|
||||
SslConfig.class);
|
||||
|
||||
for (Class<? extends AbstractConfig> configType : multipleConfigTypes) {
|
||||
checkDefaultAndValidateConfigs(configType);
|
||||
|
|
@ -290,7 +304,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
ProtocolConfig prevProtocol = protocolPortMap.get(port);
|
||||
if (prevProtocol != null) {
|
||||
throw new IllegalStateException("Duplicated port used by protocol configs, port: " + port +
|
||||
", configs: " + Arrays.asList(prevProtocol, protocol));
|
||||
", configs: " + Arrays.asList(prevProtocol, protocol));
|
||||
}
|
||||
protocolPortMap.put(port, protocol);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.apache.dubbo.config.ReferenceConfigBase;
|
|||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
|
@ -352,6 +353,10 @@ public class ModuleConfigManager extends AbstractConfigManager implements Module
|
|||
return applicationConfigManager.getMetrics();
|
||||
}
|
||||
|
||||
public Optional<TracingConfig> getTracing() {
|
||||
return applicationConfigManager.getTracing();
|
||||
}
|
||||
|
||||
public Optional<SslConfig> getSsl() {
|
||||
return applicationConfigManager.getSsl();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.config.nested;
|
||||
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BaggageConfig implements Serializable {
|
||||
|
||||
private Boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Correlation configuration.
|
||||
*/
|
||||
@Nested
|
||||
private Correlation correlation = new Correlation();
|
||||
|
||||
/**
|
||||
* List of fields that are referenced the same in-process as it is on the wire.
|
||||
* For example, the field "x-vcap-request-id" would be set as-is including the
|
||||
* prefix.
|
||||
*/
|
||||
private List<String> remoteFields = new ArrayList<>();
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Correlation getCorrelation() {
|
||||
return correlation;
|
||||
}
|
||||
|
||||
public void setCorrelation(Correlation correlation) {
|
||||
this.correlation = correlation;
|
||||
}
|
||||
|
||||
public List<String> getRemoteFields() {
|
||||
return remoteFields;
|
||||
}
|
||||
|
||||
public void setRemoteFields(List<String> remoteFields) {
|
||||
this.remoteFields = remoteFields;
|
||||
}
|
||||
|
||||
public static class Correlation implements Serializable {
|
||||
|
||||
/**
|
||||
* Whether to enable correlation of the baggage context with logging contexts.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* List of fields that should be correlated with the logging context. That
|
||||
* means that these fields would end up as key-value pairs in e.g. MDC.
|
||||
*/
|
||||
private List<String> fields = new ArrayList<>();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public List<String> getFields() {
|
||||
return this.fields;
|
||||
}
|
||||
|
||||
public void setFields(List<String> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.config.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class HistogramConfig implements Serializable {
|
||||
|
||||
private Boolean enabled;
|
||||
|
||||
private Integer[] bucketsMs;
|
||||
|
||||
private Integer minExpectedMs;
|
||||
|
||||
private Integer maxExpectedMs;
|
||||
|
||||
private Boolean enabledPercentiles;
|
||||
|
||||
private double[] percentiles;
|
||||
|
||||
private Integer distributionStatisticExpiryMin;
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Integer[] getBucketsMs() {
|
||||
return bucketsMs;
|
||||
}
|
||||
|
||||
public void setBucketsMs(Integer[] bucketsMs) {
|
||||
this.bucketsMs = bucketsMs;
|
||||
}
|
||||
|
||||
public Integer getMinExpectedMs() {
|
||||
return minExpectedMs;
|
||||
}
|
||||
|
||||
public void setMinExpectedMs(Integer minExpectedMs) {
|
||||
this.minExpectedMs = minExpectedMs;
|
||||
}
|
||||
|
||||
public Integer getMaxExpectedMs() {
|
||||
return maxExpectedMs;
|
||||
}
|
||||
|
||||
public void setMaxExpectedMs(Integer maxExpectedMs) {
|
||||
this.maxExpectedMs = maxExpectedMs;
|
||||
}
|
||||
|
||||
public Boolean getEnabledPercentiles() {
|
||||
return enabledPercentiles;
|
||||
}
|
||||
|
||||
public void setEnabledPercentiles(Boolean enabledPercentiles) {
|
||||
this.enabledPercentiles = enabledPercentiles;
|
||||
}
|
||||
|
||||
public double[] getPercentiles() {
|
||||
return percentiles;
|
||||
}
|
||||
|
||||
public void setPercentiles(double[] percentiles) {
|
||||
this.percentiles = percentiles;
|
||||
}
|
||||
|
||||
public Integer getDistributionStatisticExpiryMin() {
|
||||
return distributionStatisticExpiryMin;
|
||||
}
|
||||
|
||||
public void setDistributionStatisticExpiryMin(Integer distributionStatisticExpiryMin) {
|
||||
this.distributionStatisticExpiryMin = distributionStatisticExpiryMin;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,27 +14,27 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.nested;
|
||||
|
||||
package org.apache.dubbo.metrics.event;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* RequestEvent.
|
||||
*/
|
||||
public class RequestEvent extends MetricsEvent {
|
||||
private Type type;
|
||||
public class PropagationConfig implements Serializable {
|
||||
|
||||
public RequestEvent(Object source, Type type) {
|
||||
super(source);
|
||||
this.type = type;
|
||||
}
|
||||
public static final String B3 = "B3";
|
||||
|
||||
public Type getType() {
|
||||
public static final String W3C = "W3C";
|
||||
|
||||
/**
|
||||
* Tracing context propagation type.
|
||||
*/
|
||||
private String type = W3C;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.config.nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SamplingConfig implements Serializable {
|
||||
|
||||
/**
|
||||
* Probability in the range from 0.0 to 1.0 that a trace will be sampled.
|
||||
*/
|
||||
private float probability = 0.10f;
|
||||
|
||||
public float getProbability() {
|
||||
return this.probability;
|
||||
}
|
||||
|
||||
public void setProbability(float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ public final class ServiceDefinitionBuilder {
|
|||
*/
|
||||
public static String schema(final Class<?> clazz) {
|
||||
ServiceDefinition sd = build(clazz);
|
||||
return JsonUtils.getJson().toJson(sd);
|
||||
return JsonUtils.toJson(sd);
|
||||
}
|
||||
|
||||
private ServiceDefinitionBuilder() {
|
||||
|
|
|
|||
|
|
@ -50,15 +50,17 @@ public abstract class AbstractIsolationExecutorSupport implements ExecutorSuppor
|
|||
|
||||
for (URL serviceUrl : serviceUrls) {
|
||||
if (serviceUrl.getProtocol().equals(url.getProtocol()) && serviceUrl.getPort() == url.getPort()) {
|
||||
return executorRepository.getExecutor(serviceUrl);
|
||||
return executorRepository.getExecutor(providerModel, serviceUrl);
|
||||
}
|
||||
}
|
||||
return executorRepository.getExecutor(serviceUrls.get(0));
|
||||
return executorRepository.getExecutor(providerModel, serviceUrls.get(0));
|
||||
}
|
||||
|
||||
protected abstract ServiceKey getServiceKey(Object data);
|
||||
protected ServiceKey getServiceKey(Object data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private ProviderModel getProviderModel(Object data) {
|
||||
protected ProviderModel getProviderModel(Object data) {
|
||||
ServiceKey serviceKey = getServiceKey(data);
|
||||
if (serviceKey == null) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -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.rpc.executor;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
|
||||
public class DefaultIsolationExecutorSupportFactory implements IsolationExecutorSupportFactory {
|
||||
@Override
|
||||
public ExecutorSupport createIsolationExecutorSupport(URL url) {
|
||||
return new DefaultExecutorSupport(url);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,23 +17,19 @@
|
|||
package org.apache.dubbo.rpc.executor;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
|
||||
@SPI
|
||||
@SPI("default")
|
||||
public interface IsolationExecutorSupportFactory {
|
||||
|
||||
@Adaptive(PROTOCOL_KEY)
|
||||
ExecutorSupport createIsolationExecutorSupport(URL url);
|
||||
|
||||
static ExecutorSupport getIsolationExecutorSupport(URL url) {
|
||||
ApplicationModel applicationModel = url.getOrDefaultApplicationModel();
|
||||
ExtensionLoader<IsolationExecutorSupportFactory> extensionLoader = applicationModel.getExtensionLoader(IsolationExecutorSupportFactory.class);
|
||||
IsolationExecutorSupportFactory factory = extensionLoader.getAdaptiveExtension();
|
||||
IsolationExecutorSupportFactory factory = extensionLoader.getOrDefaultExtension(url.getProtocol());
|
||||
return factory.createIsolationExecutorSupport(url);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import java.util.concurrent.locks.Lock;
|
|||
* returned from them are of process scope. If you want to support multiple dubbo servers in one
|
||||
* single process, you may need to refactor those three classes.
|
||||
* <p>
|
||||
* Represent a application which is using Dubbo and store basic metadata info for using
|
||||
* Represent an application which is using Dubbo and store basic metadata info for using
|
||||
* during the processing of RPC invoking.
|
||||
* <p>
|
||||
* ApplicationModel includes many ProviderModel which is about published services
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
|
@ -45,9 +44,6 @@ public class FrameworkServiceRepository {
|
|||
// useful to find a provider model quickly with serviceInterfaceName:version
|
||||
private final ConcurrentMap<String, List<ProviderModel>> providersWithoutGroup = new ConcurrentHashMap<>();
|
||||
|
||||
// useful to find a url quickly with serviceInterfaceName:version
|
||||
private final ConcurrentMap<String, List<URL>> providerUrlsWithoutGroup = new ConcurrentHashMap<>();
|
||||
|
||||
public FrameworkServiceRepository(FrameworkModel frameworkModel) {
|
||||
this.frameworkModel = frameworkModel;
|
||||
}
|
||||
|
|
@ -67,7 +63,6 @@ public class FrameworkServiceRepository {
|
|||
providers.remove(providerModel.getServiceKey());
|
||||
String keyWithoutGroup = keyWithoutGroup(providerModel.getServiceKey());
|
||||
providersWithoutGroup.remove(keyWithoutGroup);
|
||||
providerUrlsWithoutGroup.remove(keyWithoutGroup);
|
||||
}
|
||||
|
||||
public ProviderModel lookupExportedServiceWithoutGroup(String key) {
|
||||
|
|
@ -83,18 +78,10 @@ public class FrameworkServiceRepository {
|
|||
return providersWithoutGroup.get(key);
|
||||
}
|
||||
|
||||
public void registerProviderUrl(URL url) {
|
||||
ConcurrentHashMapUtils.computeIfAbsent(providerUrlsWithoutGroup, keyWithoutGroup(url.getServiceKey()), (k) -> new CopyOnWriteArrayList<>()).add(url);
|
||||
}
|
||||
|
||||
public ProviderModel lookupExportedService(String serviceKey) {
|
||||
return providers.get(serviceKey);
|
||||
}
|
||||
|
||||
public List<URL> lookupRegisteredProviderUrlsWithoutGroup(String key) {
|
||||
return providerUrlsWithoutGroup.get(key);
|
||||
}
|
||||
|
||||
public List<ProviderModel> allProviderModels() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(providers.values()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@ public interface PackableMethod {
|
|||
byte[] pack(Object obj) throws IOException;
|
||||
}
|
||||
|
||||
interface WrapperUnPack extends UnPack {
|
||||
|
||||
default Object unpack(byte[] data) throws IOException, ClassNotFoundException {
|
||||
return unpack(data, false);
|
||||
}
|
||||
|
||||
Object unpack(byte[] data, boolean isReturnTriException) throws IOException, ClassNotFoundException;
|
||||
|
||||
|
||||
}
|
||||
|
||||
interface UnPack {
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +55,7 @@ public interface PackableMethod {
|
|||
* @throws ClassNotFoundException when no class found
|
||||
*/
|
||||
Object unpack(byte[] data) throws IOException, ClassNotFoundException;
|
||||
|
||||
}
|
||||
|
||||
default Object parseRequest(byte[] data) throws IOException, ClassNotFoundException {
|
||||
|
|
@ -51,7 +63,15 @@ public interface PackableMethod {
|
|||
}
|
||||
|
||||
default Object parseResponse(byte[] data) throws IOException, ClassNotFoundException {
|
||||
return getResponseUnpack().unpack(data);
|
||||
return parseResponse(data, false);
|
||||
}
|
||||
|
||||
default Object parseResponse(byte[] data, boolean isReturnTriException) throws IOException, ClassNotFoundException {
|
||||
UnPack unPack = getResponseUnpack();
|
||||
if (unPack instanceof WrapperUnPack) {
|
||||
return ((WrapperUnPack) unPack).unpack(data, isReturnTriException);
|
||||
}
|
||||
return unPack.unpack(data);
|
||||
}
|
||||
|
||||
default byte[] packRequest(Object request) throws IOException {
|
||||
|
|
|
|||
|
|
@ -116,18 +116,18 @@ public class GenericException extends RuntimeException {
|
|||
if(this.useCause) {
|
||||
return getCause().getMessage();
|
||||
}
|
||||
return JsonUtils.getJson().toJson(GenericExceptionInfo.createNoStackTrace(genericExceptionInfo));
|
||||
return JsonUtils.toJson(GenericExceptionInfo.createNoStackTrace(genericExceptionInfo));
|
||||
}
|
||||
|
||||
public String getGenericException() {
|
||||
if(this.useCause) {
|
||||
return ((GenericException)getCause()).getGenericException();
|
||||
}
|
||||
return JsonUtils.getJson().toJson(genericExceptionInfo);
|
||||
return JsonUtils.toJson(genericExceptionInfo);
|
||||
}
|
||||
|
||||
public void setGenericException(String json) {
|
||||
GenericExceptionInfo info = JsonUtils.getJson().toJavaObject(json, GenericExceptionInfo.class);
|
||||
GenericExceptionInfo info = JsonUtils.toJavaObject(json, GenericExceptionInfo.class);
|
||||
if(info == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
default=org.apache.dubbo.rpc.executor.DefaultIsolationExecutorSupportFactory
|
||||
|
|
@ -125,6 +125,8 @@ java.util.TreeMap
|
|||
java.util.TreeSet
|
||||
java.util.UUID
|
||||
java.util.WeakHashMap
|
||||
org.apache.dubbo
|
||||
com.alibaba.dubbo
|
||||
org.apache.dubbo.metadata.MetadataInfo
|
||||
com.alibaba.com.caucho.hessian.io
|
||||
com.alibaba.dubbo.rpc.service.GenericException
|
||||
org.apache.dubbo.rpc.service.GenericException
|
||||
org.apache.dubbo.rpc.RpcException
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common;
|
||||
|
||||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -47,6 +48,24 @@ class URLBuilderTest {
|
|||
assertThat(url2.getVersion(), equalTo("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefault() {
|
||||
ServiceConfigURL url1 = URLBuilder.from(URL.valueOf(""))
|
||||
.addParameter("timeout", "1234")
|
||||
.addParameter("default.timeout", "5678")
|
||||
.build();
|
||||
|
||||
assertThat(url1.getParameter("timeout"), equalTo("1234"));
|
||||
assertThat(url1.getParameter("default.timeout"), equalTo("5678"));
|
||||
|
||||
ServiceConfigURL url2 = URLBuilder.from(URL.valueOf(""))
|
||||
.addParameter("default.timeout", "5678")
|
||||
.build();
|
||||
|
||||
assertThat(url2.getParameter("timeout"), equalTo("5678"));
|
||||
assertThat(url2.getParameter("default.timeout"), equalTo("5678"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSet() {
|
||||
URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan");
|
||||
|
|
@ -145,4 +164,4 @@ class URLBuilderTest {
|
|||
assertThat(url2.getParameter("version"), equalTo("1.0.0"));
|
||||
assertThat(url2.getParameter("absentKey"), equalTo("absentValue"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ class URLStrParserTest {
|
|||
testCases.add("dubbo://fe80:0:0:0:894:aeec:f37d:23e1%en0/path?abc=abc");
|
||||
testCases.add("dubbo://[fe80:0:0:0:894:aeec:f37d:23e1]:20880/path?abc=abc");
|
||||
testCases.add("nacos://192.168.1.1:8848?username=&password=");
|
||||
testCases.add("dubbo://127.0.0.1?timeout=1234&default.timeout=5678");
|
||||
testCases.add("dubbo://127.0.0.1?default.timeout=5678");
|
||||
|
||||
errorDecodedCases.add("dubbo:192.168.1.1");
|
||||
errorDecodedCases.add("://192.168.1.1");
|
||||
|
|
@ -81,4 +83,15 @@ class URLStrParserTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefault() {
|
||||
URL url1 = URLStrParser.parseEncodedStr(URL.encode("dubbo://127.0.0.1?timeout=1234&default.timeout=5678"));
|
||||
assertThat(url1.getParameter("timeout"), equalTo("1234"));
|
||||
assertThat(url1.getParameter("default.timeout"), equalTo("5678"));
|
||||
|
||||
URL url2 = URLStrParser.parseEncodedStr(URL.encode("dubbo://127.0.0.1?default.timeout=5678"));
|
||||
assertThat(url2.getParameter("timeout"), equalTo("5678"));
|
||||
assertThat(url2.getParameter("default.timeout"), equalTo("5678"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,17 @@ class URLTest {
|
|||
assertEquals("org.apache.dubbo.config.RegistryConfig#0", url.getParameter("id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefault() {
|
||||
URL url1 = URL.valueOf("dubbo://127.0.0.1:12345?timeout=1234&default.timeout=5678");
|
||||
assertEquals(1234, url1.getParameter("timeout", 0));
|
||||
assertEquals(5678, url1.getParameter("default.timeout", 0));
|
||||
|
||||
URL url2 = URL.valueOf("dubbo://127.0.0.1:12345?default.timeout=5678");
|
||||
assertEquals(5678, url2.getParameter("timeout", 0));
|
||||
assertEquals(5678, url2.getParameter("default.timeout", 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_valueOf_noProtocolAndHost() throws Exception {
|
||||
URL url = URL.valueOf("/context/path?version=1.0.0&application=morgan");
|
||||
|
|
|
|||
|
|
@ -60,22 +60,22 @@ class ClassUtilsTest {
|
|||
|
||||
@Test
|
||||
void testForName2() {
|
||||
ClassUtils.forName("boolean");
|
||||
ClassUtils.forName("byte");
|
||||
ClassUtils.forName("char");
|
||||
ClassUtils.forName("short");
|
||||
ClassUtils.forName("int");
|
||||
ClassUtils.forName("long");
|
||||
ClassUtils.forName("float");
|
||||
ClassUtils.forName("double");
|
||||
ClassUtils.forName("boolean[]");
|
||||
ClassUtils.forName("byte[]");
|
||||
ClassUtils.forName("char[]");
|
||||
ClassUtils.forName("short[]");
|
||||
ClassUtils.forName("int[]");
|
||||
ClassUtils.forName("long[]");
|
||||
ClassUtils.forName("float[]");
|
||||
ClassUtils.forName("double[]");
|
||||
Assertions.assertEquals(boolean.class, ClassUtils.forName("boolean"));
|
||||
Assertions.assertEquals(byte.class, ClassUtils.forName("byte"));
|
||||
Assertions.assertEquals(char.class, ClassUtils.forName("char"));
|
||||
Assertions.assertEquals(short.class, ClassUtils.forName("short"));
|
||||
Assertions.assertEquals(int.class, ClassUtils.forName("int"));
|
||||
Assertions.assertEquals(long.class, ClassUtils.forName("long"));
|
||||
Assertions.assertEquals(float.class, ClassUtils.forName("float"));
|
||||
Assertions.assertEquals(double.class, ClassUtils.forName("double"));
|
||||
Assertions.assertEquals(boolean[].class, ClassUtils.forName("boolean[]"));
|
||||
Assertions.assertEquals(byte[].class, ClassUtils.forName("byte[]"));
|
||||
Assertions.assertEquals(char[].class, ClassUtils.forName("char[]"));
|
||||
Assertions.assertEquals(short[].class, ClassUtils.forName("short[]"));
|
||||
Assertions.assertEquals(int[].class, ClassUtils.forName("int[]"));
|
||||
Assertions.assertEquals(long[].class, ClassUtils.forName("long[]"));
|
||||
Assertions.assertEquals(float[].class, ClassUtils.forName("float[]"));
|
||||
Assertions.assertEquals(double[].class, ClassUtils.forName("double[]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -174,4 +174,4 @@ class ClassUtilsTest {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ class EnvironmentTest {
|
|||
|
||||
// test getConfigurationMaps(AbstractConfig config, String prefix)
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps(registryConfig, prefix);
|
||||
Assertions.assertEquals(configurationMaps.size(), 7);
|
||||
Assertions.assertEquals(7, configurationMaps.size());
|
||||
|
||||
// test getConfigurationMaps()
|
||||
configurationMaps = environment.getConfigurationMaps();
|
||||
Assertions.assertEquals(configurationMaps.size(), 6);
|
||||
Assertions.assertEquals(6, configurationMaps.size());
|
||||
|
||||
CompositeConfiguration configuration1 = environment.getConfiguration();
|
||||
CompositeConfiguration configuration2 = environment.getConfiguration();
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@
|
|||
package org.apache.dubbo.common.config.configcenter;
|
||||
|
||||
import org.apache.dubbo.common.config.configcenter.nop.NopDynamicConfigurationFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
|
|
@ -36,4 +37,8 @@ class DynamicConfigurationFactoryTest {
|
|||
assertEquals(NopDynamicConfigurationFactory.class, factory.getClass());
|
||||
assertEquals(NopDynamicConfigurationFactory.class, getExtensionLoader(DynamicConfigurationFactory.class).getExtension("nop").getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> ExtensionLoader<T> getExtensionLoader(Class<T> extClass) {
|
||||
return ApplicationModel.defaultModel().getDefaultModule().getExtensionLoader(extClass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.convert;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
|
|
@ -60,4 +61,8 @@ class ConverterTest {
|
|||
assertEquals(Boolean.FALSE, converterUtil.convertIfPossible("false", Boolean.class));
|
||||
assertEquals(Double.valueOf(1), converterUtil.convertIfPossible("1", Double.class));
|
||||
}
|
||||
}
|
||||
|
||||
private <T> ExtensionLoader<T> getExtensionLoader(Class<T> extClass) {
|
||||
return ApplicationModel.defaultModel().getDefaultModule().getExtensionLoader(extClass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.convert;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
|
@ -52,4 +54,8 @@ class StringToLongConverterTest {
|
|||
converter.convert("ttt");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private <T> ExtensionLoader<T> getExtensionLoader(Class<T> extClass) {
|
||||
return ApplicationModel.defaultModel().getDefaultModule().getExtensionLoader(extClass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class ExtensionLoaderTest {
|
|||
// get origin instance from wrapper
|
||||
WrappedExt originImpl1 = impl1;
|
||||
while (originImpl1 instanceof WrappedExtWrapper) {
|
||||
originImpl1 = ((WrappedExtWrapper)originImpl1).getOrigin();
|
||||
originImpl1 = ((WrappedExtWrapper) originImpl1).getOrigin();
|
||||
}
|
||||
|
||||
// test unwrapped instance
|
||||
|
|
@ -292,7 +292,7 @@ class ExtensionLoaderTest {
|
|||
void test_getSupportedExtensions() {
|
||||
Set<String> exts = getExtensionLoader(SimpleExt.class).getSupportedExtensions();
|
||||
|
||||
Set<String> expected = new HashSet<String>();
|
||||
Set<String> expected = new HashSet<>();
|
||||
expected.add("impl1");
|
||||
expected.add("impl2");
|
||||
expected.add("impl3");
|
||||
|
|
@ -304,7 +304,7 @@ class ExtensionLoaderTest {
|
|||
void test_getSupportedExtensions_wrapperIsNotExt() {
|
||||
Set<String> exts = getExtensionLoader(WrappedExt.class).getSupportedExtensions();
|
||||
|
||||
Set<String> expected = new HashSet<String>();
|
||||
Set<String> expected = new HashSet<>();
|
||||
expected.add("impl1");
|
||||
expected.add("impl2");
|
||||
expected.add("impl3");
|
||||
|
|
@ -720,7 +720,7 @@ class ExtensionLoaderTest {
|
|||
void testDuplicatedImplWithoutOverriddenStrategy() {
|
||||
List<LoadingStrategy> loadingStrategies = ExtensionLoader.getLoadingStrategies();
|
||||
ExtensionLoader.setLoadingStrategies(new DubboExternalLoadingStrategyTest(false),
|
||||
new DubboInternalLoadingStrategyTest(false));
|
||||
new DubboInternalLoadingStrategyTest(false));
|
||||
ExtensionLoader<DuplicatedWithoutOverriddenExt> extensionLoader = getExtensionLoader(DuplicatedWithoutOverriddenExt.class);
|
||||
try {
|
||||
extensionLoader.getExtension("duplicated");
|
||||
|
|
@ -728,7 +728,7 @@ class ExtensionLoaderTest {
|
|||
} catch (IllegalStateException expected) {
|
||||
assertThat(expected.getMessage(), containsString("Failed to load extension class (interface: interface org.apache.dubbo.common.extension.duplicated.DuplicatedWithoutOverriddenExt"));
|
||||
assertThat(expected.getMessage(), containsString("cause: Duplicate extension org.apache.dubbo.common.extension.duplicated.DuplicatedWithoutOverriddenExt name duplicated"));
|
||||
}finally {
|
||||
} finally {
|
||||
//recover the loading strategies
|
||||
ExtensionLoader.setLoadingStrategies(loadingStrategies.toArray(new LoadingStrategy[loadingStrategies.size()]));
|
||||
}
|
||||
|
|
@ -738,7 +738,7 @@ class ExtensionLoaderTest {
|
|||
void testDuplicatedImplWithOverriddenStrategy() {
|
||||
List<LoadingStrategy> loadingStrategies = ExtensionLoader.getLoadingStrategies();
|
||||
ExtensionLoader.setLoadingStrategies(new DubboExternalLoadingStrategyTest(true),
|
||||
new DubboInternalLoadingStrategyTest(true));
|
||||
new DubboInternalLoadingStrategyTest(true));
|
||||
ExtensionLoader<DuplicatedOverriddenExt> extensionLoader = getExtensionLoader(DuplicatedOverriddenExt.class);
|
||||
DuplicatedOverriddenExt duplicatedOverriddenExt = extensionLoader.getExtension("duplicated");
|
||||
assertEquals("DuplicatedOverriddenExt1", duplicatedOverriddenExt.echo());
|
||||
|
|
@ -749,25 +749,25 @@ class ExtensionLoaderTest {
|
|||
@Test
|
||||
void testLoadByDubboInternalSPI() {
|
||||
ExtensionLoader<SPI1> extensionLoader = getExtensionLoader(SPI1.class);
|
||||
SPI1 spi1 = extensionLoader.getExtension("1",true);
|
||||
SPI1 spi1 = extensionLoader.getExtension("1", true);
|
||||
assertNotNull(spi1);
|
||||
|
||||
ExtensionLoader<SPI2> extensionLoader2 = getExtensionLoader(SPI2.class);
|
||||
SPI2 spi2 = extensionLoader2.getExtension("2",true);
|
||||
SPI2 spi2 = extensionLoader2.getExtension("2", true);
|
||||
assertNotNull(spi2);
|
||||
|
||||
try {
|
||||
ExtensionLoader<SPI3> extensionLoader3 = getExtensionLoader(SPI3.class);
|
||||
SPI3 spi3 = extensionLoader3.getExtension("3",true);
|
||||
SPI3 spi3 = extensionLoader3.getExtension("3", true);
|
||||
assertNotNull(spi3);
|
||||
}catch (IllegalStateException illegalStateException){
|
||||
} catch (IllegalStateException illegalStateException) {
|
||||
if (!illegalStateException.getMessage().contains("No such extension")) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionLoader<SPI4> extensionLoader4 = getExtensionLoader(SPI4.class);
|
||||
SPI4 spi4 = extensionLoader4.getExtension("4",true);
|
||||
SPI4 spi4 = extensionLoader4.getExtension("4", true);
|
||||
assertNotNull(spi4);
|
||||
|
||||
}
|
||||
|
|
@ -780,7 +780,7 @@ class ExtensionLoaderTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* The external {@link LoadingStrategy}, which can set if it support overridden
|
||||
* The external {@link LoadingStrategy}, which can set if it supports overriding.
|
||||
*/
|
||||
private static class DubboExternalLoadingStrategyTest implements LoadingStrategy {
|
||||
|
||||
|
|
@ -832,4 +832,4 @@ class ExtensionLoaderTest {
|
|||
return MAX_PRIORITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.apache.dubbo.common.extension;
|
|||
import org.apache.dubbo.common.extension.compatible.CompatibleExt;
|
||||
import org.apache.dubbo.common.extension.compatible.impl.CompatibleExtImpl1;
|
||||
import org.apache.dubbo.common.extension.compatible.impl.CompatibleExtImpl2;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -27,8 +29,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
class ExtensionLoader_Compatible_Test {
|
||||
|
||||
@Test
|
||||
void test_getExtension() throws Exception {
|
||||
assertTrue(ExtensionLoader.getExtensionLoader(CompatibleExt.class).getExtension("impl1") instanceof CompatibleExtImpl1);
|
||||
assertTrue(ExtensionLoader.getExtensionLoader(CompatibleExt.class).getExtension("impl2") instanceof CompatibleExtImpl2);
|
||||
void test_getExtension() {
|
||||
|
||||
ModuleModel moduleModel = ApplicationModel.defaultModel().getDefaultModule();
|
||||
|
||||
assertTrue(moduleModel.getExtensionLoader(CompatibleExt.class).getExtension("impl1") instanceof CompatibleExtImpl1);
|
||||
assertTrue(moduleModel.getExtensionLoader(CompatibleExt.class).getExtension("impl2") instanceof CompatibleExtImpl2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,23 +14,25 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.person;
|
||||
|
||||
package org.apache.dubbo.metrics.event;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ApplicationEvent extends MetricsEvent{
|
||||
private ApplicationEvent.Type type;
|
||||
public class Ageneric<T> implements Serializable {
|
||||
public static String NAME = "A";
|
||||
|
||||
public ApplicationEvent(Object source, ApplicationEvent.Type type) {
|
||||
super(source);
|
||||
this.type = type;
|
||||
private String name = NAME;
|
||||
private T data;
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public ApplicationEvent.Type getType() {
|
||||
return type;
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setType(ApplicationEvent.Type type) {
|
||||
this.type = type;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.common.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Bgeneric<T> implements Serializable {
|
||||
public static String NAME = "B";
|
||||
|
||||
private String name = NAME;
|
||||
private T data;
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,38 +14,43 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.rest.annotation.consumer;
|
||||
package org.apache.dubbo.common.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.dubbo.common.serialize.Constants;
|
||||
public class Cgeneric<T> implements Serializable {
|
||||
public static String NAME = "C";
|
||||
|
||||
public class HttpConnectionConfig {
|
||||
private String name = NAME;
|
||||
private T data;
|
||||
private Ageneric<T> a;
|
||||
private Bgeneric<PersonInfo> b;
|
||||
|
||||
|
||||
private int connectTimeout;
|
||||
private int readTimeout;
|
||||
private int chunkLength = 8196;
|
||||
private byte serialization = Constants.FASTJSON2_SERIALIZATION_ID;
|
||||
private int keepAlive = 60;
|
||||
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getReadTimeout() {
|
||||
return readTimeout;
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public int getChunkLength() {
|
||||
return chunkLength;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public byte getSerialization() {
|
||||
return serialization;
|
||||
public Ageneric<T> getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public int getKeepAlive() {
|
||||
return keepAlive;
|
||||
public void setA(Ageneric<T> a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public Bgeneric<PersonInfo> getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public void setB(Bgeneric<PersonInfo> b) {
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.common.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Dgeneric<T,Y,Z> implements Serializable {
|
||||
public static String NAME = "D";
|
||||
|
||||
private String name = NAME;
|
||||
private T t;
|
||||
private Y y;
|
||||
private Z z;
|
||||
|
||||
public T getT() {
|
||||
return t;
|
||||
}
|
||||
|
||||
public void setT(T t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public Y getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(Y y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Z getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(Z z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -75,13 +75,13 @@ class FrameworkStatusReportServiceTest {
|
|||
|
||||
// verify registrationStatus
|
||||
Object registrationStatus = reportContent.get(REGISTRATION_STATUS);
|
||||
Map<String, String> registrationMap = JsonUtils.getJson().toJavaObject(String.valueOf(registrationStatus), Map.class);
|
||||
Map<String, String> registrationMap = JsonUtils.toJavaObject(String.valueOf(registrationStatus), Map.class);
|
||||
Assertions.assertEquals(registrationMap.get("application"), "APP");
|
||||
Assertions.assertEquals(registrationMap.get("status"), "instance");
|
||||
|
||||
// verify addressConsumptionStatus
|
||||
Object addressConsumptionStatus = reportContent.get(ADDRESS_CONSUMPTION_STATUS);
|
||||
Map<String, String> consumptionMap = JsonUtils.getJson().toJavaObject(String.valueOf(addressConsumptionStatus), Map.class);
|
||||
Map<String, String> consumptionMap = JsonUtils.toJavaObject(String.valueOf(addressConsumptionStatus), Map.class);
|
||||
Assertions.assertEquals(consumptionMap.get("application"), "APP");
|
||||
Assertions.assertEquals(consumptionMap.get("service"), "Test");
|
||||
Assertions.assertEquals(consumptionMap.get("status"), "status");
|
||||
|
|
@ -91,7 +91,7 @@ class FrameworkStatusReportServiceTest {
|
|||
|
||||
// verify migrationStepStatus
|
||||
Object migrationStepStatus = reportContent.get(MIGRATION_STEP_STATUS);
|
||||
Map<String, String> migrationStepStatusMap = JsonUtils.getJson().toJavaObject(String.valueOf(migrationStepStatus), Map.class);
|
||||
Map<String, String> migrationStepStatusMap = JsonUtils.toJavaObject(String.valueOf(migrationStepStatus), Map.class);
|
||||
Assertions.assertEquals(migrationStepStatusMap.get("originStep"), "FORCE_INTERFACE");
|
||||
Assertions.assertEquals(migrationStepStatusMap.get("application"), "APP");
|
||||
Assertions.assertEquals(migrationStepStatusMap.get("service"), "Test");
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue