Merge branch 'apache-3.2' into apache-3.3
# Conflicts: # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java # dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java # dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
This commit is contained in:
commit
b14201f393
|
|
@ -33,7 +33,7 @@ The following code snippet comes from [Dubbo Samples](https://github.com/apache/
|
|||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/dubbo-samples-api
|
||||
cd dubbo-samples/1-basic/dubbo-samples-api
|
||||
```
|
||||
|
||||
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
|
||||
|
|
|
|||
|
|
@ -476,15 +476,21 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
|
||||
private boolean addValidInvoker(Invoker<T> invoker) {
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
return this.validInvokers.add(invoker);
|
||||
result = this.validInvokers.add(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean removeValidInvoker(Invoker<T> invoker) {
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
return this.validInvokers.remove(invoker);
|
||||
result = this.validInvokers.remove(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
|
|||
*/
|
||||
public class StaticDirectory<T> extends AbstractDirectory<T> {
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StaticDirectory.class);
|
||||
private final Class<T> interfaceClass;
|
||||
|
||||
public StaticDirectory(List<Invoker<T>> invokers) {
|
||||
this(null, invokers, null);
|
||||
|
|
@ -55,11 +56,12 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
|
|||
throw new IllegalArgumentException("invokers == null");
|
||||
}
|
||||
this.setInvokers(new BitList<>(invokers));
|
||||
this.interfaceClass = invokers.get(0).getInterface();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getInterface() {
|
||||
return getInvokers().get(0).getInterface();
|
||||
return interfaceClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Liste
|
|||
if (timeoutCountDown.isExpired()) {
|
||||
return AsyncRpcResult.newDefaultAsyncResult(new RpcException(RpcException.TIMEOUT_TERMINATE,
|
||||
"No time left for making the following call: " + invocation.getServiceName() + "."
|
||||
+ invocation.getMethodName() + ", terminate directly."), invocation);
|
||||
+ RpcUtils.getMethodName(invocation) + ", terminate directly."), invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleReposi
|
|||
}
|
||||
|
||||
private DynamicConfiguration getDynamicConfiguration() {
|
||||
return moduleModel.getModelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
return moduleModel.modelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.Invocation;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -83,7 +84,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
|
|||
if (REGISTRY_SERVICE_REFERENCE_PATH.equals(url.getServiceInterface())) {
|
||||
weight = url.getParameter(WEIGHT_KEY, DEFAULT_WEIGHT);
|
||||
} else {
|
||||
weight = url.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT);
|
||||
weight = url.getMethodParameter(RpcUtils.getMethodName(invocation), WEIGHT_KEY, DEFAULT_WEIGHT);
|
||||
if (weight > 0) {
|
||||
long timestamp = invoker.getUrl().getParameter(TIMESTAMP_KEY, 0L);
|
||||
if (timestamp > 0L) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import java.util.TreeMap;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
|
||||
|
||||
/**
|
||||
|
|
@ -97,10 +96,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
}
|
||||
|
||||
public Invoker<T> select(Invocation invocation) {
|
||||
boolean isGeneric = invocation.getMethodName().equals($INVOKE);
|
||||
String key = toKey(invocation.getArguments(),isGeneric);
|
||||
|
||||
byte[] digest = Bytes.getMD5(key);
|
||||
byte[] digest = Bytes.getMD5(RpcUtils.getMethodName(invocation));
|
||||
return selectForKey(hash(digest, 0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcStatus;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
|
@ -60,7 +61,7 @@ public class LeastActiveLoadBalance extends AbstractLoadBalance {
|
|||
for (int i = 0; i < length; i++) {
|
||||
Invoker<T> invoker = invokers.get(i);
|
||||
// Get the active number of the invoker
|
||||
int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive();
|
||||
int active = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation)).getActive();
|
||||
// Get the weight of the invoker's configuration. The default value is 100.
|
||||
int afterWarmup = getWeight(invoker, invocation);
|
||||
// save for later use
|
||||
|
|
@ -97,7 +98,7 @@ public class LeastActiveLoadBalance extends AbstractLoadBalance {
|
|||
return invokers.get(leastIndexes[0]);
|
||||
}
|
||||
if (!sameWeight && totalWeight > 0) {
|
||||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
|
||||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
|
||||
// totalWeight.
|
||||
int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight);
|
||||
// Return a invoker based on the random value.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
|
@ -115,7 +116,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
|
|||
String weight = invokerUrl.getParameter(WEIGHT_KEY);
|
||||
return StringUtils.isNotEmpty(weight);
|
||||
} else {
|
||||
String weight = invokerUrl.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY);
|
||||
String weight = invokerUrl.getMethodParameter(RpcUtils.getMethodName(invocation), WEIGHT_KEY);
|
||||
if (StringUtils.isNotEmpty(weight)) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
|
@ -79,7 +80,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
* @return
|
||||
*/
|
||||
protected <T> Collection<String> getInvokerAddrList(List<Invoker<T>> invokers, Invocation invocation) {
|
||||
String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();
|
||||
String key = invokers.get(0).getUrl().getServiceKey() + "." + RpcUtils.getMethodName(invocation);
|
||||
Map<String, WeightedRoundRobin> map = methodWeightMap.get(key);
|
||||
if (map != null) {
|
||||
return map.keySet();
|
||||
|
|
@ -89,7 +90,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
|
||||
@Override
|
||||
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
|
||||
String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();
|
||||
String key = invokers.get(0).getUrl().getServiceKey() + "." + RpcUtils.getMethodName(invocation);
|
||||
ConcurrentMap<String, WeightedRoundRobin> map = ConcurrentHashMapUtils.computeIfAbsent(methodWeightMap, key, k -> new ConcurrentHashMap<>());
|
||||
int totalWeight = 0;
|
||||
long maxCurrent = Long.MIN_VALUE;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.RpcStatus;
|
|||
import org.apache.dubbo.rpc.cluster.Constants;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -58,7 +59,7 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
slidePeriod = applicationModel.getModelEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
slidePeriod = applicationModel.modelEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
executorService = applicationModel.getFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getSharedExecutor();
|
||||
}
|
||||
|
|
@ -116,7 +117,7 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
// Filter out all the shortest response invokers
|
||||
for (int i = 0; i < length; i++) {
|
||||
Invoker<T> invoker = invokers.get(i);
|
||||
RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
|
||||
RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation));
|
||||
SlideWindowData slideWindowData = ConcurrentHashMapUtils.computeIfAbsent(methodMap, rpcStatus, SlideWindowData::new);
|
||||
|
||||
// Calculate the estimated response time from the product of active connections and succeeded average elapsed time.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
|
@ -55,7 +56,7 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
|
|||
String sampleValue;
|
||||
//get real invoked method name from invocation
|
||||
if (invocation != null && (METHOD_KEY.equals(conditionKey) || METHODS_KEY.equals(conditionKey))) {
|
||||
sampleValue = invocation.getMethodName();
|
||||
sampleValue = RpcUtils.getMethodName(invocation);
|
||||
} else {
|
||||
sampleValue = sample.get(conditionKey);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -83,7 +84,7 @@ public class DubboMethodMatch {
|
|||
|
||||
public boolean isMatch(Invocation invocation) {
|
||||
StringMatch nameMatch = getName_match();
|
||||
if (nameMatch != null && !nameMatch.isMatch(invocation.getMethodName())) {
|
||||
if (nameMatch != null && !nameMatch.isMatch(RpcUtils.getMethodName(invocation))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Compilable;
|
||||
|
|
@ -139,7 +140,7 @@ public class ScriptStateRouter<T> extends AbstractStateRouter<T> {
|
|||
return function.eval(bindings);
|
||||
} catch (ScriptException e) {
|
||||
logger.error(CLUSTER_SCRIPT_EXCEPTION, "Scriptrouter exec script error", "", "Script route error, rule has been ignored. rule: " + rule + ", method:" +
|
||||
invocation.getMethodName() + ", url: " + RpcContext.getContext().getUrl(), e);
|
||||
RpcUtils.getMethodName(invocation) + ", url: " + RpcContext.getContext().getUrl(), e);
|
||||
return invokers;
|
||||
}
|
||||
}, accessControlContext));
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
return null;
|
||||
}
|
||||
String methodName = invocation == null ? StringUtils.EMPTY_STRING : invocation.getMethodName();
|
||||
String methodName = invocation == null ? StringUtils.EMPTY_STRING : RpcUtils.getMethodName(invocation);
|
||||
|
||||
boolean sticky = invokers.get(0).getUrl()
|
||||
.getMethodParameter(methodName, CLUSTER_STICKY_KEY, DEFAULT_CLUSTER_STICKY);
|
||||
|
|
@ -363,7 +363,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
protected void checkInvokers(List<Invoker<T>> invokers, Invocation invocation) {
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
throw new RpcException(RpcException.NO_INVOKER_AVAILABLE_AFTER_FILTER, "Failed to invoke the method "
|
||||
+ invocation.getMethodName() + " in the service " + getInterface().getName()
|
||||
+ RpcUtils.getMethodName(invocation) + " in the service " + getInterface().getName()
|
||||
+ ". No provider available for the service " + getDirectory().getConsumerUrl().getServiceKey()
|
||||
+ " from registry " + getDirectory().getUrl().getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.dubbo.rpc.RpcContext;
|
|||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -109,7 +110,9 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
// Then the serviceContext will be cleared after the call is completed.
|
||||
return invokeWithContextAsync(invoker, invocation, consumerUrl);
|
||||
} catch (Throwable e) {
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failback to invoke method and start to retries","","Failback to invoke method " + invocation.getMethodName() + ", wait for retry in background. Ignored exception: "
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failback to invoke method and start to retries",
|
||||
"","Failback to invoke method " + RpcUtils.getMethodName(invocation) +
|
||||
", wait for retry in background. Ignored exception: "
|
||||
+ e.getMessage() + ", ",e);
|
||||
if (retries > 0) {
|
||||
addFailed(loadbalance, invocation, invokers, invoker, consumerUrl);
|
||||
|
|
@ -161,13 +164,13 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
@Override
|
||||
public void run(Timeout timeout) {
|
||||
try {
|
||||
logger.info("Attempt to retry to invoke method " + invocation.getMethodName() +
|
||||
logger.info("Attempt to retry to invoke method " + RpcUtils.getMethodName(invocation) +
|
||||
". The total will retry " + retries + " times, the current is the " + retriedTimes + " retry");
|
||||
Invoker<T> retryInvoker = select(loadbalance, invocation, invokers, Collections.singletonList(lastInvoker));
|
||||
lastInvoker = retryInvoker;
|
||||
invokeWithContextAsync(retryInvoker, invocation, consumerUrl);
|
||||
} catch (Throwable e) {
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failed retry to invoke method","","Failed retry to invoke method " + invocation.getMethodName() + ", waiting again.",e);
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failed retry to invoke method","","Failed retry to invoke method " + RpcUtils.getMethodName(invocation) + ", waiting again.",e);
|
||||
if ((++retriedTimes) >= retries) {
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failed retry to invoke method and retry times exceed threshold","","Failed retry times exceed threshold (" + retries + "), We have to abandon, invocation->" + invocation,e);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.apache.dubbo.rpc.Result;
|
|||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ public class FailfastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
throw new RpcException(e instanceof RpcException ? ((RpcException) e).getCode() : 0,
|
||||
"Failfast invoke providers " + invoker.getUrl() + " " + loadbalance.getClass().getSimpleName()
|
||||
+ " for service " + getInterface().getName()
|
||||
+ " method " + invocation.getMethodName() + " on consumer " + NetUtils.getLocalHost()
|
||||
+ " method " + RpcUtils.getMethodName(invocation) + " on consumer " + NetUtils.getLocalHost()
|
||||
+ " use dubbo version " + Version.getVersion()
|
||||
+ ", but no luck to perform the invocation. Last error is: " + e.getMessage(),
|
||||
e.getCause() != null ? e.getCause() : e);
|
||||
|
|
|
|||
|
|
@ -97,13 +97,13 @@ public class MockClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
Result result;
|
||||
|
||||
String value = getUrl().getMethodParameter(invocation.getMethodName(), MOCK_KEY, Boolean.FALSE.toString()).trim();
|
||||
String value = getUrl().getMethodParameter(RpcUtils.getMethodName(invocation), MOCK_KEY, Boolean.FALSE.toString()).trim();
|
||||
if (ConfigUtils.isEmpty(value)) {
|
||||
//no mock
|
||||
result = this.invoker.invoke(invocation);
|
||||
} else if (value.startsWith(FORCE_KEY)) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(CLUSTER_FAILED_MOCK_REQUEST,"force mock","","force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + getUrl());
|
||||
logger.warn(CLUSTER_FAILED_MOCK_REQUEST,"force mock","","force-mock: " + RpcUtils.getMethodName(invocation) + " force-mock enabled , url : " + getUrl());
|
||||
}
|
||||
//force:direct mock
|
||||
result = doMockInvoke(invocation, null);
|
||||
|
|
@ -128,7 +128,7 @@ public class MockClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
}
|
||||
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(CLUSTER_FAILED_MOCK_REQUEST,"failed to mock invoke","","fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + getUrl(),e);
|
||||
logger.warn(CLUSTER_FAILED_MOCK_REQUEST,"failed to mock invoke","","fail-mock: " + RpcUtils.getMethodName(invocation) + " fail-mock enabled , url : " + getUrl(),e);
|
||||
}
|
||||
result = doMockInvoke(invocation, e);
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ public class MockClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
} catch (RpcException e) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Exception when try to invoke mock. Get mock invokers error for service:"
|
||||
+ getUrl().getServiceInterface() + ", method:" + invocation.getMethodName()
|
||||
+ getUrl().getServiceInterface() + ", method:" + RpcUtils.getMethodName(invocation)
|
||||
+ ", will construct a new mock with 'new MockInvoker()'.", e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.url.component.DubboServiceAddressURL;
|
||||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
|
|
@ -35,6 +36,7 @@ import org.apache.dubbo.rpc.cluster.Directory;
|
|||
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
|
||||
import org.apache.dubbo.rpc.listener.ExporterChangeListener;
|
||||
import org.apache.dubbo.rpc.listener.InjvmExporterListener;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -142,26 +144,26 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
// When broadcasting, it should be called remotely.
|
||||
if (isBroadcast()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Performing broadcast call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey());
|
||||
logger.debug("Performing broadcast call for method: " + RpcUtils.getMethodName(invocation) + " of service: " + getUrl().getServiceKey());
|
||||
}
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
if (peerFlag) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Performing point-to-point call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey());
|
||||
logger.debug("Performing point-to-point call for method: " + RpcUtils.getMethodName(invocation) + " of service: " + getUrl().getServiceKey());
|
||||
}
|
||||
// If it's a point-to-point direct connection, invoke the original Invoker
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
if (isInjvmExported()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Performing local JVM call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey());
|
||||
logger.debug("Performing local JVM call for method: " + RpcUtils.getMethodName(invocation) + " of service: " + getUrl().getServiceKey());
|
||||
}
|
||||
// If it's exported to the local JVM, invoke the corresponding Invoker
|
||||
return injvmInvoker.invoke(invocation);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Performing remote call for method: " + invocation.getMethodName() + " of service: " + getUrl().getServiceKey());
|
||||
logger.debug("Performing remote call for method: " + RpcUtils.getMethodName(invocation) + " of service: " + getUrl().getServiceKey());
|
||||
}
|
||||
// Otherwise, delegate the invocation to the original Invoker
|
||||
return invoker.invoke(invocation);
|
||||
|
|
@ -178,7 +180,7 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
}
|
||||
if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
|
||||
&& exporter.getInvoker().getUrl().getProtocol().equalsIgnoreCase(LOCAL_PROTOCOL)) {
|
||||
createInjvmInvoker();
|
||||
createInjvmInvoker(exporter);
|
||||
isExported.compareAndSet(false, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -274,14 +276,19 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
|
|||
/**
|
||||
* Creates a new Invoker for the current ScopeClusterInvoker and exports it to the local JVM.
|
||||
*/
|
||||
private void createInjvmInvoker() {
|
||||
private void createInjvmInvoker(Exporter<?> exporter) {
|
||||
if (injvmInvoker == null) {
|
||||
synchronized (createLock) {
|
||||
if (injvmInvoker == null) {
|
||||
URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
|
||||
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);
|
||||
|
||||
DubboServiceAddressURL consumerUrl = new DubboServiceAddressURL(url.getUrlAddress(), url.getUrlParam(),
|
||||
exporter.getInvoker().getUrl(), null);
|
||||
|
||||
Invoker<?> invoker = protocolSPI.refer(getInterface(), consumerUrl);
|
||||
List<Invoker<?>> invokers = new ArrayList<>();
|
||||
invokers.add(invoker);
|
||||
injvmInvoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT, false).join(new StaticDirectory(url, invokers), true);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
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;
|
||||
|
|
@ -24,6 +23,8 @@ import org.apache.dubbo.rpc.BaseFilter;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
|
|
|||
|
|
@ -17,14 +17,15 @@
|
|||
|
||||
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.support.ObservationSenderFilter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
import io.micrometer.tracing.test.simple.SpansAssert;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
|
||||
class ObservationSenderFilterTest extends AbstractObservationFilterTest {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ import java.util.Set;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION;
|
||||
|
||||
/**
|
||||
* Utilities for manipulating configurations from different sources
|
||||
|
|
@ -77,7 +76,7 @@ public final class ConfigurationUtils {
|
|||
* @return
|
||||
*/
|
||||
public static Configuration getSystemConfiguration(ScopeModel scopeModel) {
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).getModelEnvironment().getSystemConfiguration();
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).modelEnvironment().getSystemConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,7 +85,7 @@ public final class ConfigurationUtils {
|
|||
* @return
|
||||
*/
|
||||
public static Configuration getEnvConfiguration(ScopeModel scopeModel) {
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).getModelEnvironment().getEnvironmentConfiguration();
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).modelEnvironment().getEnvironmentConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,11 +97,11 @@ public final class ConfigurationUtils {
|
|||
*/
|
||||
|
||||
public static Configuration getGlobalConfiguration(ScopeModel scopeModel) {
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).getModelEnvironment().getConfiguration();
|
||||
return getScopeModelOrDefaultApplicationModel(scopeModel).modelEnvironment().getConfiguration();
|
||||
}
|
||||
|
||||
public static Configuration getDynamicGlobalConfiguration(ScopeModel scopeModel) {
|
||||
return scopeModel.getModelEnvironment().getDynamicGlobalConfiguration();
|
||||
return scopeModel.modelEnvironment().getDynamicGlobalConfiguration();
|
||||
}
|
||||
|
||||
// FIXME
|
||||
|
|
@ -174,7 +173,7 @@ public final class ConfigurationUtils {
|
|||
public static Map<String, String> parseProperties(String content) throws IOException {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (StringUtils.isEmpty(content)) {
|
||||
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "Config center was specified, but no config item found.");
|
||||
logger.info("Config center was specified, but no config item found.");
|
||||
} else {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new StringReader(content));
|
||||
|
|
@ -365,7 +364,7 @@ public final class ConfigurationUtils {
|
|||
*/
|
||||
@Deprecated
|
||||
public static Configuration getSystemConfiguration() {
|
||||
return ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration();
|
||||
return ApplicationModel.defaultModel().modelEnvironment().getSystemConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -375,7 +374,7 @@ public final class ConfigurationUtils {
|
|||
*/
|
||||
@Deprecated
|
||||
public static Configuration getEnvConfiguration() {
|
||||
return ApplicationModel.defaultModel().getModelEnvironment().getEnvironmentConfiguration();
|
||||
return ApplicationModel.defaultModel().modelEnvironment().getEnvironmentConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -385,7 +384,7 @@ public final class ConfigurationUtils {
|
|||
*/
|
||||
@Deprecated
|
||||
public static Configuration getGlobalConfiguration() {
|
||||
return ApplicationModel.defaultModel().getModelEnvironment().getConfiguration();
|
||||
return ApplicationModel.defaultModel().modelEnvironment().getConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -395,7 +394,7 @@ public final class ConfigurationUtils {
|
|||
*/
|
||||
@Deprecated
|
||||
public static Configuration getDynamicGlobalConfiguration() {
|
||||
return ApplicationModel.defaultModel().getDefaultModule().getModelEnvironment().getDynamicGlobalConfiguration();
|
||||
return ApplicationModel.defaultModel().getDefaultModule().modelEnvironment().getDynamicGlobalConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class ModuleEnvironment extends Environment implements ModuleExt {
|
|||
public ModuleEnvironment(ModuleModel moduleModel) {
|
||||
super(moduleModel);
|
||||
this.moduleModel = moduleModel;
|
||||
this.applicationDelegate = moduleModel.getApplicationModel().getModelEnvironment();
|
||||
this.applicationDelegate = moduleModel.getApplicationModel().modelEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.ServiceLoader.load;
|
||||
|
|
@ -346,7 +347,9 @@ public class ExtensionLoader<T> {
|
|||
checkDestroyed();
|
||||
// solve the bug of using @SPI's wrapper method to report a null pointer exception.
|
||||
Map<Class<?>, T> activateExtensionsMap = new TreeMap<>(activateComparator);
|
||||
List<String> names = values == null ? new ArrayList<>(0) : asList(values);
|
||||
List<String> names = values == null ?
|
||||
new ArrayList<>(0) :
|
||||
Arrays.stream(values).map(StringUtils::trim).collect(Collectors.toList());
|
||||
Set<String> namesSet = new HashSet<>(names);
|
||||
if (!namesSet.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) {
|
||||
if (cachedActivateGroups.size() == 0) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.AbstractExecutorService;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
/**
|
||||
|
|
@ -46,7 +47,7 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
/**
|
||||
* Wait thread. It must be visible to other threads and does not need to be thread-safe
|
||||
*/
|
||||
private volatile Object waiter;
|
||||
private final AtomicReference<Object> waiter = new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* Waits until there is a task, executes the task and all queued tasks (if there're any). The task is either a normal
|
||||
|
|
@ -56,22 +57,25 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
throwIfInterrupted();
|
||||
Runnable runnable = queue.poll();
|
||||
if (runnable == null) {
|
||||
waiter = Thread.currentThread();
|
||||
try {
|
||||
while ((runnable = queue.poll()) == null) {
|
||||
long restTime = deadline - System.nanoTime();
|
||||
if (restTime <= 0) {
|
||||
return;
|
||||
if (waiter.compareAndSet(null, Thread.currentThread())) {
|
||||
try {
|
||||
while ((runnable = queue.poll()) == null && waiter.get() == Thread.currentThread()) {
|
||||
long restTime = deadline - System.nanoTime();
|
||||
if (restTime <= 0) {
|
||||
return;
|
||||
}
|
||||
LockSupport.parkNanos(this, restTime);
|
||||
throwIfInterrupted();
|
||||
}
|
||||
LockSupport.parkNanos(this, restTime);
|
||||
throwIfInterrupted();
|
||||
} finally {
|
||||
waiter.compareAndSet(Thread.currentThread(), null);
|
||||
}
|
||||
} finally {
|
||||
waiter = null;
|
||||
}
|
||||
}
|
||||
do {
|
||||
runnable.run();
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
} while ((runnable = queue.poll()) != null);
|
||||
}
|
||||
|
||||
|
|
@ -91,8 +95,8 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
public void execute(Runnable runnable) {
|
||||
RunnableWrapper run = new RunnableWrapper(runnable);
|
||||
queue.add(run);
|
||||
if (waiter != SHUTDOWN) {
|
||||
LockSupport.unpark((Thread) waiter);
|
||||
if (waiter.get() != SHUTDOWN) {
|
||||
LockSupport.unpark((Thread) waiter.get());
|
||||
} else if (queue.remove(run)) {
|
||||
throw new RejectedExecutionException();
|
||||
}
|
||||
|
|
@ -109,7 +113,10 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
|
||||
@Override
|
||||
public List<Runnable> shutdownNow() {
|
||||
waiter = SHUTDOWN;
|
||||
if (waiter.get() != SHUTDOWN) {
|
||||
LockSupport.unpark((Thread) waiter.get());
|
||||
}
|
||||
waiter.set(SHUTDOWN);
|
||||
Runnable runnable;
|
||||
while ((runnable = queue.poll()) != null) {
|
||||
runnable.run();
|
||||
|
|
@ -119,7 +126,7 @@ public class ThreadlessExecutor extends AbstractExecutorService {
|
|||
|
||||
@Override
|
||||
public boolean isShutdown() {
|
||||
return waiter == SHUTDOWN;
|
||||
return waiter.get() == SHUTDOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ToStringUtils {
|
||||
|
||||
|
|
@ -36,4 +40,63 @@ public class ToStringUtils {
|
|||
return obj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static String toString(Object obj) {
|
||||
if (obj == null) {
|
||||
return "null";
|
||||
}
|
||||
if (ClassUtils.isSimpleType(obj.getClass())) {
|
||||
return obj.toString();
|
||||
}
|
||||
if (obj.getClass().isPrimitive()) {
|
||||
return obj.toString();
|
||||
}
|
||||
if (obj instanceof Object[]) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("[");
|
||||
Object[] objects = (Object[]) obj;
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
stringBuilder.append(toString(objects[i]));
|
||||
if (i != objects.length - 1) {
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
}
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
if (obj instanceof List) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("[");
|
||||
List list = (List) obj;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
stringBuilder.append(toString(list.get(i)));
|
||||
if (i != list.size() - 1) {
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
}
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
if (obj instanceof Map) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("{");
|
||||
Map map = (Map) obj;
|
||||
int i = 0;
|
||||
for (Object key : map.keySet()) {
|
||||
stringBuilder.append(toString(key));
|
||||
stringBuilder.append("=");
|
||||
stringBuilder.append(toString(map.get(key)));
|
||||
if (i != map.size() - 1) {
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
stringBuilder.append("}");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
if (obj instanceof AbstractConfig) {
|
||||
return obj.toString();
|
||||
}
|
||||
return obj.getClass() + "@" + Integer.toHexString(System.identityHashCode(obj));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.common.utils.FieldUtils;
|
|||
import org.apache.dubbo.common.utils.MethodUtils;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.ToStringUtils;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.context.ConfigMode;
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
|
|
@ -695,7 +696,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
}
|
||||
|
||||
protected void refreshWithPrefixes(List<String> prefixes, ConfigMode configMode) {
|
||||
Environment environment = getScopeModel().getModelEnvironment();
|
||||
Environment environment = getScopeModel().modelEnvironment();
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps();
|
||||
|
||||
// Search props starts with PREFIX in order
|
||||
|
|
@ -967,7 +968,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
buf.append(' ');
|
||||
buf.append(key);
|
||||
buf.append("=\"");
|
||||
buf.append(key.equals("password") ? "******" : value);
|
||||
buf.append(key.equals("password") ? "******" : ToStringUtils.toString(value));
|
||||
buf.append('\"');
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
|
||||
protected Environment getEnvironment() {
|
||||
return getScopeModel().getModelEnvironment();
|
||||
return getScopeModel().modelEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import org.apache.dubbo.config.support.Parameter;
|
|||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.support.ProtocolUtils;
|
||||
|
||||
import java.beans.Transient;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
|
||||
|
|
@ -184,6 +186,7 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
protected boolean isNeedCheckMethod() {
|
||||
return StringUtils.isEmpty(getGeneric());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
private void refreshArgument(ArgumentConfig argument, InmemoryConfiguration subPropsConfiguration) {
|
||||
if (argument.getIndex() != null && argument.getIndex() >= 0) {
|
||||
String prefix = argument.getIndex() + ".";
|
||||
Environment environment = getScopeModel().getModelEnvironment();
|
||||
Environment environment = getScopeModel().modelEnvironment();
|
||||
List<java.lang.reflect.Method> methods = MethodUtils.getMethods(argument.getClass(),
|
||||
method -> method.getDeclaringClass() != Object.class);
|
||||
for (java.lang.reflect.Method method : methods) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -135,11 +136,13 @@ public class ModuleConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public ModuleModel getScopeModel() {
|
||||
return (ModuleModel) super.getScopeModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
protected ScopeModel getDefaultModel() {
|
||||
return ApplicationModel.defaultModel().getDefaultModule();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public Map<String, String> getMetaData() {
|
||||
return getMetaData(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public Map<String, String> getMetaData() {
|
||||
return getMetaData(null);
|
||||
}
|
||||
|
|
@ -425,7 +426,25 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
|
||||
public abstract boolean isUnexported();
|
||||
|
||||
/**
|
||||
* Export service to network
|
||||
*
|
||||
* @param register Whether register service to registry. If false, can be registered manually
|
||||
* through the {@link ServiceConfigBase#register(boolean)} API.
|
||||
*/
|
||||
public abstract void export(boolean register);
|
||||
|
||||
public abstract void register();
|
||||
/**
|
||||
* Register delay published service to registry.
|
||||
*/
|
||||
public final void register() {
|
||||
register(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register delay published service to registry.
|
||||
*
|
||||
* @param onlyDefault only register those services that export with configured register false
|
||||
*/
|
||||
public abstract void register(boolean onlyDefault);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
this.scopeModel = scopeModel;
|
||||
this.applicationModel = ScopeModelUtil.getApplicationModel(scopeModel);
|
||||
this.supportedConfigTypes = supportedConfigTypes;
|
||||
environment = scopeModel.getModelEnvironment();
|
||||
environment = scopeModel.modelEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -113,7 +113,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
if (!initialized.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
CompositeConfiguration configuration = scopeModel.getModelEnvironment().getConfiguration();
|
||||
CompositeConfiguration configuration = scopeModel.modelEnvironment().getConfiguration();
|
||||
|
||||
// dubbo.config.mode
|
||||
String configModeStr = (String) configuration.getProperty(ConfigKeys.DUBBO_CONFIG_MODE);
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
package org.apache.dubbo.config.nested;
|
||||
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.dubbo.config.support.Nested;
|
||||
|
||||
public class ExporterConfig implements Serializable {
|
||||
|
||||
@Nested
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ public class ApplicationModel extends ScopeModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Environment getModelEnvironment() {
|
||||
public Environment modelEnvironment() {
|
||||
if (environment == null) {
|
||||
environment = (Environment) this.getExtensionLoader(ApplicationExt.class)
|
||||
.getExtension(Environment.NAME);
|
||||
|
|
@ -390,11 +390,11 @@ public class ApplicationModel extends ScopeModel {
|
|||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replace to {@link ScopeModel#getModelEnvironment()}
|
||||
* @deprecated Replace to {@link ScopeModel#modelEnvironment()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Environment getEnvironment() {
|
||||
return defaultModel().getModelEnvironment();
|
||||
return defaultModel().modelEnvironment();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ public class FrameworkModel extends ScopeModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Environment getModelEnvironment() {
|
||||
public Environment modelEnvironment() {
|
||||
throw new UnsupportedOperationException("Environment is inaccessible for FrameworkModel");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ public class ModuleModel extends ScopeModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ModuleEnvironment getModelEnvironment() {
|
||||
public ModuleEnvironment modelEnvironment() {
|
||||
if (moduleEnvironment == null) {
|
||||
moduleEnvironment = (ModuleEnvironment) this.getExtensionLoader(ModuleExt.class)
|
||||
.getExtension(ModuleEnvironment.NAME);
|
||||
|
|
|
|||
|
|
@ -243,7 +243,28 @@ public abstract class ScopeModel implements ExtensionAccessor {
|
|||
return Collections.unmodifiableSet(classLoaders);
|
||||
}
|
||||
|
||||
public abstract Environment getModelEnvironment();
|
||||
/**
|
||||
* Get current model's environment.
|
||||
* </br>
|
||||
* Note: This method should not start with `get` or it would be invoked due to Spring boot refresh.
|
||||
* @see <a href="https://github.com/apache/dubbo/issues/12542">Configuration refresh issue</a>
|
||||
*/
|
||||
public abstract Environment modelEnvironment();
|
||||
|
||||
/**
|
||||
* Get current model's environment.
|
||||
*
|
||||
* @see <a href="https://github.com/apache/dubbo/issues/12542">Configuration refresh issue</a>
|
||||
* @deprecated use modelEnvironment() instead
|
||||
*/
|
||||
@Deprecated
|
||||
public final Environment getModelEnvironment() {
|
||||
try {
|
||||
return modelEnvironment();
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getInternalId() {
|
||||
return this.internalId;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class ConfigurationUtilsTest {
|
|||
FrameworkModel frameworkModel = new FrameworkModel();
|
||||
|
||||
ApplicationModel applicationModel = frameworkModel.newApplication();
|
||||
Environment originApplicationEnvironment = applicationModel.getModelEnvironment();
|
||||
Environment originApplicationEnvironment = applicationModel.modelEnvironment();
|
||||
Environment applicationEnvironment = Mockito.spy(originApplicationEnvironment);
|
||||
applicationModel.setEnvironment(applicationEnvironment);
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ class ConfigurationUtilsTest {
|
|||
Assertions.assertEquals("a", ConfigurationUtils.getCachedDynamicProperty(applicationModel, "TestKey", "xxx"));
|
||||
|
||||
ModuleModel moduleModel = applicationModel.newModule();
|
||||
ModuleEnvironment originModuleEnvironment = moduleModel.getModelEnvironment();
|
||||
ModuleEnvironment originModuleEnvironment = moduleModel.modelEnvironment();
|
||||
ModuleEnvironment moduleEnvironment = Mockito.spy(originModuleEnvironment);
|
||||
moduleModel.setModuleEnvironment(moduleEnvironment);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class EnvironmentTest {
|
|||
|
||||
@Test
|
||||
void testResolvePlaceholders() {
|
||||
Environment environment = ApplicationModel.defaultModel().getModelEnvironment();
|
||||
Environment environment = ApplicationModel.defaultModel().modelEnvironment();
|
||||
|
||||
Map<String, String> externalMap = new LinkedHashMap<>();
|
||||
externalMap.put("zookeeper.address", "127.0.0.1");
|
||||
|
|
@ -65,7 +65,7 @@ class EnvironmentTest {
|
|||
void test() {
|
||||
FrameworkModel frameworkModel = new FrameworkModel();
|
||||
ApplicationModel applicationModel = frameworkModel.newApplication();
|
||||
Environment environment = applicationModel.getModelEnvironment();
|
||||
Environment environment = applicationModel.modelEnvironment();
|
||||
|
||||
// test getPrefixedConfiguration
|
||||
RegistryConfig registryConfig = new RegistryConfig();
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ class ExtensionLoaderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void test_getActivateExtension_WithWrapper() {
|
||||
void test_getActivateExtension_WithWrapper1() {
|
||||
URL url = URL.valueOf("test://localhost/test");
|
||||
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
|
||||
.getActivateExtension(url, new String[]{}, "order");
|
||||
|
|
@ -596,7 +596,7 @@ class ExtensionLoaderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testLoadDefaultActivateExtension() {
|
||||
void testLoadDefaultActivateExtension1() {
|
||||
// test default
|
||||
URL url = URL.valueOf("test://localhost/test?ext=order1,default");
|
||||
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
|
||||
|
|
@ -620,6 +620,31 @@ class ExtensionLoaderTest {
|
|||
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadDefaultActivateExtension2() {
|
||||
// test default
|
||||
URL url = URL.valueOf("test://localhost/test?ext=order1 , default");
|
||||
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
|
||||
.getActivateExtension(url, "ext", "default_group");
|
||||
Assertions.assertEquals(2, list.size());
|
||||
assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class);
|
||||
assertSame(list.get(1).getClass(), ActivateExt1Impl1.class);
|
||||
|
||||
url = URL.valueOf("test://localhost/test?ext=default, order1");
|
||||
list = getExtensionLoader(ActivateExt1.class)
|
||||
.getActivateExtension(url, "ext", "default_group");
|
||||
Assertions.assertEquals(2, list.size());
|
||||
assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
|
||||
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
|
||||
|
||||
url = URL.valueOf("test://localhost/test?ext=order1");
|
||||
list = getExtensionLoader(ActivateExt1.class)
|
||||
.getActivateExtension(url, "ext", "default_group");
|
||||
Assertions.assertEquals(2, list.size());
|
||||
assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
|
||||
assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInjectExtension() {
|
||||
// register bean for test ScopeBeanExtensionInjector
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class ModuleModelTest {
|
|||
ApplicationModel applicationModel = frameworkModel.newApplication();
|
||||
ModuleModel moduleModel = applicationModel.newModule();
|
||||
|
||||
ModuleEnvironment modelEnvironment = moduleModel.getModelEnvironment();
|
||||
ModuleEnvironment modelEnvironment = moduleModel.modelEnvironment();
|
||||
Assertions.assertNotNull(modelEnvironment);
|
||||
|
||||
frameworkModel.destroy();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class ScopeModelUtilTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Environment getModelEnvironment() {
|
||||
public Environment modelEnvironment() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,21 +23,532 @@ import org.apache.dubbo.common.constants.QosConstants;
|
|||
import org.apache.dubbo.common.constants.RegistryConstants;
|
||||
import org.apache.dubbo.common.constants.RemotingConstants;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Deprecated
|
||||
public class Constants implements CommonConstants,
|
||||
QosConstants,
|
||||
FilterConstants,
|
||||
RegistryConstants,
|
||||
RemotingConstants,
|
||||
org.apache.dubbo.config.Constants,
|
||||
org.apache.dubbo.remoting.Constants,
|
||||
org.apache.dubbo.rpc.cluster.Constants,
|
||||
org.apache.dubbo.monitor.Constants,
|
||||
org.apache.dubbo.rpc.Constants,
|
||||
org.apache.dubbo.rpc.protocol.dubbo.Constants,
|
||||
org.apache.dubbo.common.serialize.Constants,
|
||||
org.apache.dubbo.common.config.configcenter.Constants,
|
||||
org.apache.dubbo.metadata.report.support.Constants ,
|
||||
org.apache.dubbo.rpc.protocol.rest.Constants,
|
||||
org.apache.dubbo.registry.Constants {
|
||||
QosConstants,
|
||||
FilterConstants,
|
||||
RegistryConstants,
|
||||
RemotingConstants,
|
||||
org.apache.dubbo.config.Constants,
|
||||
org.apache.dubbo.remoting.Constants,
|
||||
org.apache.dubbo.rpc.cluster.Constants,
|
||||
org.apache.dubbo.monitor.Constants,
|
||||
org.apache.dubbo.rpc.Constants,
|
||||
org.apache.dubbo.rpc.protocol.dubbo.Constants,
|
||||
org.apache.dubbo.common.serialize.Constants,
|
||||
org.apache.dubbo.common.config.configcenter.Constants,
|
||||
org.apache.dubbo.metadata.report.support.Constants,
|
||||
org.apache.dubbo.rpc.protocol.rest.Constants,
|
||||
org.apache.dubbo.registry.Constants {
|
||||
public static final String PROVIDER = "provider";
|
||||
|
||||
public static final String CONSUMER = "consumer";
|
||||
|
||||
public static final String REGISTER = "register";
|
||||
|
||||
public static final String UNREGISTER = "unregister";
|
||||
|
||||
public static final String SUBSCRIBE = "subscribe";
|
||||
|
||||
public static final String UNSUBSCRIBE = "unsubscribe";
|
||||
|
||||
public static final String CATEGORY_KEY = "category";
|
||||
|
||||
public static final String PROVIDERS_CATEGORY = "providers";
|
||||
|
||||
public static final String CONSUMERS_CATEGORY = "consumers";
|
||||
|
||||
public static final String ROUTERS_CATEGORY = "routers";
|
||||
|
||||
public static final String CONFIGURATORS_CATEGORY = "configurators";
|
||||
|
||||
public static final String DEFAULT_CATEGORY = PROVIDERS_CATEGORY;
|
||||
|
||||
public static final String ENABLED_KEY = "enabled";
|
||||
|
||||
public static final String DISABLED_KEY = "disabled";
|
||||
|
||||
public static final String VALIDATION_KEY = "validation";
|
||||
|
||||
public static final String CACHE_KEY = "cache";
|
||||
|
||||
public static final String DYNAMIC_KEY = "dynamic";
|
||||
|
||||
public static final String DUBBO_PROPERTIES_KEY = "dubbo.properties.file";
|
||||
|
||||
public static final String DEFAULT_DUBBO_PROPERTIES = "dubbo.properties";
|
||||
|
||||
public static final String SENT_KEY = "sent";
|
||||
|
||||
public static final boolean DEFAULT_SENT = false;
|
||||
|
||||
public static final String REGISTRY_PROTOCOL = "registry";
|
||||
|
||||
public static final String $INVOKE = "$invoke";
|
||||
|
||||
public static final String $ECHO = "$echo";
|
||||
|
||||
public static final int DEFAULT_IO_THREADS = Runtime.getRuntime()
|
||||
.availableProcessors() + 1;
|
||||
|
||||
public static final String DEFAULT_PROXY = "javassist";
|
||||
|
||||
public static final int DEFAULT_PAYLOAD = 8 * 1024 * 1024;
|
||||
|
||||
public static final String DEFAULT_CLUSTER = "failover";
|
||||
|
||||
public static final String DEFAULT_DIRECTORY = "dubbo";
|
||||
|
||||
public static final String DEFAULT_LOADBALANCE = "random";
|
||||
|
||||
public static final String DEFAULT_PROTOCOL = "dubbo";
|
||||
|
||||
public static final String DEFAULT_EXCHANGER = "header";
|
||||
|
||||
public static final String DEFAULT_TRANSPORTER = "netty";
|
||||
|
||||
public static final String DEFAULT_REMOTING_SERVER = "netty";
|
||||
|
||||
public static final String DEFAULT_REMOTING_CLIENT = "netty";
|
||||
|
||||
public static final String DEFAULT_REMOTING_CODEC = "dubbo";
|
||||
|
||||
public static final String DEFAULT_REMOTING_SERIALIZATION = "hessian2";
|
||||
|
||||
public static final String DEFAULT_HTTP_SERVER = "servlet";
|
||||
|
||||
public static final String DEFAULT_HTTP_CLIENT = "jdk";
|
||||
|
||||
public static final String DEFAULT_HTTP_SERIALIZATION = "json";
|
||||
|
||||
public static final String DEFAULT_CHARSET = "UTF-8";
|
||||
|
||||
public static final int DEFAULT_WEIGHT = 100;
|
||||
|
||||
public static final int DEFAULT_FORKS = 2;
|
||||
|
||||
public static final String DEFAULT_THREAD_NAME = "Dubbo";
|
||||
|
||||
public static final int DEFAULT_CORE_THREADS = 0;
|
||||
|
||||
public static final int DEFAULT_THREADS = 200;
|
||||
|
||||
public static final int DEFAULT_QUEUES = 0;
|
||||
|
||||
public static final int DEFAULT_ALIVE = 60 * 1000;
|
||||
|
||||
public static final int DEFAULT_CONNECTIONS = 0;
|
||||
|
||||
public static final int DEFAULT_ACCEPTS = 0;
|
||||
|
||||
public static final int DEFAULT_IDLE_TIMEOUT = 600 * 1000;
|
||||
|
||||
public static final int DEFAULT_HEARTBEAT = 60 * 1000;
|
||||
|
||||
public static final int DEFAULT_TIMEOUT = 1000;
|
||||
|
||||
public static final int DEFAULT_CONNECT_TIMEOUT = 3000;
|
||||
|
||||
public static final int DEFAULT_RETRIES = 2;
|
||||
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
public static final int MAX_BUFFER_SIZE = 16 * 1024;
|
||||
|
||||
public static final int MIN_BUFFER_SIZE = 1 * 1024;
|
||||
|
||||
public static final String REMOVE_VALUE_PREFIX = "-";
|
||||
|
||||
public static final String HIDE_KEY_PREFIX = ".";
|
||||
|
||||
public static final String DEFAULT_KEY_PREFIX = "default.";
|
||||
|
||||
public static final String DEFAULT_KEY = "default";
|
||||
|
||||
public static final String LOADBALANCE_KEY = "loadbalance";
|
||||
|
||||
public static final String ROUTER_KEY = "router";
|
||||
|
||||
public static final String CLUSTER_KEY = "cluster";
|
||||
|
||||
public static final String REGISTRY_KEY = "registry";
|
||||
|
||||
public static final String MONITOR_KEY = "monitor";
|
||||
|
||||
public static final String SIDE_KEY = "side";
|
||||
|
||||
public static final String PROVIDER_SIDE = "provider";
|
||||
|
||||
public static final String CONSUMER_SIDE = "consumer";
|
||||
|
||||
public static final String DEFAULT_REGISTRY = "dubbo";
|
||||
|
||||
public static final String BACKUP_KEY = "backup";
|
||||
|
||||
public static final String DIRECTORY_KEY = "directory";
|
||||
|
||||
public static final String DEPRECATED_KEY = "deprecated";
|
||||
|
||||
public static final String ANYHOST_KEY = "anyhost";
|
||||
|
||||
public static final String ANYHOST_VALUE = "0.0.0.0";
|
||||
|
||||
public static final String LOCALHOST_KEY = "localhost";
|
||||
|
||||
public static final String LOCALHOST_VALUE = "127.0.0.1";
|
||||
|
||||
public static final String APPLICATION_KEY = "application";
|
||||
|
||||
public static final String LOCAL_KEY = "local";
|
||||
|
||||
public static final String STUB_KEY = "stub";
|
||||
|
||||
public static final String MOCK_KEY = "mock";
|
||||
|
||||
public static final String PROTOCOL_KEY = "protocol";
|
||||
|
||||
public static final String PROXY_KEY = "proxy";
|
||||
|
||||
public static final String WEIGHT_KEY = "weight";
|
||||
|
||||
public static final String FORKS_KEY = "forks";
|
||||
|
||||
public static final String DEFAULT_THREADPOOL = "limited";
|
||||
|
||||
public static final String DEFAULT_CLIENT_THREADPOOL = "cached";
|
||||
|
||||
public static final String THREADPOOL_KEY = "threadpool";
|
||||
|
||||
public static final String THREAD_NAME_KEY = "threadname";
|
||||
|
||||
public static final String IO_THREADS_KEY = "iothreads";
|
||||
|
||||
public static final String CORE_THREADS_KEY = "corethreads";
|
||||
|
||||
public static final String THREADS_KEY = "threads";
|
||||
|
||||
public static final String QUEUES_KEY = "queues";
|
||||
|
||||
public static final String ALIVE_KEY = "alive";
|
||||
|
||||
public static final String EXECUTES_KEY = "executes";
|
||||
|
||||
public static final String BUFFER_KEY = "buffer";
|
||||
|
||||
public static final String PAYLOAD_KEY = "payload";
|
||||
|
||||
public static final String REFERENCE_FILTER_KEY = "reference.filter";
|
||||
|
||||
public static final String INVOKER_LISTENER_KEY = "invoker.listener";
|
||||
|
||||
public static final String SERVICE_FILTER_KEY = "service.filter";
|
||||
|
||||
public static final String EXPORTER_LISTENER_KEY = "exporter.listener";
|
||||
|
||||
public static final String ACCESS_LOG_KEY = "accesslog";
|
||||
|
||||
public static final String ACTIVES_KEY = "actives";
|
||||
|
||||
public static final String CONNECTIONS_KEY = "connections";
|
||||
|
||||
public static final String ACCEPTS_KEY = "accepts";
|
||||
|
||||
public static final String IDLE_TIMEOUT_KEY = "idle.timeout";
|
||||
|
||||
public static final String HEARTBEAT_KEY = "heartbeat";
|
||||
|
||||
public static final String HEARTBEAT_TIMEOUT_KEY = "heartbeat.timeout";
|
||||
|
||||
public static final String CONNECT_TIMEOUT_KEY = "connect.timeout";
|
||||
|
||||
public static final String TIMEOUT_KEY = "timeout";
|
||||
|
||||
public static final String RETRIES_KEY = "retries";
|
||||
|
||||
public static final String PROMPT_KEY = "prompt";
|
||||
|
||||
public static final String DEFAULT_PROMPT = "dubbo>";
|
||||
|
||||
public static final String CODEC_KEY = "codec";
|
||||
|
||||
public static final String SERIALIZATION_KEY = "serialization";
|
||||
|
||||
public static final String EXCHANGER_KEY = "exchanger";
|
||||
|
||||
public static final String TRANSPORTER_KEY = "transporter";
|
||||
|
||||
public static final String SERVER_KEY = "server";
|
||||
|
||||
public static final String CLIENT_KEY = "client";
|
||||
|
||||
public static final String ID_KEY = "id";
|
||||
|
||||
public static final String ASYNC_KEY = "async";
|
||||
|
||||
public static final String RETURN_KEY = "return";
|
||||
|
||||
public static final String TOKEN_KEY = "token";
|
||||
|
||||
public static final String METHOD_KEY = "method";
|
||||
|
||||
public static final String METHODS_KEY = "methods";
|
||||
|
||||
public static final String CHARSET_KEY = "charset";
|
||||
|
||||
public static final String RECONNECT_KEY = "reconnect";
|
||||
|
||||
public static final String SEND_RECONNECT_KEY = "send.reconnect";
|
||||
|
||||
public static final int DEFAULT_RECONNECT_PERIOD = 2000;
|
||||
|
||||
public static final String SHUTDOWN_TIMEOUT_KEY = "shutdown.timeout";
|
||||
|
||||
public static final int DEFAULT_SHUTDOWN_TIMEOUT = 1000 * 60 * 15;
|
||||
|
||||
public static final String PID_KEY = "pid";
|
||||
|
||||
public static final String TIMESTAMP_KEY = "timestamp";
|
||||
|
||||
public static final String WARMUP_KEY = "warmup";
|
||||
|
||||
public static final int DEFAULT_WARMUP = 10 * 60 * 1000;
|
||||
|
||||
public static final String CHECK_KEY = "check";
|
||||
|
||||
public static final String REGISTER_KEY = "register";
|
||||
|
||||
public static final String SUBSCRIBE_KEY = "subscribe";
|
||||
|
||||
public static final String GROUP_KEY = "group";
|
||||
|
||||
public static final String PATH_KEY = "path";
|
||||
|
||||
public static final String INTERFACE_KEY = "interface";
|
||||
|
||||
public static final String GENERIC_KEY = "generic";
|
||||
|
||||
public static final String FILE_KEY = "file";
|
||||
|
||||
public static final String WAIT_KEY = "wait";
|
||||
|
||||
public static final String CLASSIFIER_KEY = "classifier";
|
||||
|
||||
public static final String VERSION_KEY = "version";
|
||||
|
||||
public static final String REVISION_KEY = "revision";
|
||||
|
||||
public static final String DUBBO_VERSION_KEY = "dubbo";
|
||||
|
||||
public static final String HESSIAN_VERSION_KEY = "hessian.version";
|
||||
|
||||
public static final String DISPATCHER_KEY = "dispatcher";
|
||||
|
||||
public static final String CHANNEL_HANDLER_KEY = "channel.handler";
|
||||
|
||||
public static final String DEFAULT_CHANNEL_HANDLER = "default";
|
||||
|
||||
public static final String ANY_VALUE = "*";
|
||||
|
||||
public static final String COMMA_SEPARATOR = ",";
|
||||
|
||||
public static final Pattern COMMA_SPLIT_PATTERN = Pattern
|
||||
.compile("\\s*[,]+\\s*");
|
||||
|
||||
public final static String PATH_SEPARATOR = "/";
|
||||
|
||||
public static final String REGISTRY_SEPARATOR = "|";
|
||||
|
||||
public static final Pattern REGISTRY_SPLIT_PATTERN = Pattern
|
||||
.compile("\\s*[|;]+\\s*");
|
||||
|
||||
public static final String SEMICOLON_SEPARATOR = ";";
|
||||
|
||||
public static final Pattern SEMICOLON_SPLIT_PATTERN = Pattern
|
||||
.compile("\\s*[;]+\\s*");
|
||||
|
||||
public static final String CONNECT_QUEUE_CAPACITY = "connect.queue.capacity";
|
||||
|
||||
public static final String CONNECT_QUEUE_WARNING_SIZE = "connect.queue.warning.size";
|
||||
|
||||
public static final int DEFAULT_CONNECT_QUEUE_WARNING_SIZE = 1000;
|
||||
|
||||
public static final String CHANNEL_ATTRIBUTE_READONLY_KEY = "channel.readonly";
|
||||
|
||||
public static final String CHANNEL_READONLYEVENT_SENT_KEY = "channel.readonly.sent";
|
||||
|
||||
public static final String CHANNEL_SEND_READONLYEVENT_KEY = "channel.readonly.send";
|
||||
|
||||
public static final String COUNT_PROTOCOL = "count";
|
||||
|
||||
public static final String TRACE_PROTOCOL = "trace";
|
||||
|
||||
public static final String EMPTY_PROTOCOL = "empty";
|
||||
|
||||
public static final String ADMIN_PROTOCOL = "admin";
|
||||
|
||||
public static final String PROVIDER_PROTOCOL = "provider";
|
||||
|
||||
public static final String CONSUMER_PROTOCOL = "consumer";
|
||||
|
||||
public static final String ROUTE_PROTOCOL = "route";
|
||||
|
||||
public static final String SCRIPT_PROTOCOL = "script";
|
||||
|
||||
public static final String CONDITION_PROTOCOL = "condition";
|
||||
|
||||
public static final String MOCK_PROTOCOL = "mock";
|
||||
|
||||
public static final String RETURN_PREFIX = "return ";
|
||||
|
||||
public static final String THROW_PREFIX = "throw";
|
||||
|
||||
public static final String FAIL_PREFIX = "fail:";
|
||||
|
||||
public static final String FORCE_PREFIX = "force:";
|
||||
|
||||
public static final String FORCE_KEY = "force";
|
||||
|
||||
public static final String MERGER_KEY = "merger";
|
||||
|
||||
public static final String CLUSTER_AVAILABLE_CHECK_KEY = "cluster.availablecheck";
|
||||
|
||||
public static final boolean DEFAULT_CLUSTER_AVAILABLE_CHECK = true;
|
||||
|
||||
public static final String CLUSTER_STICKY_KEY = "sticky";
|
||||
|
||||
public static final boolean DEFAULT_CLUSTER_STICKY = false;
|
||||
|
||||
public static final String LAZY_CONNECT_KEY = "lazy";
|
||||
|
||||
public static final String LAZY_CONNECT_INITIAL_STATE_KEY = "connect.lazy.initial.state";
|
||||
|
||||
public static final boolean DEFAULT_LAZY_CONNECT_INITIAL_STATE = true;
|
||||
|
||||
public static final String REGISTRY_FILESAVE_SYNC_KEY = "save.file";
|
||||
|
||||
public static final String REGISTRY_RETRY_PERIOD_KEY = "retry.period";
|
||||
|
||||
public static final int DEFAULT_REGISTRY_RETRY_PERIOD = 5 * 1000;
|
||||
|
||||
public static final String REGISTRY_RECONNECT_PERIOD_KEY = "reconnect.period";
|
||||
|
||||
public static final int DEFAULT_REGISTRY_RECONNECT_PERIOD = 3 * 1000;
|
||||
|
||||
public static final String SESSION_TIMEOUT_KEY = "session";
|
||||
|
||||
public static final int DEFAULT_SESSION_TIMEOUT = 60 * 1000;
|
||||
|
||||
public static final String EXPORT_KEY = "export";
|
||||
|
||||
public static final String REFER_KEY = "refer";
|
||||
|
||||
public static final String CALLBACK_SERVICE_KEY = "callback.service.instid";
|
||||
|
||||
public static final String CALLBACK_INSTANCES_LIMIT_KEY = "callbacks";
|
||||
|
||||
public static final int DEFAULT_CALLBACK_INSTANCES = 1;
|
||||
|
||||
public static final String CALLBACK_SERVICE_PROXY_KEY = "callback.service.proxy";
|
||||
|
||||
public static final String IS_CALLBACK_SERVICE = "is_callback_service";
|
||||
|
||||
public static final String CHANNEL_CALLBACK_KEY = "channel.callback.invokers.key";
|
||||
|
||||
@Deprecated
|
||||
public static final String SHUTDOWN_WAIT_SECONDS_KEY = "dubbo.service.shutdown.wait.seconds";
|
||||
|
||||
public static final String SHUTDOWN_WAIT_KEY = "dubbo.service.shutdown.wait";
|
||||
|
||||
public static final String IS_SERVER_KEY = "isserver";
|
||||
|
||||
public static final int DEFAULT_SERVER_SHUTDOWN_TIMEOUT = 10000;
|
||||
|
||||
public static final String ON_CONNECT_KEY = "onconnect";
|
||||
|
||||
public static final String ON_DISCONNECT_KEY = "ondisconnect";
|
||||
|
||||
public static final String ON_INVOKE_METHOD_KEY = "oninvoke.method";
|
||||
|
||||
public static final String ON_RETURN_METHOD_KEY = "onreturn.method";
|
||||
|
||||
public static final String ON_THROW_METHOD_KEY = "onthrow.method";
|
||||
|
||||
public static final String ON_INVOKE_INSTANCE_KEY = "oninvoke.instance";
|
||||
|
||||
public static final String ON_RETURN_INSTANCE_KEY = "onreturn.instance";
|
||||
|
||||
public static final String ON_THROW_INSTANCE_KEY = "onthrow.instance";
|
||||
|
||||
public static final String OVERRIDE_PROTOCOL = "override";
|
||||
|
||||
public static final String PRIORITY_KEY = "priority";
|
||||
|
||||
public static final String RULE_KEY = "rule";
|
||||
|
||||
public static final String TYPE_KEY = "type";
|
||||
|
||||
public static final String RUNTIME_KEY = "runtime";
|
||||
|
||||
public static final String ROUTER_TYPE_CLEAR = "clean";
|
||||
|
||||
public static final String DEFAULT_SCRIPT_TYPE_KEY = "javascript";
|
||||
|
||||
public static final String STUB_EVENT_KEY = "dubbo.stub.event";
|
||||
|
||||
public static final boolean DEFAULT_STUB_EVENT = false;
|
||||
|
||||
public static final String STUB_EVENT_METHODS_KEY = "dubbo.stub.event.methods";
|
||||
|
||||
public static final String INVOCATION_NEED_MOCK = "invocation.need.mock";
|
||||
|
||||
public static final String LOCAL_PROTOCOL = "injvm";
|
||||
|
||||
public static final String AUTO_ATTACH_INVOCATIONID_KEY = "invocationid.autoattach";
|
||||
|
||||
public static final String SCOPE_KEY = "scope";
|
||||
|
||||
public static final String SCOPE_LOCAL = "local";
|
||||
|
||||
public static final String SCOPE_REMOTE = "remote";
|
||||
|
||||
public static final String SCOPE_NONE = "none";
|
||||
|
||||
public static final String RELIABLE_PROTOCOL = "napoli";
|
||||
|
||||
public static final String TPS_LIMIT_RATE_KEY = "tps";
|
||||
|
||||
public static final String TPS_LIMIT_INTERVAL_KEY = "tps.interval";
|
||||
|
||||
public static final long DEFAULT_TPS_LIMIT_INTERVAL = 60 * 1000;
|
||||
|
||||
public static final String DECODE_IN_IO_THREAD_KEY = "decode.in.io";
|
||||
|
||||
public static final boolean DEFAULT_DECODE_IN_IO_THREAD = true;
|
||||
|
||||
public static final String INPUT_KEY = "input";
|
||||
|
||||
public static final String OUTPUT_KEY = "output";
|
||||
|
||||
public static final String EXECUTOR_SERVICE_COMPONENT_KEY = ExecutorService.class.getName();
|
||||
|
||||
public static final String GENERIC_SERIALIZATION_NATIVE_JAVA = "nativejava";
|
||||
|
||||
public static final String GENERIC_SERIALIZATION_DEFAULT = "true";
|
||||
|
||||
public static final String INVOKER_CONNECTED_KEY = "connected";
|
||||
|
||||
public static final String INVOKER_INSIDE_INVOKERS_KEY = "inside.invokers";
|
||||
|
||||
public static final String INVOKER_INSIDE_INVOKER_COUNT_KEY = "inside.invoker.count";
|
||||
|
||||
public static final String CLUSTER_SWITCH_FACTOR = "cluster.switch.factor";
|
||||
|
||||
public static final String CLUSTER_SWITCH_LOG_ERROR = "cluster.switch.log.error";
|
||||
|
||||
public static final double DEFAULT_CLUSTER_SWITCH_FACTOR = 2;
|
||||
|
||||
public static final String DISPATHER_KEY = "dispather";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,15 @@
|
|||
|
||||
package com.alibaba.dubbo.rpc;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
@Deprecated
|
||||
public interface Invocation extends org.apache.dubbo.rpc.Invocation {
|
||||
|
||||
|
|
@ -184,6 +185,7 @@ public interface Invocation extends org.apache.dubbo.rpc.Invocation {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public Invoker<?> getInvoker() {
|
||||
return new Invoker.CompatibleInvoker(delegate.getInvoker());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Deprecated
|
||||
public class RpcContext {
|
||||
|
|
@ -320,6 +321,25 @@ public class RpcContext {
|
|||
return isConsumerSide();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Invoker<?> getInvoker() {
|
||||
org.apache.dubbo.rpc.Invoker<?> invoker = newRpcContext.getInvoker();
|
||||
if (invoker == null) {
|
||||
return null;
|
||||
}
|
||||
return new Invoker.CompatibleInvoker<>(invoker);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<Invoker<?>> getInvokers() {
|
||||
List<org.apache.dubbo.rpc.Invoker<?>> invokers = newRpcContext.getInvokers();
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return invokers.stream()
|
||||
.map(Invoker.CompatibleInvoker::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
/**
|
||||
* Async invocation. Timeout will be handled even if <code>Future.get()</code> is not called.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package com.alibaba.dubbo.rpc;
|
|||
|
||||
@Deprecated
|
||||
public class RpcException extends org.apache.dubbo.rpc.RpcException {
|
||||
|
||||
|
||||
public RpcException() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -51,4 +51,8 @@ public class RpcException extends org.apache.dubbo.rpc.RpcException {
|
|||
public RpcException(int code, Throwable cause) {
|
||||
super(code, cause);
|
||||
}
|
||||
|
||||
public boolean isForbidded() {
|
||||
return isForbidden();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
package com.alibaba.dubbo.rpc;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -24,9 +28,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
public class RpcInvocation implements Invocation, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4355285085441097045L;
|
||||
|
|
@ -101,6 +102,7 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
this.invoker = invoker;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public Invoker<?> getInvoker() {
|
||||
return invoker;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package com.alibaba.dubbo.rpc.cluster.loadbalance;
|
||||
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
|
|
@ -40,7 +42,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
|
|||
protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
|
||||
|
||||
protected int getWeight(Invoker<?> invoker, Invocation invocation) {
|
||||
int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
|
||||
int weight = invoker.getUrl().getMethodParameter(RpcUtils.getMethodName(invocation), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
|
||||
if (weight > 0) {
|
||||
long timestamp = invoker.getUrl().getParameter(Constants.TIMESTAMP_KEY, 0L);
|
||||
if (timestamp > 0L) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import org.apache.dubbo.rpc.support.ProtocolUtils;
|
|||
import java.beans.Transient;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -409,9 +409,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", "No method found in service interface: " + interfaceClass.getName());
|
||||
map.put(METHODS_KEY, ANY_VALUE);
|
||||
} else {
|
||||
List<String> copyOfMethods = new ArrayList<>(Arrays.asList(methods));
|
||||
copyOfMethods.sort(Comparator.naturalOrder());
|
||||
map.put(METHODS_KEY, String.join(COMMA_SEPARATOR, copyOfMethods));
|
||||
map.put(METHODS_KEY, StringUtils.join(new TreeSet<>(Arrays.asList(methods)), COMMA_SEPARATOR));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ import java.beans.Transient;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -99,6 +99,7 @@ import static org.apache.dubbo.config.Constants.DUBBO_PORT_TO_BIND;
|
|||
import static org.apache.dubbo.config.Constants.DUBBO_PORT_TO_REGISTRY;
|
||||
import static org.apache.dubbo.config.Constants.SCOPE_NONE;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTER_ORIGIN_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.IS_PU_SERVER_KEY;
|
||||
|
|
@ -310,7 +311,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
public void register(boolean onlyDefault) {
|
||||
if (!this.exported) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -321,7 +322,9 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
for (Exporter<?> exporter : exporters) {
|
||||
exporter.register();
|
||||
if (!onlyDefault || exporter.getInvoker().getUrl().getParameter(REGISTER_ORIGIN_KEY, true)) {
|
||||
exporter.register();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -584,9 +587,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", "No method found in service interface: " + interfaceClass.getName());
|
||||
map.put(METHODS_KEY, ANY_VALUE);
|
||||
} else {
|
||||
List<String> copyOfMethods = new ArrayList<>(Arrays.asList(methods));
|
||||
copyOfMethods.sort(Comparator.naturalOrder());
|
||||
map.put(METHODS_KEY, String.join(COMMA_SEPARATOR, copyOfMethods));
|
||||
map.put(METHODS_KEY, StringUtils.join(new TreeSet<>(Arrays.asList(methods)), COMMA_SEPARATOR));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -815,6 +816,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void doExportUrl(URL url, boolean withMetaData, boolean register) {
|
||||
if (!register) {
|
||||
url = url.addParameter(REGISTER_ORIGIN_KEY, url.getParameter(REGISTER_KEY, true));
|
||||
url = url.addParameter(REGISTER_KEY, false);
|
||||
}
|
||||
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public final class DubboBootstrap {
|
|||
private DubboBootstrap(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
configManager = applicationModel.getApplicationConfigManager();
|
||||
environment = applicationModel.getModelEnvironment();
|
||||
environment = applicationModel.modelEnvironment();
|
||||
|
||||
executorRepository = ExecutorRepository.getInstance(applicationModel);
|
||||
applicationDeployer = applicationModel.getDeployer();
|
||||
|
|
|
|||
|
|
@ -275,6 +275,7 @@ public class InternalServiceConfigBuilder<T> {
|
|||
serviceConfig.setRef(this.ref);
|
||||
serviceConfig.setGroup(applicationConfig.getName());
|
||||
serviceConfig.setVersion("1.0.0");
|
||||
serviceConfig.setFilter("-default");
|
||||
|
||||
serviceConfig.setExecutor(executor);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
super(applicationModel);
|
||||
this.applicationModel = applicationModel;
|
||||
configManager = applicationModel.getApplicationConfigManager();
|
||||
environment = applicationModel.getModelEnvironment();
|
||||
environment = applicationModel.modelEnvironment();
|
||||
|
||||
referenceCache = new CompositeReferenceCache(applicationModel);
|
||||
frameworkExecutorRepository = applicationModel.getFrameworkModel().getBeanFactory().getBean(FrameworkExecutorRepository.class);
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
if (!sc.isExported()) {
|
||||
return;
|
||||
}
|
||||
sc.register();
|
||||
sc.register(true);
|
||||
}
|
||||
|
||||
private void unexportServices() {
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ public class ConfigValidationUtils {
|
|||
|
||||
// backward compatibility
|
||||
ScopeModel scopeModel = ScopeModelUtil.getOrDefaultApplicationModel(config.getScopeModel());
|
||||
PropertiesConfiguration configuration = scopeModel.getModelEnvironment().getPropertiesConfiguration();
|
||||
PropertiesConfiguration configuration = scopeModel.modelEnvironment().getPropertiesConfiguration();
|
||||
String wait = configuration.getProperty(SHUTDOWN_WAIT_KEY);
|
||||
if (wait != null && wait.trim().length() > 0) {
|
||||
System.setProperty(SHUTDOWN_WAIT_KEY, wait.trim());
|
||||
|
|
@ -670,8 +670,9 @@ public class ConfigValidationUtils {
|
|||
if (isNotEmpty(value)) {
|
||||
String[] values = value.split("\\s*[,]+\\s*");
|
||||
for (String v : values) {
|
||||
v = StringUtils.trim(v);
|
||||
if (v.startsWith(REMOVE_VALUE_PREFIX)) {
|
||||
v = v.substring(1);
|
||||
continue;
|
||||
}
|
||||
if (DEFAULT_KEY.equals(v)) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -207,8 +207,25 @@ class AbstractConfigTest {
|
|||
|
||||
@Test
|
||||
void checkMultiExtension2() {
|
||||
try {
|
||||
ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world");
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail(t);
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void checkMultiExtension3() {
|
||||
Assertions.assertThrows(IllegalStateException.class,
|
||||
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world"));
|
||||
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkMultiExtension4() {
|
||||
try {
|
||||
ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , -world ");
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -335,8 +352,8 @@ class AbstractConfigTest {
|
|||
external.put("dubbo.override.key", "external");
|
||||
// @Parameter(key="key2", useKeyAsProperty=true)
|
||||
external.put("dubbo.override.key2", "external");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
SysProps.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
|
||||
SysProps.setProperty("dubbo.override.protocol", "system");
|
||||
|
|
@ -353,7 +370,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("system", overrideConfig.getKey2());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,14 +394,14 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("override-config://", overrideConfig.getEscape());
|
||||
Assertions.assertEquals("system", overrideConfig.getKey());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRefreshProperties() throws Exception {
|
||||
try {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(new HashMap<>());
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(new HashMap<>());
|
||||
OverrideConfig overrideConfig = new OverrideConfig();
|
||||
overrideConfig.setAddress("override-config://127.0.0.1:2181");
|
||||
overrideConfig.setProtocol("override-config");
|
||||
|
|
@ -392,7 +409,7 @@ class AbstractConfigTest {
|
|||
|
||||
Properties properties = new Properties();
|
||||
properties.load(this.getClass().getResourceAsStream("/dubbo.properties"));
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperties(properties);
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperties(properties);
|
||||
|
||||
overrideConfig.refresh();
|
||||
|
||||
|
|
@ -402,7 +419,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("properties", overrideConfig.getKey2());
|
||||
//Assertions.assertEquals("properties", overrideConfig.getUseKeyAsProperty());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -425,8 +442,8 @@ class AbstractConfigTest {
|
|||
external.put("dubbo.override.key", "external");
|
||||
// @Parameter(key="key2", useKeyAsProperty=true)
|
||||
external.put("dubbo.override.key2", "external");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
overrideConfig.refresh();
|
||||
|
||||
|
|
@ -437,7 +454,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey2());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,8 +474,8 @@ class AbstractConfigTest {
|
|||
external.put("dubbo.overrides.override-id.key2", "external");
|
||||
external.put("dubbo.override.address", "external://127.0.0.1:2181");
|
||||
external.put("dubbo.override.exclude", "external");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
// refresh config
|
||||
overrideConfig.refresh();
|
||||
|
|
@ -469,7 +486,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey2());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,8 +502,8 @@ class AbstractConfigTest {
|
|||
|
||||
Map<String, String> external = new HashMap<>();
|
||||
external.put("dubbo.override.parameters", "[{key3:value3},{key4:value4},{key2:value5}]");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
// refresh config
|
||||
overrideConfig.refresh();
|
||||
|
|
@ -502,7 +519,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals("value6", overrideConfig.getParameters().get("key3"));
|
||||
Assertions.assertEquals("value4", overrideConfig.getParameters().get("key4"));
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -514,7 +531,7 @@ class AbstractConfigTest {
|
|||
overrideConfig.refresh();
|
||||
assertEquals("value00", overrideConfig.getParameters().get("key00"));
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -587,14 +604,14 @@ class AbstractConfigTest {
|
|||
external.put("notConflictKey", "value-from-external");
|
||||
external.put("dubbo.override.notConflictKey2", "value-from-external");
|
||||
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
overrideConfig.refresh();
|
||||
|
||||
Assertions.assertEquals("value-from-config", overrideConfig.getNotConflictKey());
|
||||
Assertions.assertEquals("value-from-external", overrideConfig.getNotConflictKey2());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1021,8 +1038,8 @@ class AbstractConfigTest {
|
|||
external.put("dubbo.outer.a1", "1");
|
||||
external.put("dubbo.outer.b.b1", "11");
|
||||
external.put("dubbo.outer.b.b2", "12");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.defaultModel().modelEnvironment().initialize();
|
||||
ApplicationModel.defaultModel().modelEnvironment().setExternalConfigMap(external);
|
||||
|
||||
// refresh config
|
||||
outerConfig.refresh();
|
||||
|
|
@ -1031,7 +1048,7 @@ class AbstractConfigTest {
|
|||
Assertions.assertEquals(11, outerConfig.getB().getB1());
|
||||
Assertions.assertEquals(12, outerConfig.getB().getB2());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().destroy();
|
||||
ApplicationModel.defaultModel().modelEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,8 +160,8 @@ class ConfigCenterConfigTest {
|
|||
|
||||
ApplicationModel.defaultModel().getDefaultModule();
|
||||
// Config instance has id, dubbo props has no id
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.check", "false");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.timeout", "1234");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.check", "false");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.timeout", "1234");
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
|
|
@ -179,7 +179,7 @@ class ConfigCenterConfigTest {
|
|||
Assertions.assertEquals(3000L, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
DubboBootstrap.getInstance().stop();
|
||||
}
|
||||
}
|
||||
|
|
@ -215,8 +215,8 @@ class ConfigCenterConfigTest {
|
|||
|
||||
ApplicationModel.defaultModel().getDefaultModule();
|
||||
// Config instance has id, dubbo props has id
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.check", "false");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.timeout", "1234");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.check", "false");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.timeout", "1234");
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
|
|
@ -235,7 +235,7 @@ class ConfigCenterConfigTest {
|
|||
Assertions.assertEquals(3000L, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
DubboBootstrap.getInstance().stop();
|
||||
}
|
||||
}
|
||||
|
|
@ -294,4 +294,4 @@ class ConfigCenterConfigTest {
|
|||
Assertions.assertEquals("pass123", cc.getPassword());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ class ConsumerConfigTest {
|
|||
@Test
|
||||
void testOverrideConfigByDubboProps() {
|
||||
ApplicationModel.defaultModel().getDefaultModule();
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.check", "false");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.group", "demo");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.threads", "10");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.check", "false");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.group", "demo");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.threads", "10");
|
||||
|
||||
try {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
|
|
@ -208,7 +208,7 @@ class ConsumerConfigTest {
|
|||
Assertions.assertEquals("groupA", consumerConfig.getGroup());
|
||||
Assertions.assertEquals(10, consumerConfig.getThreads());
|
||||
} finally {
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
DubboBootstrap.getInstance().destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -683,4 +683,20 @@ class ServiceConfigTest {
|
|||
|
||||
scheduledExecutorService.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
|
||||
service.setRef(new DemoServiceImpl() {
|
||||
@Override
|
||||
public String toString() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
});
|
||||
try {
|
||||
serviceConfig.toString();
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,13 +115,13 @@ class DubboBootstrapTest {
|
|||
System.clearProperty(SHUTDOWN_WAIT_SECONDS_KEY);
|
||||
|
||||
writeDubboProperties(SHUTDOWN_WAIT_KEY, "100");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
Assertions.assertEquals("100", System.getProperty(SHUTDOWN_WAIT_KEY));
|
||||
|
||||
System.clearProperty(SHUTDOWN_WAIT_KEY);
|
||||
writeDubboProperties(SHUTDOWN_WAIT_SECONDS_KEY, "1000");
|
||||
ApplicationModel.defaultModel().getModelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
Assertions.assertEquals("1000", System.getProperty(SHUTDOWN_WAIT_SECONDS_KEY));
|
||||
} finally {
|
||||
|
|
@ -369,4 +369,4 @@ class DubboBootstrapTest {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ package org.apache.dubbo.config.deploy;
|
|||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DefaultApplicationDeployerTest {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.config.integration;
|
|||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.ExporterListener;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
|
||||
import org.apache.dubbo.rpc.listener.ListenerExporterWrapper;
|
||||
|
|
@ -56,7 +57,13 @@ public abstract class AbstractRegistryCenterExporterListener implements Exporter
|
|||
@Override
|
||||
public void exported(Exporter<?> exporter) throws RpcException {
|
||||
ListenerExporterWrapper listenerExporterWrapper = (ListenerExporterWrapper) exporter;
|
||||
FilterChainBuilder.CallbackRegistrationInvoker callbackRegistrationInvoker = (FilterChainBuilder.CallbackRegistrationInvoker) listenerExporterWrapper.getInvoker();
|
||||
|
||||
Invoker invoker = listenerExporterWrapper.getInvoker();
|
||||
if (!(invoker instanceof FilterChainBuilder.CallbackRegistrationInvoker)) {
|
||||
exportedExporters.add(exporter);
|
||||
return;
|
||||
}
|
||||
FilterChainBuilder.CallbackRegistrationInvoker callbackRegistrationInvoker = (FilterChainBuilder.CallbackRegistrationInvoker) invoker;
|
||||
if (callbackRegistrationInvoker == null ||
|
||||
callbackRegistrationInvoker.getInterface() != getInterface()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ class MultipleRegistryCenterExportProviderIntegrationTest implements Integration
|
|||
// 1. InjvmExporter
|
||||
// 2. DubboExporter with service-discovery-registry protocol
|
||||
// 3. DubboExporter with registry protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 5);
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 4);
|
||||
// The exported exporter contains MultipleRegistryCenterExportProviderFilter
|
||||
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class MultipleRegistryCenterInjvmIntegrationTest implements IntegrationTest {
|
|||
// The MultipleRegistryCenterInjvmService is exported
|
||||
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
|
||||
// The exported exporter is only one
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 1);
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 3);
|
||||
// The exported exporter contains MultipleRegistryCenterInjvmFilter
|
||||
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
|
||||
}
|
||||
|
|
@ -189,4 +189,4 @@ class MultipleRegistryCenterInjvmIntegrationTest implements IntegrationTest {
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class SingleRegistryCenterExportProviderIntegrationTest implements IntegrationTe
|
|||
// 1. InjvmExporter
|
||||
// 2. DubboExporter with service-discovery-registry protocol
|
||||
// 3. DubboExporter with registry protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 3);
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 4);
|
||||
// The exported exporter contains SingleRegistryCenterExportProviderFilter
|
||||
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
|
||||
// The consumer can be notified and get provider's metadata through metadata mapping info.
|
||||
|
|
@ -244,4 +244,4 @@ class SingleRegistryCenterExportProviderIntegrationTest implements IntegrationTe
|
|||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
registryProtocolListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class SingleRegistryCenterInjvmIntegrationTest implements IntegrationTest {
|
|||
// The SingleRegistryCenterInjvmService is exported
|
||||
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
|
||||
// The exported exporter is only one
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 1);
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 3);
|
||||
// The exported exporter contains SingleRegistryCenterInjvmFilter
|
||||
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
|
||||
}
|
||||
|
|
@ -188,4 +188,4 @@ class SingleRegistryCenterInjvmIntegrationTest implements IntegrationTest {
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@
|
|||
<plugin>
|
||||
<groupId>org.graalvm.buildtools</groupId>
|
||||
<artifactId>native-maven-plugin</artifactId>
|
||||
<version>0.9.22</version>
|
||||
<version>0.9.23</version>
|
||||
<configuration>
|
||||
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
|
||||
<metadataRepository>
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@
|
|||
<plugin>
|
||||
<groupId>org.graalvm.buildtools</groupId>
|
||||
<artifactId>native-maven-plugin</artifactId>
|
||||
<version>0.9.22</version>
|
||||
<version>0.9.23</version>
|
||||
<configuration>
|
||||
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
|
||||
<metadataRepository>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
<spring-boot.version>2.7.12</spring-boot.version>
|
||||
<spring-boot-maven-plugin.version>2.7.12</spring-boot-maven-plugin.version>
|
||||
<micrometer-core.version>1.11.0</micrometer-core.version>
|
||||
<micrometer-core.version>1.11.1</micrometer-core.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@
|
|||
<cxf_version>3.5.5</cxf_version>
|
||||
<thrift_version>0.18.1</thrift_version>
|
||||
<hessian_version>4.0.66</hessian_version>
|
||||
<protobuf-java_version>3.23.2</protobuf-java_version>
|
||||
<protobuf-java_version>3.23.3</protobuf-java_version>
|
||||
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
|
||||
<servlet_version>3.1.0</servlet_version>
|
||||
<jetty_version>9.4.51.v20230217</jetty_version>
|
||||
|
|
@ -133,13 +133,13 @@
|
|||
<commons_lang3_version>3.12.0</commons_lang3_version>
|
||||
<protostuff_version>1.8.0</protostuff_version>
|
||||
<envoy_api_version>0.1.35</envoy_api_version>
|
||||
<micrometer.version>1.11.0</micrometer.version>
|
||||
<micrometer.version>1.11.1</micrometer.version>
|
||||
|
||||
<micrometer-tracing.version>1.1.1</micrometer-tracing.version>
|
||||
<micrometer-tracing.version>1.1.2</micrometer-tracing.version>
|
||||
<t_digest.version>3.3</t_digest.version>
|
||||
<prometheus_client.version>0.16.0</prometheus_client.version>
|
||||
<reactive.version>1.0.4</reactive.version>
|
||||
<reactor.version>3.5.6</reactor.version>
|
||||
<reactor.version>3.5.7</reactor.version>
|
||||
<rxjava.version>2.2.21</rxjava.version>
|
||||
<okhttp_version>3.14.9</okhttp_version>
|
||||
|
||||
|
|
@ -149,7 +149,7 @@
|
|||
<tomcat_embed_version>8.5.87</tomcat_embed_version>
|
||||
<jetcd_version>0.7.5</jetcd_version>
|
||||
<nacos_version>2.2.3</nacos_version>
|
||||
<grpc.version>1.55.1</grpc.version>
|
||||
<grpc.version>1.56.0</grpc.version>
|
||||
<grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
|
||||
<jprotoc_version>1.2.2</jprotoc_version>
|
||||
<!-- Log libs -->
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<eureka.version>1.10.18</eureka.version>
|
||||
|
||||
<!-- Fabric8 for Kubernetes -->
|
||||
<fabric8_kubernetes_version>6.7.1</fabric8_kubernetes_version>
|
||||
<fabric8_kubernetes_version>6.6.2</fabric8_kubernetes_version>
|
||||
|
||||
<!-- Alibaba -->
|
||||
<alibaba_spring_context_support_version>1.0.11</alibaba_spring_context_support_version>
|
||||
|
|
@ -179,7 +179,7 @@
|
|||
<hessian_lite_version>3.2.13</hessian_lite_version>
|
||||
<swagger_version>1.6.11</swagger_version>
|
||||
|
||||
<snappy_java_version>1.1.10.0</snappy_java_version>
|
||||
<snappy_java_version>1.1.10.1</snappy_java_version>
|
||||
<bouncycastle-bcprov_version>1.70</bouncycastle-bcprov_version>
|
||||
<metrics_version>2.0.6</metrics_version>
|
||||
<sofa_registry_version>5.4.3</sofa_registry_version>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.dubbo.metrics.model.sample.MetricSample;
|
|||
import org.apache.dubbo.metrics.report.AbstractMetricsExport;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -94,7 +95,7 @@ public class RtStatComposite extends AbstractMetricsExport {
|
|||
|
||||
public void calcMethodKeyRt(Invocation invocation, String registryOpType, Long responseTime) {
|
||||
for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
|
||||
Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getTargetServiceUniqueName() + "_" + invocation.getMethodName(), container.getInitFunc());
|
||||
Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getTargetServiceUniqueName() + "_" + RpcUtils.getMethodName(invocation), container.getInitFunc());
|
||||
container.getConsumerFunc().accept(responseTime, current);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.dubbo.metrics.model;
|
|||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
|
@ -40,7 +41,7 @@ public class MethodMetric extends ServiceKeyMetric {
|
|||
|
||||
public MethodMetric(ApplicationModel applicationModel, Invocation invocation) {
|
||||
super(applicationModel, MetricsSupport.getInterfaceName(invocation));
|
||||
this.methodName = MetricsSupport.getMethodName(invocation);
|
||||
this.methodName = RpcUtils.getMethodName(invocation);
|
||||
this.side = MetricsSupport.getSide(invocation);
|
||||
this.group = MetricsSupport.getGroup(invocation);
|
||||
this.version = MetricsSupport.getVersion(invocation);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -55,7 +54,6 @@ import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName;
|
|||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.INVOCATION;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
|
||||
import static org.apache.dubbo.rpc.support.RpcUtils.isGenericCall;
|
||||
|
||||
public class MetricsSupport {
|
||||
|
||||
|
|
@ -159,17 +157,6 @@ public class MetricsSupport {
|
|||
return ivArr[0];
|
||||
}
|
||||
|
||||
public static String getMethodName(Invocation invocation) {
|
||||
String methodName = invocation.getMethodName();
|
||||
if (invocation instanceof RpcInvocation
|
||||
&& isGenericCall(((RpcInvocation) invocation).getParameterTypesDesc(), methodName)
|
||||
&& invocation.getArguments() != null
|
||||
&& invocation.getArguments().length == 3) {
|
||||
methodName = ((String) invocation.getArguments()[0]).trim();
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public static String getGroup(Invocation invocation) {
|
||||
String serviceUniqueName = invocation.getTargetServiceUniqueName();
|
||||
String group = null;
|
||||
|
|
|
|||
|
|
@ -16,15 +16,15 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.common.docs.KeyName;
|
||||
import io.micrometer.common.lang.Nullable;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.common.docs.KeyName;
|
||||
import io.micrometer.common.lang.Nullable;
|
||||
|
||||
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_METHOD;
|
||||
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SERVICE;
|
||||
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SYSTEM;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import io.micrometer.observation.transport.SenderContext;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
||||
import io.micrometer.observation.transport.SenderContext;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Provider context for RPC.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.observation.transport.ReceiverContext;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
||||
import io.micrometer.observation.transport.ReceiverContext;
|
||||
|
||||
/**
|
||||
* Consumer context for RPC.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
*/
|
||||
package org.apache.dubbo.metrics.observation.utils;
|
||||
|
||||
import io.micrometer.common.KeyValue;
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
||||
import io.micrometer.common.KeyValue;
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
|
|
@ -25,6 +24,8 @@ import org.apache.dubbo.rpc.BaseFilter;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,6 @@
|
|||
|
||||
package org.apache.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.test.simple.SpansAssert;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
|
|
@ -31,6 +26,12 @@ import org.apache.dubbo.rpc.Result;
|
|||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.test.simple.SpansAssert;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
|
||||
class ObservationReceiverFilterTest extends AbstractObservationFilterTest {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public class MonitorFilter implements Filter, Filter.Listener {
|
|||
* @return
|
||||
*/
|
||||
private AtomicInteger getConcurrent(Invoker<?> invoker, Invocation invocation) {
|
||||
String key = invoker.getInterface().getName() + "." + invocation.getMethodName();
|
||||
String key = invoker.getInterface().getName() + "." + RpcUtils.getMethodName(invocation);
|
||||
return ConcurrentHashMapUtils.computeIfAbsent(concurrents, key, k -> new AtomicInteger());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
public class AccessKeyAuthenticator implements Authenticator {
|
||||
private final ApplicationModel applicationModel;
|
||||
|
|
@ -54,7 +55,7 @@ public class AccessKeyAuthenticator implements Authenticator {
|
|||
if (StringUtils.isAnyEmpty(accessKeyId, consumer, requestTimestamp, originSignature)) {
|
||||
throw new RpcAuthenticationException("Failed to authenticate, maybe consumer side did not enable the auth");
|
||||
}
|
||||
|
||||
|
||||
AccessKeyPair accessKeyPair;
|
||||
try {
|
||||
accessKeyPair = getAccessKeyPair(invocation, url);
|
||||
|
|
@ -86,7 +87,7 @@ public class AccessKeyAuthenticator implements Authenticator {
|
|||
}
|
||||
|
||||
String getSignature(URL url, Invocation invocation, String secretKey, String time) {
|
||||
String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT, url.getColonSeparatedKey(), invocation.getMethodName(), secretKey, time);
|
||||
String requestString = String.format(Constants.SIGNATURE_STRING_FORMAT, url.getColonSeparatedKey(), RpcUtils.getMethodName(invocation), secretKey, time);
|
||||
boolean parameterEncrypt = url.getParameter(Constants.PARAMETER_SIGNATURE_ENABLE_KEY, false);
|
||||
if (parameterEncrypt) {
|
||||
return SignatureUtils.sign(invocation.getArguments(), requestString, secretKey);
|
||||
|
|
|
|||
|
|
@ -24,12 +24,16 @@ import org.apache.dubbo.rpc.Invocation;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
import static org.apache.dubbo.rpc.RpcException.AUTHORIZATION_EXCEPTION;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
|
||||
|
||||
@Activate(group = CommonConstants.PROVIDER, order =Integer.MAX_VALUE,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
|
||||
@Activate(group = CommonConstants.PROVIDER, order = Integer.MAX_VALUE, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
|
||||
public class AuthenticationExceptionTranslatorFilter implements Filter, Filter.Listener {
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,13 +27,17 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
|
||||
import org.apache.dubbo.spring.security.utils.SecurityNames;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
|
||||
|
||||
@Activate(group = CommonConstants.CONSUMER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
|
||||
public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter{
|
||||
@Activate(group = CommonConstants.CONSUMER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
|
||||
public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter {
|
||||
|
||||
private final ObjectMapperCodec mapper;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,11 +27,15 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
|
||||
import org.apache.dubbo.spring.security.utils.SecurityNames;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
|
||||
|
||||
@Activate(group = CommonConstants.PROVIDER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
|
||||
@Activate(group = CommonConstants.PROVIDER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
|
||||
public class ContextHolderAuthenticationResolverFilter implements Filter {
|
||||
|
||||
private final ObjectMapperCodec mapper;
|
||||
|
|
|
|||
|
|
@ -25,10 +25,14 @@ import org.apache.dubbo.rpc.model.ModuleModel;
|
|||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec;
|
||||
import org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME;
|
||||
import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME;
|
||||
|
||||
@Activate(onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME)
|
||||
@Activate(onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME})
|
||||
public class SecurityScopeModelInitializer implements ScopeModelInitializer {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ final public class SecurityNames {
|
|||
public static final String SECURITY_AUTHENTICATION_CONTEXT_KEY = "security_authentication_context";
|
||||
|
||||
public static final String SECURITY_CONTEXT_HOLDER_CLASS_NAME = "org.springframework.security.core.context.SecurityContextHolder";
|
||||
public static final String CORE_JACKSON_2_MODULE_CLASS_NAME = "org.springframework.security.jackson2.CoreJackson2Module";
|
||||
public static final String OBJECT_MAPPER_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper";
|
||||
|
||||
private SecurityNames() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public interface Constants {
|
|||
String REGISTER_IP_KEY = "register.ip";
|
||||
|
||||
String REGISTER_KEY = "register";
|
||||
String REGISTER_ORIGIN_KEY = "register_origin";
|
||||
|
||||
String SUBSCRIBE_KEY = "subscribe";
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ public abstract class RegistryNotifier {
|
|||
}
|
||||
scheduler.submit(new NotificationTask(this, notifyTime));
|
||||
}
|
||||
try {
|
||||
while (this.lastEventTime == System.currentTimeMillis()) {
|
||||
// wait to let event time refresh
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public long getDelayTime() {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.registry;
|
|||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.registry.client.metadata.MetadataServiceDelegation;
|
||||
import org.apache.dubbo.registry.integration.ExporterFactory;
|
||||
import org.apache.dubbo.registry.support.RegistryManager;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
|
@ -27,7 +28,8 @@ import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
|||
public class RegistryScopeModelInitializer implements ScopeModelInitializer {
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
|
||||
|
||||
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
|
||||
beanFactory.registerBean(ExporterFactory.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
|
||||
@Override
|
||||
public void subscribe(URL url) {
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
enableConfigurationListen = true;
|
||||
getConsumerConfigurationListener(moduleModel).addNotifyListener(this);
|
||||
referenceConfigurationListener = new ReferenceConfigurationListener(this.moduleModel, this, url);
|
||||
|
|
@ -143,7 +143,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
public void unSubscribe(URL url) {
|
||||
super.unSubscribe(url);
|
||||
this.originalUrls = null;
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
getConsumerConfigurationListener(moduleModel).removeNotifyListener(this);
|
||||
referenceConfigurationListener.stop();
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
getConsumerConfigurationListener(moduleModel).removeNotifyListener(this);
|
||||
referenceConfigurationListener.stop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ public interface ServiceInstance extends Serializable {
|
|||
|
||||
void setApplicationModel(ApplicationModel applicationModel);
|
||||
|
||||
@Transient
|
||||
ApplicationModel getApplicationModel();
|
||||
|
||||
@Transient
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur
|
|||
|
||||
private void init() {
|
||||
this.ruleKey = moduleModel.getApplicationModel().getApplicationName() + ".migration";
|
||||
this.configuration = moduleModel.getModelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
this.configuration = moduleModel.modelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
|
||||
if (this.configuration != null) {
|
||||
logger.info("Listening for migration rules on dataId " + ruleKey + ", group " + DUBBO_SERVICEDISCOVERY_MIGRATION);
|
||||
|
|
@ -115,7 +115,7 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur
|
|||
setRawRule(INIT);
|
||||
}
|
||||
|
||||
String localRawRule = moduleModel.getModelEnvironment().getLocalMigrationRule();
|
||||
String localRawRule = moduleModel.modelEnvironment().getLocalMigrationRule();
|
||||
if (!StringUtils.isEmpty(localRawRule)) {
|
||||
localRuleMigrationFuture = moduleModel.getApplicationModel().getFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getSharedScheduledExecutor()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.registry.integration;
|
||||
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ExporterFactory {
|
||||
private final Map<String, ReferenceCountExporter<?>> exporters = new ConcurrentHashMap<>();
|
||||
|
||||
protected ReferenceCountExporter<?> createExporter(String providerKey, Callable<Exporter<?>> exporterProducer) {
|
||||
return exporters.computeIfAbsent(providerKey,
|
||||
key -> {
|
||||
try {
|
||||
return new ReferenceCountExporter<>(exporterProducer.call(), key, this);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void remove(String key, ReferenceCountExporter<?> exporter) {
|
||||
exporters.remove(key, exporter);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.registry.integration;
|
||||
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ReferenceCountExporter<T> implements Exporter<T> {
|
||||
private final Exporter<T> exporter;
|
||||
private final String providerKey;
|
||||
private final ExporterFactory exporterFactory;
|
||||
private final AtomicInteger count = new AtomicInteger(0);
|
||||
|
||||
public ReferenceCountExporter(Exporter<T> exporter, String providerKey, ExporterFactory exporterFactory) {
|
||||
this.exporter = exporter;
|
||||
this.providerKey = providerKey;
|
||||
this.exporterFactory = exporterFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Invoker<T> getInvoker() {
|
||||
return exporter.getInvoker();
|
||||
}
|
||||
|
||||
public void increaseCount() {
|
||||
count.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unexport() {
|
||||
if (count.decrementAndGet() == 0) {
|
||||
exporter.unexport();
|
||||
}
|
||||
exporterFactory.remove(providerKey, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
return null;
|
||||
}
|
||||
);
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
consumerConfigurationListener.addNotifyListener(this);
|
||||
referenceConfigurationListener = new ReferenceConfigurationListener(moduleModel, this, url);
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
@Override
|
||||
public void unSubscribe(URL url) {
|
||||
super.unSubscribe(url);
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
consumerConfigurationListener.removeNotifyListener(this);
|
||||
if (referenceConfigurationListener != null) {
|
||||
referenceConfigurationListener.stop();
|
||||
|
|
@ -163,7 +163,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
consumerConfigurationListener.removeNotifyListener(this);
|
||||
if (referenceConfigurationListener != null) {
|
||||
referenceConfigurationListener.stop();
|
||||
|
|
@ -183,7 +183,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
.filter(this::isNotCompatibleFor26x)
|
||||
.collect(Collectors.groupingBy(this::judgeCategory));
|
||||
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
List<URL> configuratorURLs = categoryUrls.getOrDefault(CONFIGURATORS_CATEGORY, Collections.emptyList());
|
||||
this.configurators = Configurator.toConfigurators(configuratorURLs).orElse(this.configurators);
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
private ConcurrentMap<URL, ReExportTask> reExportFailedTasks = new ConcurrentHashMap<>();
|
||||
private HashedWheelTimer retryTimer = new HashedWheelTimer(new NamedThreadFactory("DubboReexportTimer", true), DEFAULT_REGISTRY_RETRY_PERIOD, TimeUnit.MILLISECONDS, 128);
|
||||
private FrameworkModel frameworkModel;
|
||||
private ExporterFactory exporterFactory;
|
||||
|
||||
//Filter the parameters that do not need to be output in url(Starting with .)
|
||||
private static String[] getFilteredKeys(URL url) {
|
||||
|
|
@ -190,6 +191,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
@Override
|
||||
public void setFrameworkModel(FrameworkModel frameworkModel) {
|
||||
this.frameworkModel = frameworkModel;
|
||||
this.exporterFactory = frameworkModel.getBeanFactory().getBean(ExporterFactory.class);
|
||||
}
|
||||
|
||||
public void setProtocol(Protocol protocol) {
|
||||
|
|
@ -276,7 +278,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
exporter.setRegistered(register);
|
||||
|
||||
ApplicationModel applicationModel = getApplicationModel(providerUrl.getScopeModel());
|
||||
if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
if (applicationModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
if (!registry.isServiceDiscovery()) {
|
||||
// Deprecated! Subscribe to override rules in 2.6.x or before.
|
||||
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
|
||||
|
|
@ -312,11 +314,13 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker, URL providerUrl) {
|
||||
String providerUrlKey = getProviderUrlKey(originInvoker);
|
||||
String registryUrlKey = getRegistryUrlKey(originInvoker);
|
||||
Invoker<?> invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl);
|
||||
|
||||
ReferenceCountExporter<?> exporter = exporterFactory.createExporter(providerUrlKey, () -> protocol.export(invokerDelegate));
|
||||
return (ExporterChangeableWrapper<T>) bounds.computeIfAbsent(providerUrlKey, _k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(registryUrlKey, s ->{
|
||||
Invoker<?> invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl);
|
||||
return new ExporterChangeableWrapper<>((Exporter<T>) protocol.export(invokerDelegate), originInvoker);
|
||||
.computeIfAbsent(registryUrlKey, s -> {
|
||||
return new ExporterChangeableWrapper<>(
|
||||
(ReferenceCountExporter<T>) exporter, originInvoker);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -657,7 +661,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
}
|
||||
|
||||
for (ApplicationModel applicationModel : frameworkModel.getApplicationModels()) {
|
||||
if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (applicationModel.modelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
for (ModuleModel moduleModel : applicationModel.getPubModuleModels()) {
|
||||
String applicationName = applicationModel.tryGetApplicationName();
|
||||
if (applicationName == null) {
|
||||
|
|
@ -869,7 +873,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
this.providerUrl = providerUrl;
|
||||
this.notifyListener = notifyListener;
|
||||
this.moduleModel = moduleModel;
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
this.initWith(DynamicConfiguration.getRuleKey(providerUrl) + CONFIGURATORS_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
|
@ -899,7 +903,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
public ProviderConfigurationListener(ModuleModel moduleModel) {
|
||||
super(moduleModel);
|
||||
this.moduleModel = moduleModel;
|
||||
if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (moduleModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
this.initWith(moduleModel.getApplicationModel().getApplicationName() + CONFIGURATORS_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
|
@ -953,8 +957,9 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
private NotifyListener notifyListener;
|
||||
private final AtomicBoolean registered = new AtomicBoolean(false);
|
||||
|
||||
public ExporterChangeableWrapper(Exporter<T> exporter, Invoker<T> originInvoker) {
|
||||
public ExporterChangeableWrapper(ReferenceCountExporter<T> exporter, Invoker<T> originInvoker) {
|
||||
this.exporter = exporter;
|
||||
exporter.increaseCount();
|
||||
this.originInvoker = originInvoker;
|
||||
FrameworkExecutorRepository frameworkExecutorRepository = originInvoker.getUrl().getOrDefaultFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class);
|
||||
|
|
@ -1009,12 +1014,12 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
if (listeners != null) {
|
||||
if (listeners.remove(notifyListener)) {
|
||||
ApplicationModel applicationModel = getApplicationModel(registerUrl.getScopeModel());
|
||||
if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
if (applicationModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
if (!registry.isServiceDiscovery()) {
|
||||
registry.unsubscribe(subscribeUrl, notifyListener);
|
||||
}
|
||||
}
|
||||
if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
if (applicationModel.modelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true)) {
|
||||
for (ModuleModel moduleModel : applicationModel.getPubModuleModels()) {
|
||||
if (moduleModel.getServiceRepository().getExportedServices().size() > 0) {
|
||||
moduleModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue